From 20efcf404cf776be262662bc3a37dc5d9fece3a6 Mon Sep 17 00:00:00 2001 From: nyagami Date: Sat, 4 Nov 2023 17:15:49 +0700 Subject: [PATCH] refactor: Classes for Plugins (#631) * set target to ES5 * refactor types * use .gitkeep * use dot to make dist/js dirs on top * add hako * add Hako * add madara * fix: url path js -> .js * fix: branch * freestyle for using UA, cookie * add parseNovels for Hako * update readme * fix: conflict types * add Kolnovel, remove node-fetch * add bestlightnovel * add plugins * WQMangaStreamScraper * PandaMTL * NobleMTL * LightNovelBrasil * WPMangaStream * add filters for popularNovels * fix undefined json * Linovelib (#26) * linovelib CN * icon for linovelib * fix undefined chapter * add check * fix: add artist * TuNovelaLigera ES + Madara Fix (#28) * app repo test * POST is now working * update madara template + run generator * template fix didnt get pushed commited idk why * template update POST * generated * fix: useNewChapterEndpoint update (#29) * useNewChapterEndpoint update * Update Selectors --------- Co-authored-by: K1ngfish3r --- {dist => .dist}/LNReader/plugins.json | 0 {dist => .dist}/LNReader/plugins.min.json | 0 .dist/k1ngfish3r/plugins.json | 486 + .dist/k1ngfish3r/plugins.min.json | 1 + .dist/nyagami/plugins.json | 464 + .dist/nyagami/plugins.min.json | 1 + .github/workflows/updatejson.yml | 6 +- .gitignore | 6 +- .js/plugins/arabic/ArMTL[madara].js | 269 + .js/plugins/arabic/ArNovel[madara].js | 269 + .js/plugins/arabic/HizoManga[madara].js | 269 + .js/plugins/arabic/Novel4Up[madara].js | 269 + .js/plugins/arabic/Riwyat[madara].js | 269 + .js/plugins/arabic/TeamXNovel[madara].js | 269 + .js/plugins/arabic/kolnovel.js | 333 + .js/plugins/chinese/linovelib.js | 525 + .js/plugins/english/BoxNovel[madara].js | 269 + .js/plugins/english/ClickNovel[madara].js | 269 + .js/plugins/english/CrateNovel[madara].js | 269 + .js/plugins/english/DaoNovel[madara].js | 269 + .../english/FansTranslations[madara].js | 269 + .js/plugins/english/FirstKissNovel[madara].js | 269 + .js/plugins/english/FreeNovelMe[madara].js | 269 + .js/plugins/english/Guavaread[madara].js | 269 + .../english/LightNovelHeaven[madara].js | 269 + .js/plugins/english/LunarLetters[madara].js | 269 + .js/plugins/english/MTLNovelClub[madara].js | 269 + .js/plugins/english/MTLNovel[madara].js | 269 + .js/plugins/english/MostNovel[madara].js | 269 + .js/plugins/english/MysticalSeries[madara].js | 269 + .../english/NeoSekaiTranslations[madara].js | 269 + .../english/NocturneTranslations[madara].js | 269 + .../english/NoobchanTranslation[madara].js | 269 + .../english/NovelMultiverse[madara].js | 269 + .js/plugins/english/NovelR18[madara].js | 269 + .js/plugins/english/NovelTranslate[madara].js | 269 + .js/plugins/english/Novelroomnet[madara].js | 269 + .js/plugins/english/Novelstic[madara].js | 269 + .js/plugins/english/OnlyMTL[madara].js | 269 + .js/plugins/english/ReadWebNovels[madara].js | 269 + .../english/SleepyTranslations[madara].js | 269 + .js/plugins/english/SonicMTL[madara].js | 269 + .js/plugins/english/SugarBabies[madara].js | 269 + .../SweetEscapeTranslations[madara].js | 269 + .js/plugins/english/WebNovelLover[madara].js | 269 + .js/plugins/english/WuxiaWorldSite[madara].js | 269 + .../english/ZetroTranslation[madara].js | 269 + .js/plugins/english/ZinnNovel[madara].js | 269 + .js/plugins/english/bestlightnovel.js | 231 + .js/plugins/english/nobleMTL.js | 377 + .js/plugins/english/pandaMTL.js | 304 + .js/plugins/indonesian/MeioNovel[madara].js | 269 + .js/plugins/indonesian/MoreNovel[madara].js | 269 + .js/plugins/indonesian/WBNovel[madara].js | 269 + .js/plugins/portuguese/lightnovelbrasil.js | 378 + .js/plugins/spanish/tunovelaligera.js | 416 + .../turkish/TurkceLightNovels[madara].js | 269 + .js/plugins/turkish/WebNovelOku[madara].js | 269 + .js/plugins/turkish/lshnovel.js | 324 + .js/plugins/vietnamese/LNHako.js | 219 + README.md | 11 +- icons/src/cn/linovelib/icon.png | Bin 0 -> 1053342 bytes index.ts | 4 + js/plugins/arabic/ArMTL[madara].js | 178 - js/plugins/arabic/ArNovel[madara].js | 179 - js/plugins/arabic/HizoManga[madara].js | 179 - js/plugins/arabic/Novel4Up[madara].js | 179 - js/plugins/arabic/Riwyat[madara].js | 179 - js/plugins/arabic/TeamXNovel[madara].js | 178 - js/plugins/arabic/kolnovel.js | 244 - js/plugins/english/BoxNovel[madara].js | 179 - js/plugins/english/ClickNovel[madara].js | 178 - js/plugins/english/CrateNovel[madara].js | 178 - js/plugins/english/DaoNovel[madara].js | 179 - .../english/FansTranslations[madara].js | 179 - js/plugins/english/FirstKissNovel[madara].js | 179 - js/plugins/english/FreeNovelMe[madara].js | 179 - js/plugins/english/Guavaread[madara].js | 179 - .../english/LightNovelHeaven[madara].js | 179 - js/plugins/english/LightNovelReader.js | 138 - js/plugins/english/Ltnovelcom[readwn].js | 163 - js/plugins/english/LunarLetters[madara].js | 179 - js/plugins/english/MTLNovelClub[madara].js | 178 - js/plugins/english/MTLNovel[madara].js | 179 - js/plugins/english/MostNovel[madara].js | 179 - js/plugins/english/MysticalSeries[madara].js | 179 - .../english/NeoSekaiTranslations[madara].js | 179 - .../english/NocturneTranslations[madara].js | 179 - .../english/NoobchanTranslation[madara].js | 178 - js/plugins/english/NovelFullMe.js | 131 - js/plugins/english/NovelMultiverse[madara].js | 179 - js/plugins/english/NovelOnline.js | 104 - js/plugins/english/NovelR18[madara].js | 179 - js/plugins/english/NovelTranslate[madara].js | 179 - js/plugins/english/Novelmtcom[readwn].js | 163 - js/plugins/english/Novelroomnet[madara].js | 178 - js/plugins/english/Novelstic[madara].js | 179 - js/plugins/english/OnlyMTL[madara].js | 178 - js/plugins/english/ReadWebNovels[madara].js | 179 - js/plugins/english/Readwncom[readwn].js | 163 - .../english/SleepyTranslations[madara].js | 179 - js/plugins/english/SonicMTL[madara].js | 179 - js/plugins/english/SugarBabies[madara].js | 178 - .../SweetEscapeTranslations[madara].js | 179 - js/plugins/english/WebNovelLover[madara].js | 179 - js/plugins/english/WuxiaWorldSite[madara].js | 179 - .../english/ZetroTranslation[madara].js | 179 - js/plugins/english/ZinnNovel[madara].js | 179 - js/plugins/english/allnovelfull.js | 177 - js/plugins/english/bestlightnovel.js | 149 - js/plugins/english/comrademao.js | 146 - js/plugins/english/divinedaolibrary.js | 134 - js/plugins/english/earlynovel.js | 174 - js/plugins/english/fastnovel.js | 152 - js/plugins/english/foxaholic.js | 154 - js/plugins/english/freenovelupdates.js | 118 - js/plugins/english/freewebnovel.js | 141 - js/plugins/english/lightnovelpub.js | 171 - js/plugins/english/mtlreader.js | 121 - js/plugins/english/nitroscans.js | 166 - js/plugins/english/nobleMTL.js | 299 - js/plugins/english/novelforest.js | 126 - js/plugins/english/novelfull.js | 147 - js/plugins/english/novelhold.js | 132 - js/plugins/english/novelpub.js | 152 - js/plugins/english/pandaMTL.js | 220 - js/plugins/french/chireads.js | 113 - js/plugins/indonesian/MeioNovel[madara].js | 179 - js/plugins/indonesian/MoreNovel[madara].js | 179 - js/plugins/indonesian/WBNovel[madara].js | 179 - js/plugins/indonesian/indowebnovel.js | 126 - js/plugins/indonesian/novelringan.js | 135 - js/plugins/indonesian/sakuranovel.js | 140 - js/plugins/japanese/Syosetu.js | 201 - js/plugins/korean/Agitoon.js | 141 - js/plugins/portuguese/lightnovelbrasil.js | 300 - js/plugins/russian/Erolate[rulate].js | 195 - js/plugins/russian/LitSpace.js | 232 - js/plugins/russian/Rulate[rulate].js | 195 - js/plugins/russian/authortoday.js | 327 - js/plugins/russian/bookriver.js | 222 - js/plugins/russian/ficbook.js | 2596 -- js/plugins/russian/jaomix.js | 299 - js/plugins/russian/novelTL.js | 855 - js/plugins/russian/ranobehub.js | 1126 - js/plugins/russian/ranobelib.js | 374 - js/plugins/russian/ranoberf.js | 143 - js/plugins/russian/renovels.js | 941 - js/plugins/spanish/hasutl.js | 121 - js/plugins/spanish/novelasligera.js | 157 - js/plugins/spanish/skynovels.js | 116 - js/plugins/spanish/tunovelaligera.js | 146 - js/plugins/spanish/yukitls.js | 160 - .../turkish/TurkceLightNovels[madara].js | 179 - js/plugins/turkish/WebNovelOku[madara].js | 179 - js/plugins/turkish/epiknovel.js | 142 - js/plugins/turkish/lshnovel.js | 247 - js/plugins/ukraine/smakolykytl.js | 139 - js/plugins/vietnamese/LNHako.js | 162 - libs/fetch.ts | 12 +- libs/filterInputs.ts | 3 +- libs/nodeFetch.ts | 9 - nodemon.json | 4 +- package-lock.json | 127 - package.json | 16 +- plugins/arabic/ArMTL[madara].ts | 433 +- plugins/arabic/ArNovel[madara].ts | 433 +- plugins/arabic/HizoManga[madara].ts | 433 +- plugins/arabic/Novel4Up[madara].ts | 433 +- plugins/arabic/Riwyat[madara].ts | 433 +- plugins/arabic/TeamXNovel[madara].ts | 433 +- plugins/arabic/kolnovel.ts | 474 +- plugins/chinese/{.chinese => .gitkeep} | 0 plugins/chinese/linovelib.ts | 559 + plugins/english/.english | 0 plugins/english/BoxNovel[madara].ts | 433 +- plugins/english/ClickNovel[madara].ts | 433 +- plugins/english/CrateNovel[madara].ts | 433 +- plugins/english/DaoNovel[madara].ts | 433 +- plugins/english/FansTranslations[madara].ts | 433 +- plugins/english/FirstKissNovel[madara].ts | 433 +- plugins/english/FreeNovelMe[madara].ts | 433 +- plugins/english/Guavaread[madara].ts | 433 +- plugins/english/LightNovelHeaven[madara].ts | 433 +- ...elReader.ts => LightNovelReader.broken.ts} | 0 plugins/english/Ltnovelcom[readwn].ts | 195 - plugins/english/LunarLetters[madara].ts | 433 +- plugins/english/MTLNovelClub[madara].ts | 433 +- plugins/english/MTLNovel[madara].ts | 433 +- plugins/english/MostNovel[madara].ts | 433 +- plugins/english/MysticalSeries[madara].ts | 433 +- .../english/NeoSekaiTranslations[madara].ts | 433 +- .../english/NocturneTranslations[madara].ts | 433 +- .../english/NoobchanTranslation[madara].ts | 433 +- .../{NovelFullMe.ts => NovelFullMe.broken.ts} | 0 plugins/english/NovelMultiverse[madara].ts | 433 +- .../{NovelOnline.ts => NovelOnline.broken.ts} | 0 plugins/english/NovelR18[madara].ts | 433 +- plugins/english/NovelTranslate[madara].ts | 433 +- plugins/english/Novelmtcom[readwn].ts | 195 - plugins/english/Novelroomnet[madara].ts | 433 +- plugins/english/Novelstic[madara].ts | 433 +- plugins/english/OnlyMTL[madara].ts | 433 +- plugins/english/ReadWebNovels[madara].ts | 433 +- plugins/english/Readwncom[readwn].ts | 195 - plugins/english/SleepyTranslations[madara].ts | 433 +- plugins/english/SonicMTL[madara].ts | 433 +- plugins/english/SugarBabies[madara].ts | 433 +- .../SweetEscapeTranslations[madara].ts | 433 +- plugins/english/WebNovelLover[madara].ts | 433 +- plugins/english/WuxiaWorldSite[madara].ts | 433 +- plugins/english/ZetroTranslation[madara].ts | 433 +- plugins/english/ZinnNovel[madara].ts | 433 +- ...allnovelfull.ts => allnovelfull.broken.ts} | 0 plugins/english/bestlightnovel.ts | 174 +- .../{comrademao.ts => comrademao.broken.ts} | 0 ...olibrary.ts => divinedaolibrary.broken.ts} | 0 .../{earlynovel.ts => earlynovel.broken.ts} | 0 .../{fastnovel.ts => fastnovel.broken.ts} | 0 .../{foxaholic.ts => foxaholic.broken.ts} | 0 ...lupdates.ts => freenovelupdates.broken.ts} | 0 ...freewebnovel.ts => freewebnovel.broken.ts} | 0 ...ghtnovelpub.ts => lightnovelpub.broken.ts} | 0 .../{mtlreader.ts => mtlreader.broken.ts} | 0 .../{nitroscans.ts => nitroscans.broken.ts} | 0 plugins/english/nobleMTL.ts | 453 +- .../{novelforest.ts => novelforest.broken.ts} | 0 .../{novelfull.ts => novelfull.broken.ts} | 0 .../{novelhold.ts => novelhold.broken.ts} | 0 .../{novelpub.ts => novelpub.broken.ts} | 0 plugins/english/pandaMTL.ts | 322 +- plugins/french/.french | 0 .../{chireads.ts => chireads.broken.ts} | 0 plugins/indonesian/.indonesian | 0 plugins/indonesian/MeioNovel[madara].ts | 433 +- plugins/indonesian/MoreNovel[madara].ts | 433 +- plugins/indonesian/WBNovel[madara].ts | 433 +- ...indowebnovel.ts => indowebnovel.broken.ts} | 0 .../{novelringan.ts => novelringan.broken.ts} | 0 .../{sakuranovel.ts => sakuranovel.broken.ts} | 0 plugins/japanese/.japanese | 0 .../{Syosetu.ts => Syosetu.broken.ts} | 0 .../korean/{Agitoon.ts => Agitoon.broken.ts} | 0 plugins/portuguese/.portuguese | 0 plugins/portuguese/lightnovelbrasil.ts | 453 +- plugins/russian/.russian | 0 plugins/russian/Erolate[rulate].ts | 226 - .../{LitSpace.ts => LitSpace.broken.ts} | 0 plugins/russian/Rulate[rulate].ts | 226 - .../{authortoday.ts => authortoday.broken.ts} | 0 .../{bookriver.ts => bookriver.broken.ts} | 0 .../russian/{ficbook.ts => ficbook.broken.ts} | 0 .../russian/{jaomix.ts => jaomix.broken.ts} | 0 .../russian/{novelTL.ts => novelTL.broken.ts} | 0 .../{ranobehub.ts => ranobehub.broken.ts} | 0 .../{ranobelib.ts => ranobelib.broken.ts} | 0 .../{ranoberf.ts => ranoberf.broken.ts} | 0 .../{renovels.ts => renovels.broken.ts} | 0 plugins/spanish/.spanish | 0 .../spanish/{hasutl.ts => hasutl.broken.ts} | 0 ...velasligera.ts => novelasligera.broken.ts} | 0 .../{skynovels.ts => skynovels.broken.ts} | 0 plugins/spanish/tunovelaligera.ts | 374 +- .../spanish/{yukitls.ts => yukitls.broken.ts} | 0 plugins/turkish/.turkish | 0 plugins/turkish/TurkceLightNovels[madara].ts | 433 +- plugins/turkish/WebNovelOku[madara].ts | 433 +- .../{epiknovel.ts => epiknovel.broken.ts} | 0 plugins/turkish/lshnovel.ts | 347 +- .../{smakolykytl.ts => smakolykytl.broken.ts} | 0 plugins/vietnamese/.vietnamese | 0 plugins/vietnamese/LNHako.ts | 334 +- scripts/clearMultisrc.ts | 12 + scripts/json_plugins.ts | 14 +- scripts/multisrc/generate.ts | 1 - scripts/multisrc/madara/generator.ts | 244 +- scripts/multisrc/madara/sources.json | 2 +- scripts/multisrc/madara/template.ts | 248 + scripts/multisrc/readwn/generator.ts | 221 - scripts/multisrc/readwn/sources.json | 818 - scripts/multisrc/rulate/generator.ts | 251 - scripts/multisrc/rulate/sources.json | 22556 ---------------- template.min.ts | 54 - template.ts | 90 - test_web/api/plugins.ts | 21 +- test_web/index.html | 37 +- test_web/static/css/index.css | 9 + test_web/static/css/mdb5.css | 19301 +++++++++++++ test_web/static/js/bootstrap.min.js | 18 + test_web/static/js/index.js | 519 +- .../js/{jquery-3.6.4.min.js => jquery.min.js} | 0 test_web/static/js/mdb5.js | 19710 ++++++++++++++ tsconfig.json | 8 +- types/plugin.ts | 92 +- types/types.ts | 2 +- 295 files changed, 67636 insertions(+), 57286 deletions(-) rename {dist => .dist}/LNReader/plugins.json (100%) rename {dist => .dist}/LNReader/plugins.min.json (100%) create mode 100644 .dist/k1ngfish3r/plugins.json create mode 100644 .dist/k1ngfish3r/plugins.min.json create mode 100644 .dist/nyagami/plugins.json create mode 100644 .dist/nyagami/plugins.min.json create mode 100644 .js/plugins/arabic/ArMTL[madara].js create mode 100644 .js/plugins/arabic/ArNovel[madara].js create mode 100644 .js/plugins/arabic/HizoManga[madara].js create mode 100644 .js/plugins/arabic/Novel4Up[madara].js create mode 100644 .js/plugins/arabic/Riwyat[madara].js create mode 100644 .js/plugins/arabic/TeamXNovel[madara].js create mode 100644 .js/plugins/arabic/kolnovel.js create mode 100644 .js/plugins/chinese/linovelib.js create mode 100644 .js/plugins/english/BoxNovel[madara].js create mode 100644 .js/plugins/english/ClickNovel[madara].js create mode 100644 .js/plugins/english/CrateNovel[madara].js create mode 100644 .js/plugins/english/DaoNovel[madara].js create mode 100644 .js/plugins/english/FansTranslations[madara].js create mode 100644 .js/plugins/english/FirstKissNovel[madara].js create mode 100644 .js/plugins/english/FreeNovelMe[madara].js create mode 100644 .js/plugins/english/Guavaread[madara].js create mode 100644 .js/plugins/english/LightNovelHeaven[madara].js create mode 100644 .js/plugins/english/LunarLetters[madara].js create mode 100644 .js/plugins/english/MTLNovelClub[madara].js create mode 100644 .js/plugins/english/MTLNovel[madara].js create mode 100644 .js/plugins/english/MostNovel[madara].js create mode 100644 .js/plugins/english/MysticalSeries[madara].js create mode 100644 .js/plugins/english/NeoSekaiTranslations[madara].js create mode 100644 .js/plugins/english/NocturneTranslations[madara].js create mode 100644 .js/plugins/english/NoobchanTranslation[madara].js create mode 100644 .js/plugins/english/NovelMultiverse[madara].js create mode 100644 .js/plugins/english/NovelR18[madara].js create mode 100644 .js/plugins/english/NovelTranslate[madara].js create mode 100644 .js/plugins/english/Novelroomnet[madara].js create mode 100644 .js/plugins/english/Novelstic[madara].js create mode 100644 .js/plugins/english/OnlyMTL[madara].js create mode 100644 .js/plugins/english/ReadWebNovels[madara].js create mode 100644 .js/plugins/english/SleepyTranslations[madara].js create mode 100644 .js/plugins/english/SonicMTL[madara].js create mode 100644 .js/plugins/english/SugarBabies[madara].js create mode 100644 .js/plugins/english/SweetEscapeTranslations[madara].js create mode 100644 .js/plugins/english/WebNovelLover[madara].js create mode 100644 .js/plugins/english/WuxiaWorldSite[madara].js create mode 100644 .js/plugins/english/ZetroTranslation[madara].js create mode 100644 .js/plugins/english/ZinnNovel[madara].js create mode 100644 .js/plugins/english/bestlightnovel.js create mode 100644 .js/plugins/english/nobleMTL.js create mode 100644 .js/plugins/english/pandaMTL.js create mode 100644 .js/plugins/indonesian/MeioNovel[madara].js create mode 100644 .js/plugins/indonesian/MoreNovel[madara].js create mode 100644 .js/plugins/indonesian/WBNovel[madara].js create mode 100644 .js/plugins/portuguese/lightnovelbrasil.js create mode 100644 .js/plugins/spanish/tunovelaligera.js create mode 100644 .js/plugins/turkish/TurkceLightNovels[madara].js create mode 100644 .js/plugins/turkish/WebNovelOku[madara].js create mode 100644 .js/plugins/turkish/lshnovel.js create mode 100644 .js/plugins/vietnamese/LNHako.js create mode 100644 icons/src/cn/linovelib/icon.png delete mode 100644 js/plugins/arabic/ArMTL[madara].js delete mode 100644 js/plugins/arabic/ArNovel[madara].js delete mode 100644 js/plugins/arabic/HizoManga[madara].js delete mode 100644 js/plugins/arabic/Novel4Up[madara].js delete mode 100644 js/plugins/arabic/Riwyat[madara].js delete mode 100644 js/plugins/arabic/TeamXNovel[madara].js delete mode 100644 js/plugins/arabic/kolnovel.js delete mode 100644 js/plugins/english/BoxNovel[madara].js delete mode 100644 js/plugins/english/ClickNovel[madara].js delete mode 100644 js/plugins/english/CrateNovel[madara].js delete mode 100644 js/plugins/english/DaoNovel[madara].js delete mode 100644 js/plugins/english/FansTranslations[madara].js delete mode 100644 js/plugins/english/FirstKissNovel[madara].js delete mode 100644 js/plugins/english/FreeNovelMe[madara].js delete mode 100644 js/plugins/english/Guavaread[madara].js delete mode 100644 js/plugins/english/LightNovelHeaven[madara].js delete mode 100644 js/plugins/english/LightNovelReader.js delete mode 100644 js/plugins/english/Ltnovelcom[readwn].js delete mode 100644 js/plugins/english/LunarLetters[madara].js delete mode 100644 js/plugins/english/MTLNovelClub[madara].js delete mode 100644 js/plugins/english/MTLNovel[madara].js delete mode 100644 js/plugins/english/MostNovel[madara].js delete mode 100644 js/plugins/english/MysticalSeries[madara].js delete mode 100644 js/plugins/english/NeoSekaiTranslations[madara].js delete mode 100644 js/plugins/english/NocturneTranslations[madara].js delete mode 100644 js/plugins/english/NoobchanTranslation[madara].js delete mode 100644 js/plugins/english/NovelFullMe.js delete mode 100644 js/plugins/english/NovelMultiverse[madara].js delete mode 100644 js/plugins/english/NovelOnline.js delete mode 100644 js/plugins/english/NovelR18[madara].js delete mode 100644 js/plugins/english/NovelTranslate[madara].js delete mode 100644 js/plugins/english/Novelmtcom[readwn].js delete mode 100644 js/plugins/english/Novelroomnet[madara].js delete mode 100644 js/plugins/english/Novelstic[madara].js delete mode 100644 js/plugins/english/OnlyMTL[madara].js delete mode 100644 js/plugins/english/ReadWebNovels[madara].js delete mode 100644 js/plugins/english/Readwncom[readwn].js delete mode 100644 js/plugins/english/SleepyTranslations[madara].js delete mode 100644 js/plugins/english/SonicMTL[madara].js delete mode 100644 js/plugins/english/SugarBabies[madara].js delete mode 100644 js/plugins/english/SweetEscapeTranslations[madara].js delete mode 100644 js/plugins/english/WebNovelLover[madara].js delete mode 100644 js/plugins/english/WuxiaWorldSite[madara].js delete mode 100644 js/plugins/english/ZetroTranslation[madara].js delete mode 100644 js/plugins/english/ZinnNovel[madara].js delete mode 100644 js/plugins/english/allnovelfull.js delete mode 100644 js/plugins/english/bestlightnovel.js delete mode 100644 js/plugins/english/comrademao.js delete mode 100644 js/plugins/english/divinedaolibrary.js delete mode 100644 js/plugins/english/earlynovel.js delete mode 100644 js/plugins/english/fastnovel.js delete mode 100644 js/plugins/english/foxaholic.js delete mode 100644 js/plugins/english/freenovelupdates.js delete mode 100644 js/plugins/english/freewebnovel.js delete mode 100644 js/plugins/english/lightnovelpub.js delete mode 100644 js/plugins/english/mtlreader.js delete mode 100644 js/plugins/english/nitroscans.js delete mode 100644 js/plugins/english/nobleMTL.js delete mode 100644 js/plugins/english/novelforest.js delete mode 100644 js/plugins/english/novelfull.js delete mode 100644 js/plugins/english/novelhold.js delete mode 100644 js/plugins/english/novelpub.js delete mode 100644 js/plugins/english/pandaMTL.js delete mode 100644 js/plugins/french/chireads.js delete mode 100644 js/plugins/indonesian/MeioNovel[madara].js delete mode 100644 js/plugins/indonesian/MoreNovel[madara].js delete mode 100644 js/plugins/indonesian/WBNovel[madara].js delete mode 100644 js/plugins/indonesian/indowebnovel.js delete mode 100644 js/plugins/indonesian/novelringan.js delete mode 100644 js/plugins/indonesian/sakuranovel.js delete mode 100644 js/plugins/japanese/Syosetu.js delete mode 100644 js/plugins/korean/Agitoon.js delete mode 100644 js/plugins/portuguese/lightnovelbrasil.js delete mode 100644 js/plugins/russian/Erolate[rulate].js delete mode 100644 js/plugins/russian/LitSpace.js delete mode 100644 js/plugins/russian/Rulate[rulate].js delete mode 100644 js/plugins/russian/authortoday.js delete mode 100644 js/plugins/russian/bookriver.js delete mode 100644 js/plugins/russian/ficbook.js delete mode 100644 js/plugins/russian/jaomix.js delete mode 100644 js/plugins/russian/novelTL.js delete mode 100644 js/plugins/russian/ranobehub.js delete mode 100644 js/plugins/russian/ranobelib.js delete mode 100644 js/plugins/russian/ranoberf.js delete mode 100644 js/plugins/russian/renovels.js delete mode 100644 js/plugins/spanish/hasutl.js delete mode 100644 js/plugins/spanish/novelasligera.js delete mode 100644 js/plugins/spanish/skynovels.js delete mode 100644 js/plugins/spanish/tunovelaligera.js delete mode 100644 js/plugins/spanish/yukitls.js delete mode 100644 js/plugins/turkish/TurkceLightNovels[madara].js delete mode 100644 js/plugins/turkish/WebNovelOku[madara].js delete mode 100644 js/plugins/turkish/epiknovel.js delete mode 100644 js/plugins/turkish/lshnovel.js delete mode 100644 js/plugins/ukraine/smakolykytl.js delete mode 100644 js/plugins/vietnamese/LNHako.js delete mode 100644 libs/nodeFetch.ts rename plugins/chinese/{.chinese => .gitkeep} (100%) create mode 100644 plugins/chinese/linovelib.ts delete mode 100644 plugins/english/.english rename plugins/english/{LightNovelReader.ts => LightNovelReader.broken.ts} (100%) delete mode 100644 plugins/english/Ltnovelcom[readwn].ts rename plugins/english/{NovelFullMe.ts => NovelFullMe.broken.ts} (100%) rename plugins/english/{NovelOnline.ts => NovelOnline.broken.ts} (100%) delete mode 100644 plugins/english/Novelmtcom[readwn].ts delete mode 100644 plugins/english/Readwncom[readwn].ts rename plugins/english/{allnovelfull.ts => allnovelfull.broken.ts} (100%) rename plugins/english/{comrademao.ts => comrademao.broken.ts} (100%) rename plugins/english/{divinedaolibrary.ts => divinedaolibrary.broken.ts} (100%) rename plugins/english/{earlynovel.ts => earlynovel.broken.ts} (100%) rename plugins/english/{fastnovel.ts => fastnovel.broken.ts} (100%) rename plugins/english/{foxaholic.ts => foxaholic.broken.ts} (100%) rename plugins/english/{freenovelupdates.ts => freenovelupdates.broken.ts} (100%) rename plugins/english/{freewebnovel.ts => freewebnovel.broken.ts} (100%) rename plugins/english/{lightnovelpub.ts => lightnovelpub.broken.ts} (100%) rename plugins/english/{mtlreader.ts => mtlreader.broken.ts} (100%) rename plugins/english/{nitroscans.ts => nitroscans.broken.ts} (100%) rename plugins/english/{novelforest.ts => novelforest.broken.ts} (100%) rename plugins/english/{novelfull.ts => novelfull.broken.ts} (100%) rename plugins/english/{novelhold.ts => novelhold.broken.ts} (100%) rename plugins/english/{novelpub.ts => novelpub.broken.ts} (100%) delete mode 100644 plugins/french/.french rename plugins/french/{chireads.ts => chireads.broken.ts} (100%) delete mode 100644 plugins/indonesian/.indonesian rename plugins/indonesian/{indowebnovel.ts => indowebnovel.broken.ts} (100%) rename plugins/indonesian/{novelringan.ts => novelringan.broken.ts} (100%) rename plugins/indonesian/{sakuranovel.ts => sakuranovel.broken.ts} (100%) delete mode 100644 plugins/japanese/.japanese rename plugins/japanese/{Syosetu.ts => Syosetu.broken.ts} (100%) rename plugins/korean/{Agitoon.ts => Agitoon.broken.ts} (100%) delete mode 100644 plugins/portuguese/.portuguese delete mode 100644 plugins/russian/.russian delete mode 100644 plugins/russian/Erolate[rulate].ts rename plugins/russian/{LitSpace.ts => LitSpace.broken.ts} (100%) delete mode 100644 plugins/russian/Rulate[rulate].ts rename plugins/russian/{authortoday.ts => authortoday.broken.ts} (100%) rename plugins/russian/{bookriver.ts => bookriver.broken.ts} (100%) rename plugins/russian/{ficbook.ts => ficbook.broken.ts} (100%) rename plugins/russian/{jaomix.ts => jaomix.broken.ts} (100%) rename plugins/russian/{novelTL.ts => novelTL.broken.ts} (100%) rename plugins/russian/{ranobehub.ts => ranobehub.broken.ts} (100%) rename plugins/russian/{ranobelib.ts => ranobelib.broken.ts} (100%) rename plugins/russian/{ranoberf.ts => ranoberf.broken.ts} (100%) rename plugins/russian/{renovels.ts => renovels.broken.ts} (100%) delete mode 100644 plugins/spanish/.spanish rename plugins/spanish/{hasutl.ts => hasutl.broken.ts} (100%) rename plugins/spanish/{novelasligera.ts => novelasligera.broken.ts} (100%) rename plugins/spanish/{skynovels.ts => skynovels.broken.ts} (100%) rename plugins/spanish/{yukitls.ts => yukitls.broken.ts} (100%) delete mode 100644 plugins/turkish/.turkish rename plugins/turkish/{epiknovel.ts => epiknovel.broken.ts} (100%) rename plugins/ukraine/{smakolykytl.ts => smakolykytl.broken.ts} (100%) delete mode 100644 plugins/vietnamese/.vietnamese create mode 100644 scripts/clearMultisrc.ts create mode 100644 scripts/multisrc/madara/template.ts delete mode 100644 scripts/multisrc/readwn/generator.ts delete mode 100644 scripts/multisrc/readwn/sources.json delete mode 100644 scripts/multisrc/rulate/generator.ts delete mode 100644 scripts/multisrc/rulate/sources.json delete mode 100644 template.min.ts delete mode 100644 template.ts create mode 100644 test_web/static/css/mdb5.css create mode 100644 test_web/static/js/bootstrap.min.js rename test_web/static/js/{jquery-3.6.4.min.js => jquery.min.js} (100%) create mode 100644 test_web/static/js/mdb5.js diff --git a/dist/LNReader/plugins.json b/.dist/LNReader/plugins.json similarity index 100% rename from dist/LNReader/plugins.json rename to .dist/LNReader/plugins.json diff --git a/dist/LNReader/plugins.min.json b/.dist/LNReader/plugins.min.json similarity index 100% rename from dist/LNReader/plugins.min.json rename to .dist/LNReader/plugins.min.json diff --git a/.dist/k1ngfish3r/plugins.json b/.dist/k1ngfish3r/plugins.json new file mode 100644 index 0000000..a5889a9 --- /dev/null +++ b/.dist/k1ngfish3r/plugins.json @@ -0,0 +1,486 @@ +{ + "العربية": [ + { + "id": "ar-mtl", + "name": "ArMTL[madara]", + "site": "https://ar-mtl.club/", + "lang": "العربية", + "version": "1.0.0", + "url": "https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/.js/plugins/arabic/ArMTL[madara].js", + "iconUrl": "https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/icons/multisrc/madara/icons/armtl.png" + }, + { + "id": "arnovel", + "name": "ArNovel[madara]", + "site": "https://arnovel.me/", + "lang": "العربية", + "version": "1.0.0", + "url": "https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/.js/plugins/arabic/ArNovel[madara].js", + "iconUrl": "https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/icons/multisrc/madara/icons/arnovel.png" + }, + { + "id": "hizomanga", + "name": "HizoManga[madara]", + "site": "https://hizomanga.com/", + "lang": "العربية", + "version": "1.0.0", + "url": "https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/.js/plugins/arabic/HizoManga[madara].js", + "iconUrl": "https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/icons/multisrc/madara/icons/hizomanga.png" + }, + { + "id": "kolnovel", + "name": "KolNovel", + "site": "https://kolnovel.lol/", + "lang": "العربية", + "version": "1.0.0", + "url": "https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/.js/plugins/arabic/kolnovel.js", + "iconUrl": "https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/icons/multisrc/wpmangastream/icons/kolnovel.png" + }, + { + "id": "novel4up", + "name": "Novel4Up[madara]", + "site": "https://novel4up.com/", + "lang": "العربية", + "version": "1.0.0", + "url": "https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/.js/plugins/arabic/Novel4Up[madara].js", + "iconUrl": "https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/icons/multisrc/madara/icons/novel4up.png" + }, + { + "id": "riwyat", + "name": "Riwyat[madara]", + "site": "https://riwyat.com/", + "lang": "العربية", + "version": "1.0.0", + "url": "https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/.js/plugins/arabic/Riwyat[madara].js", + "iconUrl": "https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/icons/multisrc/madara/icons/riwyat.png" + }, + { + "id": "teamxnovel", + "name": "TeamXNovel[madara]", + "site": "https://teamxnovel.com/", + "lang": "العربية", + "version": "1.0.0", + "url": "https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/.js/plugins/arabic/TeamXNovel[madara].js", + "iconUrl": "https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/icons/multisrc/madara/icons/teamxnovel.png" + } + ], + "中文, 汉语, 漢語": [ + { + "id": "linovelib", + "name": "Linovelib", + "site": "https://w.linovelib.com", + "lang": "中文, 汉语, 漢語", + "version": "1.0.0", + "url": "https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/.js/plugins/chinese/linovelib.js", + "iconUrl": "https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/icons/src/cn/linovelib/icon.png" + } + ], + "English": [ + { + "id": "1stkissnovel", + "name": "FirstKissNovel[madara]", + "site": "https://1stkissnovel.org/", + "lang": "English", + "version": "1.0.0", + "url": "https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/.js/plugins/english/FirstKissNovel[madara].js", + "iconUrl": "https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/icons/multisrc/madara/icons/firstkissnovel.png" + }, + { + "id": "BLN.com", + "name": "BestLightNovel", + "site": "https://bestlightnovel.com/", + "lang": "English", + "version": "1.0.0", + "url": "https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/.js/plugins/english/bestlightnovel.js", + "iconUrl": "https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/icons/src/en/bestlightnovel/icon.png" + }, + { + "id": "boxnovel", + "name": "BoxNovel[madara]", + "site": "https://boxnovel.com/", + "lang": "English", + "version": "1.0.0", + "url": "https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/.js/plugins/english/BoxNovel[madara].js", + "iconUrl": "https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/icons/multisrc/madara/icons/boxnovel.png" + }, + { + "id": "clicknovel", + "name": "ClickNovel[madara]", + "site": "https://clicknovel.net/", + "lang": "English", + "version": "1.0.0", + "url": "https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/.js/plugins/english/ClickNovel[madara].js", + "iconUrl": "https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/icons/multisrc/madara/icons/clicknovel.png" + }, + { + "id": "cratenovel", + "name": "CrateNovel[madara]", + "site": "https://cratenovel.com/", + "lang": "English", + "version": "1.0.0", + "url": "https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/.js/plugins/english/CrateNovel[madara].js", + "iconUrl": "https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/icons/multisrc/madara/icons/cratenovel.png" + }, + { + "id": "daonovel", + "name": "DaoNovel[madara]", + "site": "https://daonovel.com/", + "lang": "English", + "version": "1.0.0", + "url": "https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/.js/plugins/english/DaoNovel[madara].js", + "iconUrl": "https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/icons/multisrc/madara/icons/daonovel.png" + }, + { + "id": "fanTLS", + "name": "Fans Translations[madara]", + "site": "https://fanstranslations.com/", + "lang": "English", + "version": "1.0.0", + "url": "https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/.js/plugins/english/FansTranslations[madara].js", + "iconUrl": "https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/icons/multisrc/madara/icons/fanstranslations.png" + }, + { + "id": "freenovel.me", + "name": "FreeNovelMe[madara]", + "site": "https://freenovel.me/", + "lang": "English", + "version": "1.0.0", + "url": "https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/.js/plugins/english/FreeNovelMe[madara].js", + "iconUrl": "https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/icons/multisrc/madara/icons/freenovelme.png" + }, + { + "id": "guavaread", + "name": "Guavaread[madara]", + "site": "https://guavaread.com/", + "lang": "English", + "version": "1.0.0", + "url": "https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/.js/plugins/english/Guavaread[madara].js", + "iconUrl": "https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/icons/multisrc/madara/icons/guavaread.png" + }, + { + "id": "lnheaven", + "name": "LightNovelHeaven[madara]", + "site": "https://lightnovelheaven.com/", + "lang": "English", + "version": "1.0.0", + "url": "https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/.js/plugins/english/LightNovelHeaven[madara].js", + "iconUrl": "https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/icons/multisrc/madara/icons/lightnovelheaven.png" + }, + { + "id": "lunarletters", + "name": "LunarLetters[madara]", + "site": "https://www.lunarletters.com/", + "lang": "English", + "version": "1.0.0", + "url": "https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/.js/plugins/english/LunarLetters[madara].js", + "iconUrl": "https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/icons/multisrc/madara/icons/lunarletters.png" + }, + { + "id": "mostnovel", + "name": "MostNovel[madara]", + "site": "https://mostnovel.com/", + "lang": "English", + "version": "1.0.0", + "url": "https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/.js/plugins/english/MostNovel[madara].js", + "iconUrl": "https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/icons/multisrc/madara/icons/mostnovel.png" + }, + { + "id": "mtl-novel", + "name": "MTL-Novel[madara]", + "site": "https://mtl-novel.com/", + "lang": "English", + "version": "1.0.0", + "url": "https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/.js/plugins/english/MTLNovel[madara].js", + "iconUrl": "https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/icons/multisrc/madara/icons/mtl-novel.png" + }, + { + "id": "mtlnovel.club", + "name": "MTLNovel.Club[madara]", + "site": "https://mtlnovel.club/", + "lang": "English", + "version": "1.0.0", + "url": "https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/.js/plugins/english/MTLNovelClub[madara].js", + "iconUrl": "https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/icons/multisrc/madara/icons/mtlnovel.club.png" + }, + { + "id": "mysticalmerries", + "name": "MysticalSeries[madara]", + "site": "https://mysticalmerries.com/", + "lang": "English", + "version": "1.0.0", + "url": "https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/.js/plugins/english/MysticalSeries[madara].js", + "iconUrl": "https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/icons/multisrc/madara/icons/mysticalseries.png" + }, + { + "id": "neosekaiTLS", + "name": "NeoSekai Translations[madara]", + "site": "https://www.neosekaitranslations.com/", + "lang": "English", + "version": "1.0.0", + "url": "https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/.js/plugins/english/NeoSekaiTranslations[madara].js", + "iconUrl": "https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/icons/multisrc/madara/icons/neosekaitranslations.png" + }, + { + "id": "noblemtl", + "name": "NobleMTL", + "site": "https://noblemtl.com/", + "lang": "English", + "version": "1.0.0", + "url": "https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/.js/plugins/english/nobleMTL.js", + "iconUrl": "https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/icons/src/en/noblemtl/icon.png" + }, + { + "id": "nocturneTLS", + "name": "Nocturne Translations[madara]", + "site": "https://nocturnetls.net/", + "lang": "English", + "version": "1.0.0", + "url": "https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/.js/plugins/english/NocturneTranslations[madara].js", + "iconUrl": "https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/icons/multisrc/madara/icons/nocturnetranslations.png" + }, + { + "id": "noobchanTL", + "name": "Noobchan Translation[madara]", + "site": "https://noobchan.xyz/", + "lang": "English", + "version": "1.0.0", + "url": "https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/.js/plugins/english/NoobchanTranslation[madara].js", + "iconUrl": "https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/icons/multisrc/madara/icons/noobchantranslation.png" + }, + { + "id": "novelmultiverse", + "name": "NovelMultiverse[madara]", + "site": "https://www.novelmultiverse.com/", + "lang": "English", + "version": "1.0.0", + "url": "https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/.js/plugins/english/NovelMultiverse[madara].js", + "iconUrl": "https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/icons/multisrc/madara/icons/novelmultiverse.png" + }, + { + "id": "novelr18", + "name": "NovelR18[madara]", + "site": "https://novelr18.com/", + "lang": "English", + "version": "1.0.0", + "url": "https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/.js/plugins/english/NovelR18[madara].js", + "iconUrl": "https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/icons/multisrc/madara/icons/novelr18.png" + }, + { + "id": "novelroom", + "name": "Novelroom.net[madara]", + "site": "https://novelroom.net/", + "lang": "English", + "version": "1.0.0", + "url": "https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/.js/plugins/english/Novelroomnet[madara].js", + "iconUrl": "https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/icons/multisrc/madara/icons/novelroom.net.png" + }, + { + "id": "novelstic", + "name": "Novelstic[madara]", + "site": "https://novelstic.com/", + "lang": "English", + "version": "1.0.0", + "url": "https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/.js/plugins/english/Novelstic[madara].js", + "iconUrl": "https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/icons/multisrc/madara/icons/novelstic.png" + }, + { + "id": "novelTL", + "name": "NovelTranslate[madara]", + "site": "https://noveltranslate.com/", + "lang": "English", + "version": "1.0.0", + "url": "https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/.js/plugins/english/NovelTranslate[madara].js", + "iconUrl": "https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/icons/multisrc/madara/icons/noveltranslate.png" + }, + { + "id": "onlymtl", + "name": "OnlyMTL[madara]", + "site": "https://www.onlymtl.com/", + "lang": "English", + "version": "1.0.0", + "url": "https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/.js/plugins/english/OnlyMTL[madara].js", + "iconUrl": "https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/icons/multisrc/madara/icons/onlymtl.png" + }, + { + "id": "pandamtl", + "name": "PandaMTL", + "site": "https://pandamtl.com/", + "lang": "English", + "version": "1.0.0", + "url": "https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/.js/plugins/english/pandaMTL.js", + "iconUrl": "https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/icons/src/en/wordpress/icon.png" + }, + { + "id": "readwebnovels", + "name": "ReadWebNovels[madara]", + "site": "https://readwebnovels.net/", + "lang": "English", + "version": "1.0.0", + "url": "https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/.js/plugins/english/ReadWebNovels[madara].js", + "iconUrl": "https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/icons/multisrc/madara/icons/readwebnovels.png" + }, + { + "id": "sleeptTLS", + "name": "SleepyTranslations[madara]", + "site": "https://sleepytranslations.com/", + "lang": "English", + "version": "1.0.0", + "url": "https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/.js/plugins/english/SleepyTranslations[madara].js", + "iconUrl": "https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/icons/multisrc/madara/icons/sleepytranslations.png" + }, + { + "id": "sonicmtl", + "name": "SonicMTL[madara]", + "site": "https://www.sonicmtl.com/", + "lang": "English", + "version": "1.0.0", + "url": "https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/.js/plugins/english/SonicMTL[madara].js", + "iconUrl": "https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/icons/multisrc/madara/icons/sonicmtl.png" + }, + { + "id": "sugarbbscan", + "name": "Sugar Babies[madara]", + "site": "https://sugarbbscan.com/", + "lang": "English", + "version": "1.0.0", + "url": "https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/.js/plugins/english/SugarBabies[madara].js", + "iconUrl": "https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/icons/multisrc/madara/icons/sugarbabies.png" + }, + { + "id": "sweetEscapeTL", + "name": "Sweet Escape Translations[madara]", + "site": "https://sweetescapetranslations.com/", + "lang": "English", + "version": "1.0.0", + "url": "https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/.js/plugins/english/SweetEscapeTranslations[madara].js", + "iconUrl": "https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/icons/multisrc/madara/icons/sweetescapetranslations.png" + }, + { + "id": "webnovelover", + "name": "WebNovelLover[madara]", + "site": "https://www.webnovelover.com/", + "lang": "English", + "version": "1.0.0", + "url": "https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/.js/plugins/english/WebNovelLover[madara].js", + "iconUrl": "https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/icons/multisrc/madara/icons/webnovellover.png" + }, + { + "id": "wuxiaworld.site", + "name": "WuxiaWorld.Site[madara]", + "site": "https://wuxiaworld.site/", + "lang": "English", + "version": "1.0.0", + "url": "https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/.js/plugins/english/WuxiaWorldSite[madara].js", + "iconUrl": "https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/icons/multisrc/madara/icons/wuxiaworld.site.png" + }, + { + "id": "zetroTL", + "name": "Zetro Translation[madara]", + "site": "https://zetrotranslation.com/", + "lang": "English", + "version": "1.0.0", + "url": "https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/.js/plugins/english/ZetroTranslation[madara].js", + "iconUrl": "https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/icons/multisrc/madara/icons/zetrotranslation.png" + }, + { + "id": "zinnovel", + "name": "ZinnNovel[madara]", + "site": "https://zinnovel.com/", + "lang": "English", + "version": "1.0.0", + "url": "https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/.js/plugins/english/ZinnNovel[madara].js", + "iconUrl": "https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/icons/multisrc/madara/icons/zinnnovel.png" + } + ], + "Bahasa Indonesia": [ + { + "id": "meionovel", + "name": "MeioNovel[madara]", + "site": "https://meionovel.id/", + "lang": "Bahasa Indonesia", + "version": "1.0.0", + "url": "https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/.js/plugins/indonesian/MeioNovel[madara].js", + "iconUrl": "https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/icons/multisrc/madara/icons/meionovel.png" + }, + { + "id": "morenovel", + "name": "MoreNovel[madara]", + "site": "https://morenovel.net/", + "lang": "Bahasa Indonesia", + "version": "1.0.0", + "url": "https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/.js/plugins/indonesian/MoreNovel[madara].js", + "iconUrl": "https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/icons/multisrc/madara/icons/morenovel.png" + }, + { + "id": "wbnovel", + "name": "WBNovel[madara]", + "site": "https://wbnovel.com/", + "lang": "Bahasa Indonesia", + "version": "1.0.0", + "url": "https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/.js/plugins/indonesian/WBNovel[madara].js", + "iconUrl": "https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/icons/multisrc/madara/icons/wbnovel.png" + } + ], + "Português": [ + { + "id": "lightnovelbrasil", + "name": "Light Novel Brasil", + "site": "https://lightnovelbrasil.com/", + "lang": "Português", + "version": "1.0.0", + "url": "https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/.js/plugins/portuguese/lightnovelbrasil.js", + "iconUrl": "https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/icons/multisrc/wpmangastream/icons/lightnovelbrasil.png" + } + ], + "español, castellano": [ + { + "id": "tunovelaligera", + "name": "TuNovelaLigera", + "site": "https://tunovelaligera.com/", + "lang": "español, castellano", + "version": "1.0.0", + "url": "https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/.js/plugins/spanish/tunovelaligera.js", + "iconUrl": "https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/icons/src/es/tunovelaligera/icon.png" + } + ], + "Türkçe": [ + { + "id": "lshnovel", + "name": "Liebe Schnee Hiver Novel", + "site": "https://lshnovel.com/", + "lang": "Türkçe", + "version": "1.0.0", + "url": "https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/.js/plugins/turkish/lshnovel.js", + "iconUrl": "https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/icons/multisrc/wpmangastream/icons/lshnovel.png" + }, + { + "id": "turkcelightnovels", + "name": "TurkceLightNovels[madara]", + "site": "https://turkcelightnovels.com/", + "lang": "Türkçe", + "version": "1.0.0", + "url": "https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/.js/plugins/turkish/TurkceLightNovels[madara].js", + "iconUrl": "https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/icons/multisrc/madara/icons/turkcelightnovels.png" + }, + { + "id": "webnoveloku", + "name": "WebNovelOku [madara]", + "site": "https://www.webnoveloku.com/", + "lang": "Türkçe", + "version": "1.0.0", + "url": "https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/.js/plugins/turkish/WebNovelOku[madara].js", + "iconUrl": "https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/icons/multisrc/madara/icons/webnoveloku.png" + } + ], + "Tiếng Việt": [ + { + "id": "ln.hako", + "name": "Hako", + "site": "https://ln.hako.vn", + "lang": "Tiếng Việt", + "version": "1.0.0", + "url": "https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/.js/plugins/vietnamese/LNHako.js", + "iconUrl": "https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/icons/src/vi/hakolightnovel/icon.png" + } + ] +} \ No newline at end of file diff --git a/.dist/k1ngfish3r/plugins.min.json b/.dist/k1ngfish3r/plugins.min.json new file mode 100644 index 0000000..d8959db --- /dev/null +++ b/.dist/k1ngfish3r/plugins.min.json @@ -0,0 +1 @@ +{"العربية":[{"id":"ar-mtl","name":"ArMTL[madara]","site":"https://ar-mtl.club/","lang":"العربية","version":"1.0.0","url":"https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/.js/plugins/arabic/ArMTL[madara].js","iconUrl":"https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/icons/multisrc/madara/icons/armtl.png"},{"id":"arnovel","name":"ArNovel[madara]","site":"https://arnovel.me/","lang":"العربية","version":"1.0.0","url":"https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/.js/plugins/arabic/ArNovel[madara].js","iconUrl":"https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/icons/multisrc/madara/icons/arnovel.png"},{"id":"hizomanga","name":"HizoManga[madara]","site":"https://hizomanga.com/","lang":"العربية","version":"1.0.0","url":"https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/.js/plugins/arabic/HizoManga[madara].js","iconUrl":"https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/icons/multisrc/madara/icons/hizomanga.png"},{"id":"kolnovel","name":"KolNovel","site":"https://kolnovel.lol/","lang":"العربية","version":"1.0.0","url":"https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/.js/plugins/arabic/kolnovel.js","iconUrl":"https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/icons/multisrc/wpmangastream/icons/kolnovel.png"},{"id":"novel4up","name":"Novel4Up[madara]","site":"https://novel4up.com/","lang":"العربية","version":"1.0.0","url":"https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/.js/plugins/arabic/Novel4Up[madara].js","iconUrl":"https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/icons/multisrc/madara/icons/novel4up.png"},{"id":"riwyat","name":"Riwyat[madara]","site":"https://riwyat.com/","lang":"العربية","version":"1.0.0","url":"https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/.js/plugins/arabic/Riwyat[madara].js","iconUrl":"https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/icons/multisrc/madara/icons/riwyat.png"},{"id":"teamxnovel","name":"TeamXNovel[madara]","site":"https://teamxnovel.com/","lang":"العربية","version":"1.0.0","url":"https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/.js/plugins/arabic/TeamXNovel[madara].js","iconUrl":"https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/icons/multisrc/madara/icons/teamxnovel.png"}],"中文, 汉语, 漢語":[{"id":"linovelib","name":"Linovelib","site":"https://w.linovelib.com","lang":"中文, 汉语, 漢語","version":"1.0.0","url":"https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/.js/plugins/chinese/linovelib.js","iconUrl":"https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/icons/src/cn/linovelib/icon.png"}],"English":[{"id":"1stkissnovel","name":"FirstKissNovel[madara]","site":"https://1stkissnovel.org/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/.js/plugins/english/FirstKissNovel[madara].js","iconUrl":"https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/icons/multisrc/madara/icons/firstkissnovel.png"},{"id":"BLN.com","name":"BestLightNovel","site":"https://bestlightnovel.com/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/.js/plugins/english/bestlightnovel.js","iconUrl":"https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/icons/src/en/bestlightnovel/icon.png"},{"id":"boxnovel","name":"BoxNovel[madara]","site":"https://boxnovel.com/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/.js/plugins/english/BoxNovel[madara].js","iconUrl":"https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/icons/multisrc/madara/icons/boxnovel.png"},{"id":"clicknovel","name":"ClickNovel[madara]","site":"https://clicknovel.net/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/.js/plugins/english/ClickNovel[madara].js","iconUrl":"https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/icons/multisrc/madara/icons/clicknovel.png"},{"id":"cratenovel","name":"CrateNovel[madara]","site":"https://cratenovel.com/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/.js/plugins/english/CrateNovel[madara].js","iconUrl":"https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/icons/multisrc/madara/icons/cratenovel.png"},{"id":"daonovel","name":"DaoNovel[madara]","site":"https://daonovel.com/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/.js/plugins/english/DaoNovel[madara].js","iconUrl":"https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/icons/multisrc/madara/icons/daonovel.png"},{"id":"fanTLS","name":"Fans Translations[madara]","site":"https://fanstranslations.com/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/.js/plugins/english/FansTranslations[madara].js","iconUrl":"https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/icons/multisrc/madara/icons/fanstranslations.png"},{"id":"freenovel.me","name":"FreeNovelMe[madara]","site":"https://freenovel.me/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/.js/plugins/english/FreeNovelMe[madara].js","iconUrl":"https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/icons/multisrc/madara/icons/freenovelme.png"},{"id":"guavaread","name":"Guavaread[madara]","site":"https://guavaread.com/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/.js/plugins/english/Guavaread[madara].js","iconUrl":"https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/icons/multisrc/madara/icons/guavaread.png"},{"id":"lnheaven","name":"LightNovelHeaven[madara]","site":"https://lightnovelheaven.com/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/.js/plugins/english/LightNovelHeaven[madara].js","iconUrl":"https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/icons/multisrc/madara/icons/lightnovelheaven.png"},{"id":"lunarletters","name":"LunarLetters[madara]","site":"https://www.lunarletters.com/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/.js/plugins/english/LunarLetters[madara].js","iconUrl":"https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/icons/multisrc/madara/icons/lunarletters.png"},{"id":"mostnovel","name":"MostNovel[madara]","site":"https://mostnovel.com/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/.js/plugins/english/MostNovel[madara].js","iconUrl":"https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/icons/multisrc/madara/icons/mostnovel.png"},{"id":"mtl-novel","name":"MTL-Novel[madara]","site":"https://mtl-novel.com/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/.js/plugins/english/MTLNovel[madara].js","iconUrl":"https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/icons/multisrc/madara/icons/mtl-novel.png"},{"id":"mtlnovel.club","name":"MTLNovel.Club[madara]","site":"https://mtlnovel.club/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/.js/plugins/english/MTLNovelClub[madara].js","iconUrl":"https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/icons/multisrc/madara/icons/mtlnovel.club.png"},{"id":"mysticalmerries","name":"MysticalSeries[madara]","site":"https://mysticalmerries.com/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/.js/plugins/english/MysticalSeries[madara].js","iconUrl":"https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/icons/multisrc/madara/icons/mysticalseries.png"},{"id":"neosekaiTLS","name":"NeoSekai Translations[madara]","site":"https://www.neosekaitranslations.com/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/.js/plugins/english/NeoSekaiTranslations[madara].js","iconUrl":"https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/icons/multisrc/madara/icons/neosekaitranslations.png"},{"id":"noblemtl","name":"NobleMTL","site":"https://noblemtl.com/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/.js/plugins/english/nobleMTL.js","iconUrl":"https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/icons/src/en/noblemtl/icon.png"},{"id":"nocturneTLS","name":"Nocturne Translations[madara]","site":"https://nocturnetls.net/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/.js/plugins/english/NocturneTranslations[madara].js","iconUrl":"https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/icons/multisrc/madara/icons/nocturnetranslations.png"},{"id":"noobchanTL","name":"Noobchan Translation[madara]","site":"https://noobchan.xyz/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/.js/plugins/english/NoobchanTranslation[madara].js","iconUrl":"https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/icons/multisrc/madara/icons/noobchantranslation.png"},{"id":"novelmultiverse","name":"NovelMultiverse[madara]","site":"https://www.novelmultiverse.com/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/.js/plugins/english/NovelMultiverse[madara].js","iconUrl":"https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/icons/multisrc/madara/icons/novelmultiverse.png"},{"id":"novelr18","name":"NovelR18[madara]","site":"https://novelr18.com/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/.js/plugins/english/NovelR18[madara].js","iconUrl":"https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/icons/multisrc/madara/icons/novelr18.png"},{"id":"novelroom","name":"Novelroom.net[madara]","site":"https://novelroom.net/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/.js/plugins/english/Novelroomnet[madara].js","iconUrl":"https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/icons/multisrc/madara/icons/novelroom.net.png"},{"id":"novelstic","name":"Novelstic[madara]","site":"https://novelstic.com/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/.js/plugins/english/Novelstic[madara].js","iconUrl":"https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/icons/multisrc/madara/icons/novelstic.png"},{"id":"novelTL","name":"NovelTranslate[madara]","site":"https://noveltranslate.com/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/.js/plugins/english/NovelTranslate[madara].js","iconUrl":"https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/icons/multisrc/madara/icons/noveltranslate.png"},{"id":"onlymtl","name":"OnlyMTL[madara]","site":"https://www.onlymtl.com/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/.js/plugins/english/OnlyMTL[madara].js","iconUrl":"https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/icons/multisrc/madara/icons/onlymtl.png"},{"id":"pandamtl","name":"PandaMTL","site":"https://pandamtl.com/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/.js/plugins/english/pandaMTL.js","iconUrl":"https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/icons/src/en/wordpress/icon.png"},{"id":"readwebnovels","name":"ReadWebNovels[madara]","site":"https://readwebnovels.net/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/.js/plugins/english/ReadWebNovels[madara].js","iconUrl":"https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/icons/multisrc/madara/icons/readwebnovels.png"},{"id":"sleeptTLS","name":"SleepyTranslations[madara]","site":"https://sleepytranslations.com/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/.js/plugins/english/SleepyTranslations[madara].js","iconUrl":"https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/icons/multisrc/madara/icons/sleepytranslations.png"},{"id":"sonicmtl","name":"SonicMTL[madara]","site":"https://www.sonicmtl.com/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/.js/plugins/english/SonicMTL[madara].js","iconUrl":"https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/icons/multisrc/madara/icons/sonicmtl.png"},{"id":"sugarbbscan","name":"Sugar Babies[madara]","site":"https://sugarbbscan.com/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/.js/plugins/english/SugarBabies[madara].js","iconUrl":"https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/icons/multisrc/madara/icons/sugarbabies.png"},{"id":"sweetEscapeTL","name":"Sweet Escape Translations[madara]","site":"https://sweetescapetranslations.com/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/.js/plugins/english/SweetEscapeTranslations[madara].js","iconUrl":"https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/icons/multisrc/madara/icons/sweetescapetranslations.png"},{"id":"webnovelover","name":"WebNovelLover[madara]","site":"https://www.webnovelover.com/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/.js/plugins/english/WebNovelLover[madara].js","iconUrl":"https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/icons/multisrc/madara/icons/webnovellover.png"},{"id":"wuxiaworld.site","name":"WuxiaWorld.Site[madara]","site":"https://wuxiaworld.site/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/.js/plugins/english/WuxiaWorldSite[madara].js","iconUrl":"https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/icons/multisrc/madara/icons/wuxiaworld.site.png"},{"id":"zetroTL","name":"Zetro Translation[madara]","site":"https://zetrotranslation.com/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/.js/plugins/english/ZetroTranslation[madara].js","iconUrl":"https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/icons/multisrc/madara/icons/zetrotranslation.png"},{"id":"zinnovel","name":"ZinnNovel[madara]","site":"https://zinnovel.com/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/.js/plugins/english/ZinnNovel[madara].js","iconUrl":"https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/icons/multisrc/madara/icons/zinnnovel.png"}],"Bahasa Indonesia":[{"id":"meionovel","name":"MeioNovel[madara]","site":"https://meionovel.id/","lang":"Bahasa Indonesia","version":"1.0.0","url":"https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/.js/plugins/indonesian/MeioNovel[madara].js","iconUrl":"https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/icons/multisrc/madara/icons/meionovel.png"},{"id":"morenovel","name":"MoreNovel[madara]","site":"https://morenovel.net/","lang":"Bahasa Indonesia","version":"1.0.0","url":"https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/.js/plugins/indonesian/MoreNovel[madara].js","iconUrl":"https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/icons/multisrc/madara/icons/morenovel.png"},{"id":"wbnovel","name":"WBNovel[madara]","site":"https://wbnovel.com/","lang":"Bahasa Indonesia","version":"1.0.0","url":"https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/.js/plugins/indonesian/WBNovel[madara].js","iconUrl":"https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/icons/multisrc/madara/icons/wbnovel.png"}],"Português":[{"id":"lightnovelbrasil","name":"Light Novel Brasil","site":"https://lightnovelbrasil.com/","lang":"Português","version":"1.0.0","url":"https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/.js/plugins/portuguese/lightnovelbrasil.js","iconUrl":"https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/icons/multisrc/wpmangastream/icons/lightnovelbrasil.png"}],"español, castellano":[{"id":"tunovelaligera","name":"TuNovelaLigera","site":"https://tunovelaligera.com/","lang":"español, castellano","version":"1.0.0","url":"https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/.js/plugins/spanish/tunovelaligera.js","iconUrl":"https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/icons/src/es/tunovelaligera/icon.png"}],"Türkçe":[{"id":"lshnovel","name":"Liebe Schnee Hiver Novel","site":"https://lshnovel.com/","lang":"Türkçe","version":"1.0.0","url":"https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/.js/plugins/turkish/lshnovel.js","iconUrl":"https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/icons/multisrc/wpmangastream/icons/lshnovel.png"},{"id":"turkcelightnovels","name":"TurkceLightNovels[madara]","site":"https://turkcelightnovels.com/","lang":"Türkçe","version":"1.0.0","url":"https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/.js/plugins/turkish/TurkceLightNovels[madara].js","iconUrl":"https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/icons/multisrc/madara/icons/turkcelightnovels.png"},{"id":"webnoveloku","name":"WebNovelOku [madara]","site":"https://www.webnoveloku.com/","lang":"Türkçe","version":"1.0.0","url":"https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/.js/plugins/turkish/WebNovelOku[madara].js","iconUrl":"https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/icons/multisrc/madara/icons/webnoveloku.png"}],"Tiếng Việt":[{"id":"ln.hako","name":"Hako","site":"https://ln.hako.vn","lang":"Tiếng Việt","version":"1.0.0","url":"https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/.js/plugins/vietnamese/LNHako.js","iconUrl":"https://raw.githubusercontent.com/k1ngfish3r/plugins/classes/icons/src/vi/hakolightnovel/icon.png"}]} \ No newline at end of file diff --git a/.dist/nyagami/plugins.json b/.dist/nyagami/plugins.json new file mode 100644 index 0000000..16c821d --- /dev/null +++ b/.dist/nyagami/plugins.json @@ -0,0 +1,464 @@ +{ + "العربية": [ + { + "id": "ar-mtl", + "name": "ArMTL[madara]", + "site": "https://ar-mtl.club/", + "lang": "العربية", + "version": "1.0.0", + "url": "https://raw.githubusercontent.com/nyagami/plugins/classes/.js/plugins/arabic/ArMTL[madara].js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/classes/icons/multisrc/madara/icons/armtl.png" + }, + { + "id": "arnovel", + "name": "ArNovel[madara]", + "site": "https://arnovel.me/", + "lang": "العربية", + "version": "1.0.0", + "url": "https://raw.githubusercontent.com/nyagami/plugins/classes/.js/plugins/arabic/ArNovel[madara].js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/classes/icons/multisrc/madara/icons/arnovel.png" + }, + { + "id": "hizomanga", + "name": "HizoManga[madara]", + "site": "https://hizomanga.com/", + "lang": "العربية", + "version": "1.0.0", + "url": "https://raw.githubusercontent.com/nyagami/plugins/classes/.js/plugins/arabic/HizoManga[madara].js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/classes/icons/multisrc/madara/icons/hizomanga.png" + }, + { + "id": "kolnovel", + "name": "KolNovel", + "site": "https://kolnovel.lol/", + "lang": "العربية", + "version": "1.0.0", + "url": "https://raw.githubusercontent.com/nyagami/plugins/classes/.js/plugins/arabic/kolnovel.js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/classes/icons/multisrc/wpmangastream/icons/kolnovel.png" + }, + { + "id": "novel4up", + "name": "Novel4Up[madara]", + "site": "https://novel4up.com/", + "lang": "العربية", + "version": "1.0.0", + "url": "https://raw.githubusercontent.com/nyagami/plugins/classes/.js/plugins/arabic/Novel4Up[madara].js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/classes/icons/multisrc/madara/icons/novel4up.png" + }, + { + "id": "riwyat", + "name": "Riwyat[madara]", + "site": "https://riwyat.com/", + "lang": "العربية", + "version": "1.0.0", + "url": "https://raw.githubusercontent.com/nyagami/plugins/classes/.js/plugins/arabic/Riwyat[madara].js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/classes/icons/multisrc/madara/icons/riwyat.png" + }, + { + "id": "teamxnovel", + "name": "TeamXNovel[madara]", + "site": "https://teamxnovel.com/", + "lang": "العربية", + "version": "1.0.0", + "url": "https://raw.githubusercontent.com/nyagami/plugins/classes/.js/plugins/arabic/TeamXNovel[madara].js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/classes/icons/multisrc/madara/icons/teamxnovel.png" + } + ], + "English": [ + { + "id": "1stkissnovel", + "name": "FirstKissNovel[madara]", + "site": "https://1stkissnovel.org/", + "lang": "English", + "version": "1.0.0", + "url": "https://raw.githubusercontent.com/nyagami/plugins/classes/.js/plugins/english/FirstKissNovel[madara].js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/classes/icons/multisrc/madara/icons/firstkissnovel.png" + }, + { + "id": "BLN.com", + "name": "BestLightNovel", + "site": "https://bestlightnovel.com/", + "lang": "English", + "version": "1.0.0", + "url": "https://raw.githubusercontent.com/nyagami/plugins/classes/.js/plugins/english/bestlightnovel.js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/classes/icons/src/en/bestlightnovel/icon.png" + }, + { + "id": "boxnovel", + "name": "BoxNovel[madara]", + "site": "https://boxnovel.com/", + "lang": "English", + "version": "1.0.0", + "url": "https://raw.githubusercontent.com/nyagami/plugins/classes/.js/plugins/english/BoxNovel[madara].js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/classes/icons/multisrc/madara/icons/boxnovel.png" + }, + { + "id": "clicknovel", + "name": "ClickNovel[madara]", + "site": "https://clicknovel.net/", + "lang": "English", + "version": "1.0.0", + "url": "https://raw.githubusercontent.com/nyagami/plugins/classes/.js/plugins/english/ClickNovel[madara].js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/classes/icons/multisrc/madara/icons/clicknovel.png" + }, + { + "id": "cratenovel", + "name": "CrateNovel[madara]", + "site": "https://cratenovel.com/", + "lang": "English", + "version": "1.0.0", + "url": "https://raw.githubusercontent.com/nyagami/plugins/classes/.js/plugins/english/CrateNovel[madara].js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/classes/icons/multisrc/madara/icons/cratenovel.png" + }, + { + "id": "daonovel", + "name": "DaoNovel[madara]", + "site": "https://daonovel.com/", + "lang": "English", + "version": "1.0.0", + "url": "https://raw.githubusercontent.com/nyagami/plugins/classes/.js/plugins/english/DaoNovel[madara].js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/classes/icons/multisrc/madara/icons/daonovel.png" + }, + { + "id": "fanTLS", + "name": "Fans Translations[madara]", + "site": "https://fanstranslations.com/", + "lang": "English", + "version": "1.0.0", + "url": "https://raw.githubusercontent.com/nyagami/plugins/classes/.js/plugins/english/FansTranslations[madara].js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/classes/icons/multisrc/madara/icons/fanstranslations.png" + }, + { + "id": "freenovel.me", + "name": "FreeNovelMe[madara]", + "site": "https://freenovel.me/", + "lang": "English", + "version": "1.0.0", + "url": "https://raw.githubusercontent.com/nyagami/plugins/classes/.js/plugins/english/FreeNovelMe[madara].js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/classes/icons/multisrc/madara/icons/freenovelme.png" + }, + { + "id": "guavaread", + "name": "Guavaread[madara]", + "site": "https://guavaread.com/", + "lang": "English", + "version": "1.0.0", + "url": "https://raw.githubusercontent.com/nyagami/plugins/classes/.js/plugins/english/Guavaread[madara].js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/classes/icons/multisrc/madara/icons/guavaread.png" + }, + { + "id": "lnheaven", + "name": "LightNovelHeaven[madara]", + "site": "https://lightnovelheaven.com/", + "lang": "English", + "version": "1.0.0", + "url": "https://raw.githubusercontent.com/nyagami/plugins/classes/.js/plugins/english/LightNovelHeaven[madara].js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/classes/icons/multisrc/madara/icons/lightnovelheaven.png" + }, + { + "id": "lunarletters", + "name": "LunarLetters[madara]", + "site": "https://www.lunarletters.com/", + "lang": "English", + "version": "1.0.0", + "url": "https://raw.githubusercontent.com/nyagami/plugins/classes/.js/plugins/english/LunarLetters[madara].js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/classes/icons/multisrc/madara/icons/lunarletters.png" + }, + { + "id": "mostnovel", + "name": "MostNovel[madara]", + "site": "https://mostnovel.com/", + "lang": "English", + "version": "1.0.0", + "url": "https://raw.githubusercontent.com/nyagami/plugins/classes/.js/plugins/english/MostNovel[madara].js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/classes/icons/multisrc/madara/icons/mostnovel.png" + }, + { + "id": "mtl-novel", + "name": "MTL-Novel[madara]", + "site": "https://mtl-novel.com/", + "lang": "English", + "version": "1.0.0", + "url": "https://raw.githubusercontent.com/nyagami/plugins/classes/.js/plugins/english/MTLNovel[madara].js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/classes/icons/multisrc/madara/icons/mtl-novel.png" + }, + { + "id": "mtlnovel.club", + "name": "MTLNovel.Club[madara]", + "site": "https://mtlnovel.club/", + "lang": "English", + "version": "1.0.0", + "url": "https://raw.githubusercontent.com/nyagami/plugins/classes/.js/plugins/english/MTLNovelClub[madara].js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/classes/icons/multisrc/madara/icons/mtlnovel.club.png" + }, + { + "id": "mysticalmerries", + "name": "MysticalSeries[madara]", + "site": "https://mysticalmerries.com/", + "lang": "English", + "version": "1.0.0", + "url": "https://raw.githubusercontent.com/nyagami/plugins/classes/.js/plugins/english/MysticalSeries[madara].js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/classes/icons/multisrc/madara/icons/mysticalseries.png" + }, + { + "id": "neosekaiTLS", + "name": "NeoSekai Translations[madara]", + "site": "https://www.neosekaitranslations.com/", + "lang": "English", + "version": "1.0.0", + "url": "https://raw.githubusercontent.com/nyagami/plugins/classes/.js/plugins/english/NeoSekaiTranslations[madara].js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/classes/icons/multisrc/madara/icons/neosekaitranslations.png" + }, + { + "id": "noblemtl", + "name": "NobleMTL", + "site": "https://noblemtl.com/", + "lang": "English", + "version": "1.0.0", + "url": "https://raw.githubusercontent.com/nyagami/plugins/classes/.js/plugins/english/nobleMTL.js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/classes/icons/src/en/noblemtl/icon.png" + }, + { + "id": "nocturneTLS", + "name": "Nocturne Translations[madara]", + "site": "https://nocturnetls.net/", + "lang": "English", + "version": "1.0.0", + "url": "https://raw.githubusercontent.com/nyagami/plugins/classes/.js/plugins/english/NocturneTranslations[madara].js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/classes/icons/multisrc/madara/icons/nocturnetranslations.png" + }, + { + "id": "noobchanTL", + "name": "Noobchan Translation[madara]", + "site": "https://noobchan.xyz/", + "lang": "English", + "version": "1.0.0", + "url": "https://raw.githubusercontent.com/nyagami/plugins/classes/.js/plugins/english/NoobchanTranslation[madara].js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/classes/icons/multisrc/madara/icons/noobchantranslation.png" + }, + { + "id": "novelmultiverse", + "name": "NovelMultiverse[madara]", + "site": "https://www.novelmultiverse.com/", + "lang": "English", + "version": "1.0.0", + "url": "https://raw.githubusercontent.com/nyagami/plugins/classes/.js/plugins/english/NovelMultiverse[madara].js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/classes/icons/multisrc/madara/icons/novelmultiverse.png" + }, + { + "id": "novelr18", + "name": "NovelR18[madara]", + "site": "https://novelr18.com/", + "lang": "English", + "version": "1.0.0", + "url": "https://raw.githubusercontent.com/nyagami/plugins/classes/.js/plugins/english/NovelR18[madara].js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/classes/icons/multisrc/madara/icons/novelr18.png" + }, + { + "id": "novelroom", + "name": "Novelroom.net[madara]", + "site": "https://novelroom.net/", + "lang": "English", + "version": "1.0.0", + "url": "https://raw.githubusercontent.com/nyagami/plugins/classes/.js/plugins/english/Novelroomnet[madara].js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/classes/icons/multisrc/madara/icons/novelroom.net.png" + }, + { + "id": "novelstic", + "name": "Novelstic[madara]", + "site": "https://novelstic.com/", + "lang": "English", + "version": "1.0.0", + "url": "https://raw.githubusercontent.com/nyagami/plugins/classes/.js/plugins/english/Novelstic[madara].js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/classes/icons/multisrc/madara/icons/novelstic.png" + }, + { + "id": "novelTL", + "name": "NovelTranslate[madara]", + "site": "https://noveltranslate.com/", + "lang": "English", + "version": "1.0.0", + "url": "https://raw.githubusercontent.com/nyagami/plugins/classes/.js/plugins/english/NovelTranslate[madara].js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/classes/icons/multisrc/madara/icons/noveltranslate.png" + }, + { + "id": "onlymtl", + "name": "OnlyMTL[madara]", + "site": "https://www.onlymtl.com/", + "lang": "English", + "version": "1.0.0", + "url": "https://raw.githubusercontent.com/nyagami/plugins/classes/.js/plugins/english/OnlyMTL[madara].js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/classes/icons/multisrc/madara/icons/onlymtl.png" + }, + { + "id": "pandamtl", + "name": "PandaMTL", + "site": "https://pandamtl.com/", + "lang": "English", + "version": "1.0.0", + "url": "https://raw.githubusercontent.com/nyagami/plugins/classes/.js/plugins/english/pandaMTL.js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/classes/icons/src/en/wordpress/icon.png" + }, + { + "id": "readwebnovels", + "name": "ReadWebNovels[madara]", + "site": "https://readwebnovels.net/", + "lang": "English", + "version": "1.0.0", + "url": "https://raw.githubusercontent.com/nyagami/plugins/classes/.js/plugins/english/ReadWebNovels[madara].js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/classes/icons/multisrc/madara/icons/readwebnovels.png" + }, + { + "id": "sleeptTLS", + "name": "SleepyTranslations[madara]", + "site": "https://sleepytranslations.com/", + "lang": "English", + "version": "1.0.0", + "url": "https://raw.githubusercontent.com/nyagami/plugins/classes/.js/plugins/english/SleepyTranslations[madara].js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/classes/icons/multisrc/madara/icons/sleepytranslations.png" + }, + { + "id": "sonicmtl", + "name": "SonicMTL[madara]", + "site": "https://www.sonicmtl.com/", + "lang": "English", + "version": "1.0.0", + "url": "https://raw.githubusercontent.com/nyagami/plugins/classes/.js/plugins/english/SonicMTL[madara].js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/classes/icons/multisrc/madara/icons/sonicmtl.png" + }, + { + "id": "sugarbbscan", + "name": "Sugar Babies[madara]", + "site": "https://sugarbbscan.com/", + "lang": "English", + "version": "1.0.0", + "url": "https://raw.githubusercontent.com/nyagami/plugins/classes/.js/plugins/english/SugarBabies[madara].js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/classes/icons/multisrc/madara/icons/sugarbabies.png" + }, + { + "id": "sweetEscapeTL", + "name": "Sweet Escape Translations[madara]", + "site": "https://sweetescapetranslations.com/", + "lang": "English", + "version": "1.0.0", + "url": "https://raw.githubusercontent.com/nyagami/plugins/classes/.js/plugins/english/SweetEscapeTranslations[madara].js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/classes/icons/multisrc/madara/icons/sweetescapetranslations.png" + }, + { + "id": "webnovelover", + "name": "WebNovelLover[madara]", + "site": "https://www.webnovelover.com/", + "lang": "English", + "version": "1.0.0", + "url": "https://raw.githubusercontent.com/nyagami/plugins/classes/.js/plugins/english/WebNovelLover[madara].js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/classes/icons/multisrc/madara/icons/webnovellover.png" + }, + { + "id": "wuxiaworld.site", + "name": "WuxiaWorld.Site[madara]", + "site": "https://wuxiaworld.site/", + "lang": "English", + "version": "1.0.0", + "url": "https://raw.githubusercontent.com/nyagami/plugins/classes/.js/plugins/english/WuxiaWorldSite[madara].js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/classes/icons/multisrc/madara/icons/wuxiaworld.site.png" + }, + { + "id": "zetroTL", + "name": "Zetro Translation[madara]", + "site": "https://zetrotranslation.com/", + "lang": "English", + "version": "1.0.0", + "url": "https://raw.githubusercontent.com/nyagami/plugins/classes/.js/plugins/english/ZetroTranslation[madara].js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/classes/icons/multisrc/madara/icons/zetrotranslation.png" + }, + { + "id": "zinnovel", + "name": "ZinnNovel[madara]", + "site": "https://zinnovel.com/", + "lang": "English", + "version": "1.0.0", + "url": "https://raw.githubusercontent.com/nyagami/plugins/classes/.js/plugins/english/ZinnNovel[madara].js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/classes/icons/multisrc/madara/icons/zinnnovel.png" + } + ], + "Bahasa Indonesia": [ + { + "id": "meionovel", + "name": "MeioNovel[madara]", + "site": "https://meionovel.id/", + "lang": "Bahasa Indonesia", + "version": "1.0.0", + "url": "https://raw.githubusercontent.com/nyagami/plugins/classes/.js/plugins/indonesian/MeioNovel[madara].js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/classes/icons/multisrc/madara/icons/meionovel.png" + }, + { + "id": "morenovel", + "name": "MoreNovel[madara]", + "site": "https://morenovel.net/", + "lang": "Bahasa Indonesia", + "version": "1.0.0", + "url": "https://raw.githubusercontent.com/nyagami/plugins/classes/.js/plugins/indonesian/MoreNovel[madara].js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/classes/icons/multisrc/madara/icons/morenovel.png" + }, + { + "id": "wbnovel", + "name": "WBNovel[madara]", + "site": "https://wbnovel.com/", + "lang": "Bahasa Indonesia", + "version": "1.0.0", + "url": "https://raw.githubusercontent.com/nyagami/plugins/classes/.js/plugins/indonesian/WBNovel[madara].js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/classes/icons/multisrc/madara/icons/wbnovel.png" + } + ], + "Português": [ + { + "id": "lightnovelbrasil", + "name": "Light Novel Brasil", + "site": "https://lightnovelbrasil.com/", + "lang": "Português", + "version": "1.0.0", + "url": "https://raw.githubusercontent.com/nyagami/plugins/classes/.js/plugins/portuguese/lightnovelbrasil.js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/classes/icons/multisrc/wpmangastream/icons/lightnovelbrasil.png" + } + ], + "Türkçe": [ + { + "id": "lshnovel", + "name": "Liebe Schnee Hiver Novel", + "site": "https://lshnovel.com/", + "lang": "Türkçe", + "version": "1.0.0", + "url": "https://raw.githubusercontent.com/nyagami/plugins/classes/.js/plugins/turkish/lshnovel.js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/classes/icons/multisrc/wpmangastream/icons/lshnovel.png" + }, + { + "id": "turkcelightnovels", + "name": "TurkceLightNovels[madara]", + "site": "https://turkcelightnovels.com/", + "lang": "Türkçe", + "version": "1.0.0", + "url": "https://raw.githubusercontent.com/nyagami/plugins/classes/.js/plugins/turkish/TurkceLightNovels[madara].js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/classes/icons/multisrc/madara/icons/turkcelightnovels.png" + }, + { + "id": "webnoveloku", + "name": "WebNovelOku [madara]", + "site": "https://www.webnoveloku.com/", + "lang": "Türkçe", + "version": "1.0.0", + "url": "https://raw.githubusercontent.com/nyagami/plugins/classes/.js/plugins/turkish/WebNovelOku[madara].js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/classes/icons/multisrc/madara/icons/webnoveloku.png" + } + ], + "Tiếng Việt": [ + { + "id": "ln.hako", + "name": "Hako", + "site": "https://ln.hako.vn", + "lang": "Tiếng Việt", + "version": "1.0.0", + "url": "https://raw.githubusercontent.com/nyagami/plugins/classes/.js/plugins/vietnamese/LNHako.js", + "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/classes/icons/src/vi/hakolightnovel/icon.png" + } + ] +} \ No newline at end of file diff --git a/.dist/nyagami/plugins.min.json b/.dist/nyagami/plugins.min.json new file mode 100644 index 0000000..526e5f3 --- /dev/null +++ b/.dist/nyagami/plugins.min.json @@ -0,0 +1 @@ +{"العربية":[{"id":"ar-mtl","name":"ArMTL[madara]","site":"https://ar-mtl.club/","lang":"العربية","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/classes/.js/plugins/arabic/ArMTL[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/classes/icons/multisrc/madara/icons/armtl.png"},{"id":"arnovel","name":"ArNovel[madara]","site":"https://arnovel.me/","lang":"العربية","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/classes/.js/plugins/arabic/ArNovel[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/classes/icons/multisrc/madara/icons/arnovel.png"},{"id":"hizomanga","name":"HizoManga[madara]","site":"https://hizomanga.com/","lang":"العربية","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/classes/.js/plugins/arabic/HizoManga[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/classes/icons/multisrc/madara/icons/hizomanga.png"},{"id":"kolnovel","name":"KolNovel","site":"https://kolnovel.lol/","lang":"العربية","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/classes/.js/plugins/arabic/kolnovel.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/classes/icons/multisrc/wpmangastream/icons/kolnovel.png"},{"id":"novel4up","name":"Novel4Up[madara]","site":"https://novel4up.com/","lang":"العربية","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/classes/.js/plugins/arabic/Novel4Up[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/classes/icons/multisrc/madara/icons/novel4up.png"},{"id":"riwyat","name":"Riwyat[madara]","site":"https://riwyat.com/","lang":"العربية","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/classes/.js/plugins/arabic/Riwyat[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/classes/icons/multisrc/madara/icons/riwyat.png"},{"id":"teamxnovel","name":"TeamXNovel[madara]","site":"https://teamxnovel.com/","lang":"العربية","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/classes/.js/plugins/arabic/TeamXNovel[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/classes/icons/multisrc/madara/icons/teamxnovel.png"}],"English":[{"id":"1stkissnovel","name":"FirstKissNovel[madara]","site":"https://1stkissnovel.org/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/classes/.js/plugins/english/FirstKissNovel[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/classes/icons/multisrc/madara/icons/firstkissnovel.png"},{"id":"BLN.com","name":"BestLightNovel","site":"https://bestlightnovel.com/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/classes/.js/plugins/english/bestlightnovel.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/classes/icons/src/en/bestlightnovel/icon.png"},{"id":"boxnovel","name":"BoxNovel[madara]","site":"https://boxnovel.com/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/classes/.js/plugins/english/BoxNovel[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/classes/icons/multisrc/madara/icons/boxnovel.png"},{"id":"clicknovel","name":"ClickNovel[madara]","site":"https://clicknovel.net/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/classes/.js/plugins/english/ClickNovel[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/classes/icons/multisrc/madara/icons/clicknovel.png"},{"id":"cratenovel","name":"CrateNovel[madara]","site":"https://cratenovel.com/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/classes/.js/plugins/english/CrateNovel[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/classes/icons/multisrc/madara/icons/cratenovel.png"},{"id":"daonovel","name":"DaoNovel[madara]","site":"https://daonovel.com/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/classes/.js/plugins/english/DaoNovel[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/classes/icons/multisrc/madara/icons/daonovel.png"},{"id":"fanTLS","name":"Fans Translations[madara]","site":"https://fanstranslations.com/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/classes/.js/plugins/english/FansTranslations[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/classes/icons/multisrc/madara/icons/fanstranslations.png"},{"id":"freenovel.me","name":"FreeNovelMe[madara]","site":"https://freenovel.me/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/classes/.js/plugins/english/FreeNovelMe[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/classes/icons/multisrc/madara/icons/freenovelme.png"},{"id":"guavaread","name":"Guavaread[madara]","site":"https://guavaread.com/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/classes/.js/plugins/english/Guavaread[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/classes/icons/multisrc/madara/icons/guavaread.png"},{"id":"lnheaven","name":"LightNovelHeaven[madara]","site":"https://lightnovelheaven.com/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/classes/.js/plugins/english/LightNovelHeaven[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/classes/icons/multisrc/madara/icons/lightnovelheaven.png"},{"id":"lunarletters","name":"LunarLetters[madara]","site":"https://www.lunarletters.com/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/classes/.js/plugins/english/LunarLetters[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/classes/icons/multisrc/madara/icons/lunarletters.png"},{"id":"mostnovel","name":"MostNovel[madara]","site":"https://mostnovel.com/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/classes/.js/plugins/english/MostNovel[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/classes/icons/multisrc/madara/icons/mostnovel.png"},{"id":"mtl-novel","name":"MTL-Novel[madara]","site":"https://mtl-novel.com/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/classes/.js/plugins/english/MTLNovel[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/classes/icons/multisrc/madara/icons/mtl-novel.png"},{"id":"mtlnovel.club","name":"MTLNovel.Club[madara]","site":"https://mtlnovel.club/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/classes/.js/plugins/english/MTLNovelClub[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/classes/icons/multisrc/madara/icons/mtlnovel.club.png"},{"id":"mysticalmerries","name":"MysticalSeries[madara]","site":"https://mysticalmerries.com/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/classes/.js/plugins/english/MysticalSeries[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/classes/icons/multisrc/madara/icons/mysticalseries.png"},{"id":"neosekaiTLS","name":"NeoSekai Translations[madara]","site":"https://www.neosekaitranslations.com/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/classes/.js/plugins/english/NeoSekaiTranslations[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/classes/icons/multisrc/madara/icons/neosekaitranslations.png"},{"id":"noblemtl","name":"NobleMTL","site":"https://noblemtl.com/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/classes/.js/plugins/english/nobleMTL.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/classes/icons/src/en/noblemtl/icon.png"},{"id":"nocturneTLS","name":"Nocturne Translations[madara]","site":"https://nocturnetls.net/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/classes/.js/plugins/english/NocturneTranslations[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/classes/icons/multisrc/madara/icons/nocturnetranslations.png"},{"id":"noobchanTL","name":"Noobchan Translation[madara]","site":"https://noobchan.xyz/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/classes/.js/plugins/english/NoobchanTranslation[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/classes/icons/multisrc/madara/icons/noobchantranslation.png"},{"id":"novelmultiverse","name":"NovelMultiverse[madara]","site":"https://www.novelmultiverse.com/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/classes/.js/plugins/english/NovelMultiverse[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/classes/icons/multisrc/madara/icons/novelmultiverse.png"},{"id":"novelr18","name":"NovelR18[madara]","site":"https://novelr18.com/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/classes/.js/plugins/english/NovelR18[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/classes/icons/multisrc/madara/icons/novelr18.png"},{"id":"novelroom","name":"Novelroom.net[madara]","site":"https://novelroom.net/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/classes/.js/plugins/english/Novelroomnet[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/classes/icons/multisrc/madara/icons/novelroom.net.png"},{"id":"novelstic","name":"Novelstic[madara]","site":"https://novelstic.com/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/classes/.js/plugins/english/Novelstic[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/classes/icons/multisrc/madara/icons/novelstic.png"},{"id":"novelTL","name":"NovelTranslate[madara]","site":"https://noveltranslate.com/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/classes/.js/plugins/english/NovelTranslate[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/classes/icons/multisrc/madara/icons/noveltranslate.png"},{"id":"onlymtl","name":"OnlyMTL[madara]","site":"https://www.onlymtl.com/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/classes/.js/plugins/english/OnlyMTL[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/classes/icons/multisrc/madara/icons/onlymtl.png"},{"id":"pandamtl","name":"PandaMTL","site":"https://pandamtl.com/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/classes/.js/plugins/english/pandaMTL.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/classes/icons/src/en/wordpress/icon.png"},{"id":"readwebnovels","name":"ReadWebNovels[madara]","site":"https://readwebnovels.net/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/classes/.js/plugins/english/ReadWebNovels[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/classes/icons/multisrc/madara/icons/readwebnovels.png"},{"id":"sleeptTLS","name":"SleepyTranslations[madara]","site":"https://sleepytranslations.com/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/classes/.js/plugins/english/SleepyTranslations[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/classes/icons/multisrc/madara/icons/sleepytranslations.png"},{"id":"sonicmtl","name":"SonicMTL[madara]","site":"https://www.sonicmtl.com/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/classes/.js/plugins/english/SonicMTL[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/classes/icons/multisrc/madara/icons/sonicmtl.png"},{"id":"sugarbbscan","name":"Sugar Babies[madara]","site":"https://sugarbbscan.com/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/classes/.js/plugins/english/SugarBabies[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/classes/icons/multisrc/madara/icons/sugarbabies.png"},{"id":"sweetEscapeTL","name":"Sweet Escape Translations[madara]","site":"https://sweetescapetranslations.com/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/classes/.js/plugins/english/SweetEscapeTranslations[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/classes/icons/multisrc/madara/icons/sweetescapetranslations.png"},{"id":"webnovelover","name":"WebNovelLover[madara]","site":"https://www.webnovelover.com/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/classes/.js/plugins/english/WebNovelLover[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/classes/icons/multisrc/madara/icons/webnovellover.png"},{"id":"wuxiaworld.site","name":"WuxiaWorld.Site[madara]","site":"https://wuxiaworld.site/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/classes/.js/plugins/english/WuxiaWorldSite[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/classes/icons/multisrc/madara/icons/wuxiaworld.site.png"},{"id":"zetroTL","name":"Zetro Translation[madara]","site":"https://zetrotranslation.com/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/classes/.js/plugins/english/ZetroTranslation[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/classes/icons/multisrc/madara/icons/zetrotranslation.png"},{"id":"zinnovel","name":"ZinnNovel[madara]","site":"https://zinnovel.com/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/classes/.js/plugins/english/ZinnNovel[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/classes/icons/multisrc/madara/icons/zinnnovel.png"}],"Bahasa Indonesia":[{"id":"meionovel","name":"MeioNovel[madara]","site":"https://meionovel.id/","lang":"Bahasa Indonesia","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/classes/.js/plugins/indonesian/MeioNovel[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/classes/icons/multisrc/madara/icons/meionovel.png"},{"id":"morenovel","name":"MoreNovel[madara]","site":"https://morenovel.net/","lang":"Bahasa Indonesia","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/classes/.js/plugins/indonesian/MoreNovel[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/classes/icons/multisrc/madara/icons/morenovel.png"},{"id":"wbnovel","name":"WBNovel[madara]","site":"https://wbnovel.com/","lang":"Bahasa Indonesia","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/classes/.js/plugins/indonesian/WBNovel[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/classes/icons/multisrc/madara/icons/wbnovel.png"}],"Português":[{"id":"lightnovelbrasil","name":"Light Novel Brasil","site":"https://lightnovelbrasil.com/","lang":"Português","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/classes/.js/plugins/portuguese/lightnovelbrasil.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/classes/icons/multisrc/wpmangastream/icons/lightnovelbrasil.png"}],"Türkçe":[{"id":"lshnovel","name":"Liebe Schnee Hiver Novel","site":"https://lshnovel.com/","lang":"Türkçe","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/classes/.js/plugins/turkish/lshnovel.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/classes/icons/multisrc/wpmangastream/icons/lshnovel.png"},{"id":"turkcelightnovels","name":"TurkceLightNovels[madara]","site":"https://turkcelightnovels.com/","lang":"Türkçe","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/classes/.js/plugins/turkish/TurkceLightNovels[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/classes/icons/multisrc/madara/icons/turkcelightnovels.png"},{"id":"webnoveloku","name":"WebNovelOku [madara]","site":"https://www.webnoveloku.com/","lang":"Türkçe","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/classes/.js/plugins/turkish/WebNovelOku[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/classes/icons/multisrc/madara/icons/webnoveloku.png"}],"Tiếng Việt":[{"id":"ln.hako","name":"Hako","site":"https://ln.hako.vn","lang":"Tiếng Việt","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/classes/.js/plugins/vietnamese/LNHako.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/classes/icons/src/vi/hakolightnovel/icon.png"}]} \ No newline at end of file diff --git a/.github/workflows/updatejson.yml b/.github/workflows/updatejson.yml index 8097fe7..9ff5b84 100644 --- a/.github/workflows/updatejson.yml +++ b/.github/workflows/updatejson.yml @@ -19,8 +19,8 @@ jobs: - name: Clean up current dist run: | - rm -rf dist - mkdir dist + rm -rf .dist + mkdir .dist cat > config.json << EOF { "githubUsername": "LNReader", @@ -32,7 +32,7 @@ jobs: id: json run: | npm run json - changes="$(git diff --staged dist)" + changes="$(git diff --staged .dist)" if [ "$changes" ] then changes=1 diff --git a/.gitignore b/.gitignore index 3365c9d..7c3b280 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,8 @@ -node_modules/**/* +node_modules .vscode .env config.json # ignore TS translation folder but keep plugins folder -js/* -!js/plugins +.js/* +!.js/plugins diff --git a/.js/plugins/arabic/ArMTL[madara].js b/.js/plugins/arabic/ArMTL[madara].js new file mode 100644 index 0000000..7c30562 --- /dev/null +++ b/.js/plugins/arabic/ArMTL[madara].js @@ -0,0 +1,269 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __generator = (this && this.__generator) || function (thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (g && (g = 0, op[0] && (_ = 0)), _) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +}; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var fetch_1 = require("@libs/fetch"); +var cheerio_1 = require("cheerio"); +var defaultCover_1 = require("@libs/defaultCover"); +var novelStatus_1 = require("@libs/novelStatus"); +var parseMadaraDate_1 = require("@libs/parseMadaraDate"); +var dayjs_1 = __importDefault(require("dayjs")); +var MadaraDefaultPath = { + novels: 'novel', + novel: 'novel', + chapter: 'novel' +}; +var MadaraPlugin = /** @class */ (function () { + function MadaraPlugin(metadata) { + this.id = metadata.id; + this.name = metadata.sourceName + "[madara]"; + var iconFileName = metadata.sourceName.replace(/\s+/g, "").toLowerCase(); + this.icon = "multisrc/madara/icons/".concat(iconFileName, ".png"); + this.site = metadata.sourceSite; + this.version = "1.0.0"; + this.userAgent = ""; + this.cookieString = ""; + this.options = metadata.options; + this.filter = metadata.filters; + } + MadaraPlugin.prototype.popularNovels = function (pageNo, _a) { + var _b, _c, _d, _e, _f, _g; + var filters = _a.filters, showLatestNovels = _a.showLatestNovels; + return __awaiter(this, void 0, void 0, function () { + var novels, url, body, loadedCheerio; + return __generator(this, function (_h) { + switch (_h.label) { + case 0: + novels = []; + url = this.site; + if ((filters === null || filters === void 0 ? void 0 : filters.genres) && ((_c = (_b = this.options) === null || _b === void 0 ? void 0 : _b.path) === null || _c === void 0 ? void 0 : _c.genres)) { + url += ((_e = (_d = this.options) === null || _d === void 0 ? void 0 : _d.path) === null || _e === void 0 ? void 0 : _e.genres) + filters.genres + '/'; + } + else { + url += ((_g = (_f = this.options) === null || _f === void 0 ? void 0 : _f.path) === null || _g === void 0 ? void 0 : _g.novels) ? this.options.path.novels : MadaraDefaultPath.novels; + } + url += '/page/' + pageNo + '/' + + '?m_orderby=' + (showLatestNovels ? 'latest' : ((filters === null || filters === void 0 ? void 0 : filters.sort) || 'rating')); + return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })]; + case 1: + body = _h.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.manga-title-badges').remove(); + loadedCheerio('.page-item-detail').each(function () { + var novelName = loadedCheerio(this).find('.post-title').text().trim(); + var image = loadedCheerio(this).find('img'); + var novelCover = image.attr('data-src') || image.attr('src'); + var novelUrl = loadedCheerio(this).find('.post-title') + .find('a') + .attr('href') || ''; + var novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + novels.push(novel); + }); + return [2 /*return*/, novels]; + } + }); + }); + }; + MadaraPlugin.prototype.parseNovelAndChapters = function (novelUrl) { + var _a; + return __awaiter(this, void 0, void 0, function () { + var novel, body, loadedCheerio, html, novelId, formData, chapters; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + novel = { + url: novelUrl, + }; + return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl).then(function (res) { return res.text(); })]; + case 1: + body = _b.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.manga-title-badges, #manga-title span').remove(); + novel.name = + loadedCheerio('.post-title h1').text().trim() || + loadedCheerio('#manga-title h1').text(); + novel.cover = + loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || + loadedCheerio('.summary_image > a > img').attr('data-src') || + loadedCheerio('.summary_image > a > img').attr('src') || + defaultCover_1.defaultCover; + loadedCheerio('.post-content_item, .post-content').each(function () { + var detailName = loadedCheerio(this).find('h5').text().trim(); + var detail = loadedCheerio(this).find('.summary-content').text().trim(); + switch (detailName) { + case 'Genre(s)': + case 'التصنيفات': + novel.genres = detail.replace(/[\\t\\n]/g, ','); + break; + case 'Author(s)': + case 'المؤلف': + case 'المؤلف (ين)': + novel.author = detail; + break; + case 'Status': + case 'الحالة': + novel.status = + detail.includes('OnGoing') || detail.includes('مستمرة') + ? novelStatus_1.NovelStatus.Ongoing + : novelStatus_1.NovelStatus.Completed; + break; + } + }); + loadedCheerio('div.summary__content .code-block,script').remove(); + novel.summary = + loadedCheerio('div.summary__content').text().trim() || + loadedCheerio('#tab-manga-about').text().trim() || + loadedCheerio('.post-content_item h5:contains("Summary")').next().text().trim(); + if (!(((_a = this.options) === null || _a === void 0 ? void 0 : _a.useNewChapterEndpoint) !== true)) return [3 /*break*/, 3]; + novelId = loadedCheerio('.rating-post-id').attr('value') || + loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; + formData = new FormData(); + formData.append("action", "manga_get_chapters"); + formData.append("manga", novelId); + return [4 /*yield*/, (0, fetch_1.fetchApi)(this.site + 'wp-admin/admin-ajax.php', { + method: 'POST', + body: formData, + }) + .then(function (res) { return res.text(); })]; + case 2: + html = _b.sent(); + return [3 /*break*/, 5]; + case 3: return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl + 'ajax/chapters/', { method: 'POST' }) + .then(function (res) { return res.text(); })]; + case 4: + html = _b.sent(); + _b.label = 5; + case 5: + if (html !== '0') { + loadedCheerio = (0, cheerio_1.load)(html); + } + chapters = []; + loadedCheerio('.wp-manga-chapter').each(function () { + var chapterName = loadedCheerio(this).find('a').text().trim(); + var releaseDate = null; + releaseDate = loadedCheerio(this) + .find('span.chapter-release-date') + .text() + .trim(); + if (releaseDate) { + releaseDate = (0, parseMadaraDate_1.parseMadaraDate)(releaseDate); + } + else { + /** + * Insert current date + */ + releaseDate = (0, dayjs_1.default)().format('LL'); + } + var chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); + }); + novel.chapters = chapters.reverse(); + return [2 /*return*/, novel]; + } + }); + }); + }; + MadaraPlugin.prototype.parseChapter = function (chapterUrl) { + return __awaiter(this, void 0, void 0, function () { + var body, loadedCheerio, chapterText; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, (0, fetch_1.fetchApi)(chapterUrl).then(function (res) { return res.text(); })]; + case 1: + body = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + chapterText = loadedCheerio('.text-left').html() || + loadedCheerio('.text-right').html() || + loadedCheerio('.entry-content').html() || ""; + return [2 /*return*/, chapterText]; + } + }); + }); + }; + MadaraPlugin.prototype.searchNovels = function (searchTerm, pageNo) { + return __awaiter(this, void 0, void 0, function () { + var novels, url, body, loadedCheerio; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + novels = []; + url = this.site + "?s=" + searchTerm + "&post_type=wp-manga"; + return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })]; + case 1: + body = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.c-tabs-item__content').each(function () { + var novelName = loadedCheerio(this).find('.post-title').text().trim(); + var image = loadedCheerio(this).find('img'); + var novelCover = image.attr('data-src') || image.attr('src'); + var novelUrl = loadedCheerio(this) + .find('.post-title') + .find('a') + .attr('href') || ''; + var novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + novels.push(novel); + }); + return [2 /*return*/, novels]; + } + }); + }); + }; + MadaraPlugin.prototype.fetchImage = function (url) { + return __awaiter(this, void 0, void 0, function () { + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, (0, fetch_1.fetchFile)(url, {})]; + case 1: return [2 /*return*/, _a.sent()]; + } + }); + }); + }; + return MadaraPlugin; +}()); +var plugin = new MadaraPlugin({ "id": "ar-mtl", "sourceSite": "https://ar-mtl.club/", "sourceName": "ArMTL", "filters": [], "options": { "useNewChapterEndpoint": true, "lang": "Arabic" } }); +exports.default = plugin; diff --git a/.js/plugins/arabic/ArNovel[madara].js b/.js/plugins/arabic/ArNovel[madara].js new file mode 100644 index 0000000..9d4d9a5 --- /dev/null +++ b/.js/plugins/arabic/ArNovel[madara].js @@ -0,0 +1,269 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __generator = (this && this.__generator) || function (thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (g && (g = 0, op[0] && (_ = 0)), _) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +}; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var fetch_1 = require("@libs/fetch"); +var cheerio_1 = require("cheerio"); +var defaultCover_1 = require("@libs/defaultCover"); +var novelStatus_1 = require("@libs/novelStatus"); +var parseMadaraDate_1 = require("@libs/parseMadaraDate"); +var dayjs_1 = __importDefault(require("dayjs")); +var MadaraDefaultPath = { + novels: 'novel', + novel: 'novel', + chapter: 'novel' +}; +var MadaraPlugin = /** @class */ (function () { + function MadaraPlugin(metadata) { + this.id = metadata.id; + this.name = metadata.sourceName + "[madara]"; + var iconFileName = metadata.sourceName.replace(/\s+/g, "").toLowerCase(); + this.icon = "multisrc/madara/icons/".concat(iconFileName, ".png"); + this.site = metadata.sourceSite; + this.version = "1.0.0"; + this.userAgent = ""; + this.cookieString = ""; + this.options = metadata.options; + this.filter = metadata.filters; + } + MadaraPlugin.prototype.popularNovels = function (pageNo, _a) { + var _b, _c, _d, _e, _f, _g; + var filters = _a.filters, showLatestNovels = _a.showLatestNovels; + return __awaiter(this, void 0, void 0, function () { + var novels, url, body, loadedCheerio; + return __generator(this, function (_h) { + switch (_h.label) { + case 0: + novels = []; + url = this.site; + if ((filters === null || filters === void 0 ? void 0 : filters.genres) && ((_c = (_b = this.options) === null || _b === void 0 ? void 0 : _b.path) === null || _c === void 0 ? void 0 : _c.genres)) { + url += ((_e = (_d = this.options) === null || _d === void 0 ? void 0 : _d.path) === null || _e === void 0 ? void 0 : _e.genres) + filters.genres + '/'; + } + else { + url += ((_g = (_f = this.options) === null || _f === void 0 ? void 0 : _f.path) === null || _g === void 0 ? void 0 : _g.novels) ? this.options.path.novels : MadaraDefaultPath.novels; + } + url += '/page/' + pageNo + '/' + + '?m_orderby=' + (showLatestNovels ? 'latest' : ((filters === null || filters === void 0 ? void 0 : filters.sort) || 'rating')); + return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })]; + case 1: + body = _h.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.manga-title-badges').remove(); + loadedCheerio('.page-item-detail').each(function () { + var novelName = loadedCheerio(this).find('.post-title').text().trim(); + var image = loadedCheerio(this).find('img'); + var novelCover = image.attr('data-src') || image.attr('src'); + var novelUrl = loadedCheerio(this).find('.post-title') + .find('a') + .attr('href') || ''; + var novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + novels.push(novel); + }); + return [2 /*return*/, novels]; + } + }); + }); + }; + MadaraPlugin.prototype.parseNovelAndChapters = function (novelUrl) { + var _a; + return __awaiter(this, void 0, void 0, function () { + var novel, body, loadedCheerio, html, novelId, formData, chapters; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + novel = { + url: novelUrl, + }; + return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl).then(function (res) { return res.text(); })]; + case 1: + body = _b.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.manga-title-badges, #manga-title span').remove(); + novel.name = + loadedCheerio('.post-title h1').text().trim() || + loadedCheerio('#manga-title h1').text(); + novel.cover = + loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || + loadedCheerio('.summary_image > a > img').attr('data-src') || + loadedCheerio('.summary_image > a > img').attr('src') || + defaultCover_1.defaultCover; + loadedCheerio('.post-content_item, .post-content').each(function () { + var detailName = loadedCheerio(this).find('h5').text().trim(); + var detail = loadedCheerio(this).find('.summary-content').text().trim(); + switch (detailName) { + case 'Genre(s)': + case 'التصنيفات': + novel.genres = detail.replace(/[\\t\\n]/g, ','); + break; + case 'Author(s)': + case 'المؤلف': + case 'المؤلف (ين)': + novel.author = detail; + break; + case 'Status': + case 'الحالة': + novel.status = + detail.includes('OnGoing') || detail.includes('مستمرة') + ? novelStatus_1.NovelStatus.Ongoing + : novelStatus_1.NovelStatus.Completed; + break; + } + }); + loadedCheerio('div.summary__content .code-block,script').remove(); + novel.summary = + loadedCheerio('div.summary__content').text().trim() || + loadedCheerio('#tab-manga-about').text().trim() || + loadedCheerio('.post-content_item h5:contains("Summary")').next().text().trim(); + if (!(((_a = this.options) === null || _a === void 0 ? void 0 : _a.useNewChapterEndpoint) !== true)) return [3 /*break*/, 3]; + novelId = loadedCheerio('.rating-post-id').attr('value') || + loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; + formData = new FormData(); + formData.append("action", "manga_get_chapters"); + formData.append("manga", novelId); + return [4 /*yield*/, (0, fetch_1.fetchApi)(this.site + 'wp-admin/admin-ajax.php', { + method: 'POST', + body: formData, + }) + .then(function (res) { return res.text(); })]; + case 2: + html = _b.sent(); + return [3 /*break*/, 5]; + case 3: return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl + 'ajax/chapters/', { method: 'POST' }) + .then(function (res) { return res.text(); })]; + case 4: + html = _b.sent(); + _b.label = 5; + case 5: + if (html !== '0') { + loadedCheerio = (0, cheerio_1.load)(html); + } + chapters = []; + loadedCheerio('.wp-manga-chapter').each(function () { + var chapterName = loadedCheerio(this).find('a').text().trim(); + var releaseDate = null; + releaseDate = loadedCheerio(this) + .find('span.chapter-release-date') + .text() + .trim(); + if (releaseDate) { + releaseDate = (0, parseMadaraDate_1.parseMadaraDate)(releaseDate); + } + else { + /** + * Insert current date + */ + releaseDate = (0, dayjs_1.default)().format('LL'); + } + var chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); + }); + novel.chapters = chapters.reverse(); + return [2 /*return*/, novel]; + } + }); + }); + }; + MadaraPlugin.prototype.parseChapter = function (chapterUrl) { + return __awaiter(this, void 0, void 0, function () { + var body, loadedCheerio, chapterText; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, (0, fetch_1.fetchApi)(chapterUrl).then(function (res) { return res.text(); })]; + case 1: + body = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + chapterText = loadedCheerio('.text-left').html() || + loadedCheerio('.text-right').html() || + loadedCheerio('.entry-content').html() || ""; + return [2 /*return*/, chapterText]; + } + }); + }); + }; + MadaraPlugin.prototype.searchNovels = function (searchTerm, pageNo) { + return __awaiter(this, void 0, void 0, function () { + var novels, url, body, loadedCheerio; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + novels = []; + url = this.site + "?s=" + searchTerm + "&post_type=wp-manga"; + return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })]; + case 1: + body = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.c-tabs-item__content').each(function () { + var novelName = loadedCheerio(this).find('.post-title').text().trim(); + var image = loadedCheerio(this).find('img'); + var novelCover = image.attr('data-src') || image.attr('src'); + var novelUrl = loadedCheerio(this) + .find('.post-title') + .find('a') + .attr('href') || ''; + var novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + novels.push(novel); + }); + return [2 /*return*/, novels]; + } + }); + }); + }; + MadaraPlugin.prototype.fetchImage = function (url) { + return __awaiter(this, void 0, void 0, function () { + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, (0, fetch_1.fetchFile)(url, {})]; + case 1: return [2 /*return*/, _a.sent()]; + } + }); + }); + }; + return MadaraPlugin; +}()); +var plugin = new MadaraPlugin({ "id": "arnovel", "sourceSite": "https://arnovel.me/", "sourceName": "ArNovel", "filters": [{ "key": "sort", "label": "الترتيب حسب", "values": [{ "label": "A-Z", "value": "alphabet" }, { "label": "الآخير", "value": "latest" }, { "label": "الأكثر مشاهدة", "value": "views" }, { "label": "التقييم", "value": "rating" }, { "label": "جديد", "value": "new-manga" }, { "label": "شائع", "value": "trending" }], "inputType": "Picker" }, { "key": "genres", "label": "التصنيفات", "values": [{ "label": "أكشن", "value": "%d8%a3%d9%83%d8%b4%d9%86" }, { "label": "إتشي", "value": "%d8%a5%d8%aa%d8%b4%d9%80%d9%8a" }, { "label": "بالغ", "value": "%d8%a8%d8%a7%d9%84%d8%ba" }, { "label": "تاريخي", "value": "%d8%aa%d8%a7%d8%b1%d9%8a%d8%ae%d9%8a" }, { "label": "تراجدي", "value": "%d8%aa%d8%b1%d8%a7%d8%ac%d8%af%d9%8a" }, { "label": "جوسي", "value": "%d8%ac%d9%88%d8%b3%d9%8a" }, { "label": "حريم", "value": "%d8%ad%d8%b1%d9%8a%d9%85" }, { "label": "حياة مدرسية", "value": "%d8%ad%d9%8a%d8%a7%d8%a9-%d9%85%d8%af%d8%b1%d8%b3%d9%8a%d8%a9" }, { "label": "خارق لطبيعية", "value": "%d8%ae%d8%a7%d8%b1%d9%82-%d9%84%d8%b7%d8%a8%d9%8a%d8%b9%d9%8a%d8%a9" }, { "label": "خيال", "value": "%d8%ae%d9%8a%d8%a7%d9%84" }, { "label": "خيال علمي", "value": "%d8%ae%d9%8a%d8%a7%d9%84-%d8%b9%d9%84%d9%85%d9%8a" }, { "label": "دراما", "value": "%d8%af%d8%b1%d8%a7%d9%85%d8%a7" }, { "label": "راشد", "value": "%d8%b1%d8%a7%d8%b4%d8%af" }, { "label": "رعب", "value": "%d8%b1%d8%b9%d8%a8" }, { "label": "رومنسي", "value": "%d8%b1%d9%88%d9%85%d9%86%d8%b3%d9%8a" }, { "label": "رياضي", "value": "%d8%b1%d9%8a%d8%a7%d8%b6%d9%8a" }, { "label": "سينين", "value": "%d8%b3%d9%8a%d9%86%d9%8a%d9%86" }, { "label": "شريحة من الحياة", "value": "%d8%b4%d8%b1%d9%8a%d8%ad%d8%a9-%d9%85%d9%86-%d8%a7%d9%84%d8%ad%d9%8a%d8%a7%d8%a9" }, { "label": "شوجو", "value": "%d8%b4%d9%88%d8%ac%d9%88" }, { "label": "شونين", "value": "%d8%b4%d9%88%d9%86%d9%8a%d9%86" }, { "label": "غموض", "value": "%d8%ba%d9%85%d9%88%d8%b6" }, { "label": "فنون قتال", "value": "%d9%81%d9%86%d9%88%d9%86-%d9%82%d8%aa%d8%a7%d9%84" }, { "label": "كوميديا", "value": "%d9%83%d9%88%d9%85%d9%8a%d8%af%d9%8a%d8%a7" }, { "label": "مغامرات", "value": "%d9%85%d8%ba%d8%a7%d9%85%d8%b1%d8%a7%d8%aa" }, { "label": "منتهية", "value": "%d9%85%d9%86%d8%aa%d9%87%d9%8a%d8%a9" }, { "label": "ميكا", "value": "%d9%85%d9%8a%d9%83%d8%a7" }, { "label": "نفسي", "value": "%d9%86%d9%81%d8%b3%d9%8a" }], "inputType": "Picker" }], "options": { "path": { "genres": "home/novel-genre" }, "useNewChapterEndpoint": true, "lang": "Arabic" } }); +exports.default = plugin; diff --git a/.js/plugins/arabic/HizoManga[madara].js b/.js/plugins/arabic/HizoManga[madara].js new file mode 100644 index 0000000..c70d234 --- /dev/null +++ b/.js/plugins/arabic/HizoManga[madara].js @@ -0,0 +1,269 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __generator = (this && this.__generator) || function (thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (g && (g = 0, op[0] && (_ = 0)), _) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +}; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var fetch_1 = require("@libs/fetch"); +var cheerio_1 = require("cheerio"); +var defaultCover_1 = require("@libs/defaultCover"); +var novelStatus_1 = require("@libs/novelStatus"); +var parseMadaraDate_1 = require("@libs/parseMadaraDate"); +var dayjs_1 = __importDefault(require("dayjs")); +var MadaraDefaultPath = { + novels: 'novel', + novel: 'novel', + chapter: 'novel' +}; +var MadaraPlugin = /** @class */ (function () { + function MadaraPlugin(metadata) { + this.id = metadata.id; + this.name = metadata.sourceName + "[madara]"; + var iconFileName = metadata.sourceName.replace(/\s+/g, "").toLowerCase(); + this.icon = "multisrc/madara/icons/".concat(iconFileName, ".png"); + this.site = metadata.sourceSite; + this.version = "1.0.0"; + this.userAgent = ""; + this.cookieString = ""; + this.options = metadata.options; + this.filter = metadata.filters; + } + MadaraPlugin.prototype.popularNovels = function (pageNo, _a) { + var _b, _c, _d, _e, _f, _g; + var filters = _a.filters, showLatestNovels = _a.showLatestNovels; + return __awaiter(this, void 0, void 0, function () { + var novels, url, body, loadedCheerio; + return __generator(this, function (_h) { + switch (_h.label) { + case 0: + novels = []; + url = this.site; + if ((filters === null || filters === void 0 ? void 0 : filters.genres) && ((_c = (_b = this.options) === null || _b === void 0 ? void 0 : _b.path) === null || _c === void 0 ? void 0 : _c.genres)) { + url += ((_e = (_d = this.options) === null || _d === void 0 ? void 0 : _d.path) === null || _e === void 0 ? void 0 : _e.genres) + filters.genres + '/'; + } + else { + url += ((_g = (_f = this.options) === null || _f === void 0 ? void 0 : _f.path) === null || _g === void 0 ? void 0 : _g.novels) ? this.options.path.novels : MadaraDefaultPath.novels; + } + url += '/page/' + pageNo + '/' + + '?m_orderby=' + (showLatestNovels ? 'latest' : ((filters === null || filters === void 0 ? void 0 : filters.sort) || 'rating')); + return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })]; + case 1: + body = _h.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.manga-title-badges').remove(); + loadedCheerio('.page-item-detail').each(function () { + var novelName = loadedCheerio(this).find('.post-title').text().trim(); + var image = loadedCheerio(this).find('img'); + var novelCover = image.attr('data-src') || image.attr('src'); + var novelUrl = loadedCheerio(this).find('.post-title') + .find('a') + .attr('href') || ''; + var novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + novels.push(novel); + }); + return [2 /*return*/, novels]; + } + }); + }); + }; + MadaraPlugin.prototype.parseNovelAndChapters = function (novelUrl) { + var _a; + return __awaiter(this, void 0, void 0, function () { + var novel, body, loadedCheerio, html, novelId, formData, chapters; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + novel = { + url: novelUrl, + }; + return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl).then(function (res) { return res.text(); })]; + case 1: + body = _b.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.manga-title-badges, #manga-title span').remove(); + novel.name = + loadedCheerio('.post-title h1').text().trim() || + loadedCheerio('#manga-title h1').text(); + novel.cover = + loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || + loadedCheerio('.summary_image > a > img').attr('data-src') || + loadedCheerio('.summary_image > a > img').attr('src') || + defaultCover_1.defaultCover; + loadedCheerio('.post-content_item, .post-content').each(function () { + var detailName = loadedCheerio(this).find('h5').text().trim(); + var detail = loadedCheerio(this).find('.summary-content').text().trim(); + switch (detailName) { + case 'Genre(s)': + case 'التصنيفات': + novel.genres = detail.replace(/[\\t\\n]/g, ','); + break; + case 'Author(s)': + case 'المؤلف': + case 'المؤلف (ين)': + novel.author = detail; + break; + case 'Status': + case 'الحالة': + novel.status = + detail.includes('OnGoing') || detail.includes('مستمرة') + ? novelStatus_1.NovelStatus.Ongoing + : novelStatus_1.NovelStatus.Completed; + break; + } + }); + loadedCheerio('div.summary__content .code-block,script').remove(); + novel.summary = + loadedCheerio('div.summary__content').text().trim() || + loadedCheerio('#tab-manga-about').text().trim() || + loadedCheerio('.post-content_item h5:contains("Summary")').next().text().trim(); + if (!(((_a = this.options) === null || _a === void 0 ? void 0 : _a.useNewChapterEndpoint) !== true)) return [3 /*break*/, 3]; + novelId = loadedCheerio('.rating-post-id').attr('value') || + loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; + formData = new FormData(); + formData.append("action", "manga_get_chapters"); + formData.append("manga", novelId); + return [4 /*yield*/, (0, fetch_1.fetchApi)(this.site + 'wp-admin/admin-ajax.php', { + method: 'POST', + body: formData, + }) + .then(function (res) { return res.text(); })]; + case 2: + html = _b.sent(); + return [3 /*break*/, 5]; + case 3: return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl + 'ajax/chapters/', { method: 'POST' }) + .then(function (res) { return res.text(); })]; + case 4: + html = _b.sent(); + _b.label = 5; + case 5: + if (html !== '0') { + loadedCheerio = (0, cheerio_1.load)(html); + } + chapters = []; + loadedCheerio('.wp-manga-chapter').each(function () { + var chapterName = loadedCheerio(this).find('a').text().trim(); + var releaseDate = null; + releaseDate = loadedCheerio(this) + .find('span.chapter-release-date') + .text() + .trim(); + if (releaseDate) { + releaseDate = (0, parseMadaraDate_1.parseMadaraDate)(releaseDate); + } + else { + /** + * Insert current date + */ + releaseDate = (0, dayjs_1.default)().format('LL'); + } + var chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); + }); + novel.chapters = chapters.reverse(); + return [2 /*return*/, novel]; + } + }); + }); + }; + MadaraPlugin.prototype.parseChapter = function (chapterUrl) { + return __awaiter(this, void 0, void 0, function () { + var body, loadedCheerio, chapterText; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, (0, fetch_1.fetchApi)(chapterUrl).then(function (res) { return res.text(); })]; + case 1: + body = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + chapterText = loadedCheerio('.text-left').html() || + loadedCheerio('.text-right').html() || + loadedCheerio('.entry-content').html() || ""; + return [2 /*return*/, chapterText]; + } + }); + }); + }; + MadaraPlugin.prototype.searchNovels = function (searchTerm, pageNo) { + return __awaiter(this, void 0, void 0, function () { + var novels, url, body, loadedCheerio; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + novels = []; + url = this.site + "?s=" + searchTerm + "&post_type=wp-manga"; + return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })]; + case 1: + body = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.c-tabs-item__content').each(function () { + var novelName = loadedCheerio(this).find('.post-title').text().trim(); + var image = loadedCheerio(this).find('img'); + var novelCover = image.attr('data-src') || image.attr('src'); + var novelUrl = loadedCheerio(this) + .find('.post-title') + .find('a') + .attr('href') || ''; + var novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + novels.push(novel); + }); + return [2 /*return*/, novels]; + } + }); + }); + }; + MadaraPlugin.prototype.fetchImage = function (url) { + return __awaiter(this, void 0, void 0, function () { + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, (0, fetch_1.fetchFile)(url, {})]; + case 1: return [2 /*return*/, _a.sent()]; + } + }); + }); + }; + return MadaraPlugin; +}()); +var plugin = new MadaraPlugin({ "id": "hizomanga", "sourceSite": "https://hizomanga.com/", "sourceName": "HizoManga", "filters": [{ "key": "sort", "label": "ترتيب حسب", "values": [{ "label": "A-Z", "value": "alphabet" }, { "label": "New", "value": "new-manga" }, { "label": "الأحدث", "value": "latest" }, { "label": "الأكثر مشاهدة", "value": "views" }, { "label": "التقييم", "value": "rating" }, { "label": "الرائج", "value": "trending" }], "inputType": "Picker" }, { "key": "genres", "label": "التصنيفات", "values": [{ "label": "آلات", "value": "mechanisms" }, { "label": "أكشن", "value": "action" }, { "label": "إثارة", "value": "excitement" }, { "label": "إيسكاي", "value": "%d8%a5%d9%8a%d8%b3%d9%83%d8%a7%d9%8a" }, { "label": "الحياة اليومية", "value": "slice-of-life" }, { "label": "الحياة مدرسية", "value": "school-life" }, { "label": "تاريخي", "value": "historical" }, { "label": "تراجيدي", "value": "tragic" }, { "label": "جريمة", "value": "%d8%ac%d8%b1%d9%8a%d9%85%d8%a9" }, { "label": "جندر بندر", "value": "%d8%ac%d9%86%d8%af%d8%b1-%d8%a8%d9%86%d8%af%d8%b1" }, { "label": "جوسي", "value": "josei" }, { "label": "حريم", "value": "harem" }, { "label": "خارق للطبيعة", "value": "supernatural" }, { "label": "خيال", "value": "fantasy" }, { "label": "خيال علمي", "value": "sci-fi" }, { "label": "دراما", "value": "drama" }, { "label": "دموي", "value": "%d8%af%d9%85%d9%88%d9%8a" }, { "label": "راشد", "value": "mature" }, { "label": "رعب", "value": "horror" }, { "label": "رومانسي", "value": "romance" }, { "label": "رياضة", "value": "sports" }, { "label": "زمنكاني", "value": "my-time" }, { "label": "زومبي", "value": "%d8%b2%d9%88%d9%85%d8%a8%d9%8a" }, { "label": "سينين", "value": "seinen" }, { "label": "شريحة من الحياة", "value": "%d8%b4%d8%b1%d9%8a%d8%ad%d8%a9-%d9%85%d9%86-%d8%a7%d9%84%d8%ad%d9%8a%d8%a7%d8%a9" }, { "label": "شوجو", "value": "shoujo" }, { "label": "شونين", "value": "shounen" }, { "label": "طبي", "value": "%d8%b7%d8%a8%d9%8a" }, { "label": "غموض", "value": "ambiguity" }, { "label": "فنون قتالية", "value": "martial-arts" }, { "label": "قوة خارقة", "value": "superpower" }, { "label": "كوميدي", "value": "comedy" }, { "label": "مغامرات", "value": "adventure" }, { "label": "نفسي", "value": "psychological" }], "inputType": "Picker" }], "options": { "path": { "novels": "serie", "novel": "serie", "chapter": "serie", "genres": "manga-genre" }, "useNewChapterEndpoint": true, "lang": "Arabic" } }); +exports.default = plugin; diff --git a/.js/plugins/arabic/Novel4Up[madara].js b/.js/plugins/arabic/Novel4Up[madara].js new file mode 100644 index 0000000..6747ac8 --- /dev/null +++ b/.js/plugins/arabic/Novel4Up[madara].js @@ -0,0 +1,269 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __generator = (this && this.__generator) || function (thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (g && (g = 0, op[0] && (_ = 0)), _) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +}; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var fetch_1 = require("@libs/fetch"); +var cheerio_1 = require("cheerio"); +var defaultCover_1 = require("@libs/defaultCover"); +var novelStatus_1 = require("@libs/novelStatus"); +var parseMadaraDate_1 = require("@libs/parseMadaraDate"); +var dayjs_1 = __importDefault(require("dayjs")); +var MadaraDefaultPath = { + novels: 'novel', + novel: 'novel', + chapter: 'novel' +}; +var MadaraPlugin = /** @class */ (function () { + function MadaraPlugin(metadata) { + this.id = metadata.id; + this.name = metadata.sourceName + "[madara]"; + var iconFileName = metadata.sourceName.replace(/\s+/g, "").toLowerCase(); + this.icon = "multisrc/madara/icons/".concat(iconFileName, ".png"); + this.site = metadata.sourceSite; + this.version = "1.0.0"; + this.userAgent = ""; + this.cookieString = ""; + this.options = metadata.options; + this.filter = metadata.filters; + } + MadaraPlugin.prototype.popularNovels = function (pageNo, _a) { + var _b, _c, _d, _e, _f, _g; + var filters = _a.filters, showLatestNovels = _a.showLatestNovels; + return __awaiter(this, void 0, void 0, function () { + var novels, url, body, loadedCheerio; + return __generator(this, function (_h) { + switch (_h.label) { + case 0: + novels = []; + url = this.site; + if ((filters === null || filters === void 0 ? void 0 : filters.genres) && ((_c = (_b = this.options) === null || _b === void 0 ? void 0 : _b.path) === null || _c === void 0 ? void 0 : _c.genres)) { + url += ((_e = (_d = this.options) === null || _d === void 0 ? void 0 : _d.path) === null || _e === void 0 ? void 0 : _e.genres) + filters.genres + '/'; + } + else { + url += ((_g = (_f = this.options) === null || _f === void 0 ? void 0 : _f.path) === null || _g === void 0 ? void 0 : _g.novels) ? this.options.path.novels : MadaraDefaultPath.novels; + } + url += '/page/' + pageNo + '/' + + '?m_orderby=' + (showLatestNovels ? 'latest' : ((filters === null || filters === void 0 ? void 0 : filters.sort) || 'rating')); + return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })]; + case 1: + body = _h.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.manga-title-badges').remove(); + loadedCheerio('.page-item-detail').each(function () { + var novelName = loadedCheerio(this).find('.post-title').text().trim(); + var image = loadedCheerio(this).find('img'); + var novelCover = image.attr('data-src') || image.attr('src'); + var novelUrl = loadedCheerio(this).find('.post-title') + .find('a') + .attr('href') || ''; + var novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + novels.push(novel); + }); + return [2 /*return*/, novels]; + } + }); + }); + }; + MadaraPlugin.prototype.parseNovelAndChapters = function (novelUrl) { + var _a; + return __awaiter(this, void 0, void 0, function () { + var novel, body, loadedCheerio, html, novelId, formData, chapters; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + novel = { + url: novelUrl, + }; + return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl).then(function (res) { return res.text(); })]; + case 1: + body = _b.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.manga-title-badges, #manga-title span').remove(); + novel.name = + loadedCheerio('.post-title h1').text().trim() || + loadedCheerio('#manga-title h1').text(); + novel.cover = + loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || + loadedCheerio('.summary_image > a > img').attr('data-src') || + loadedCheerio('.summary_image > a > img').attr('src') || + defaultCover_1.defaultCover; + loadedCheerio('.post-content_item, .post-content').each(function () { + var detailName = loadedCheerio(this).find('h5').text().trim(); + var detail = loadedCheerio(this).find('.summary-content').text().trim(); + switch (detailName) { + case 'Genre(s)': + case 'التصنيفات': + novel.genres = detail.replace(/[\\t\\n]/g, ','); + break; + case 'Author(s)': + case 'المؤلف': + case 'المؤلف (ين)': + novel.author = detail; + break; + case 'Status': + case 'الحالة': + novel.status = + detail.includes('OnGoing') || detail.includes('مستمرة') + ? novelStatus_1.NovelStatus.Ongoing + : novelStatus_1.NovelStatus.Completed; + break; + } + }); + loadedCheerio('div.summary__content .code-block,script').remove(); + novel.summary = + loadedCheerio('div.summary__content').text().trim() || + loadedCheerio('#tab-manga-about').text().trim() || + loadedCheerio('.post-content_item h5:contains("Summary")').next().text().trim(); + if (!(((_a = this.options) === null || _a === void 0 ? void 0 : _a.useNewChapterEndpoint) !== true)) return [3 /*break*/, 3]; + novelId = loadedCheerio('.rating-post-id').attr('value') || + loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; + formData = new FormData(); + formData.append("action", "manga_get_chapters"); + formData.append("manga", novelId); + return [4 /*yield*/, (0, fetch_1.fetchApi)(this.site + 'wp-admin/admin-ajax.php', { + method: 'POST', + body: formData, + }) + .then(function (res) { return res.text(); })]; + case 2: + html = _b.sent(); + return [3 /*break*/, 5]; + case 3: return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl + 'ajax/chapters/', { method: 'POST' }) + .then(function (res) { return res.text(); })]; + case 4: + html = _b.sent(); + _b.label = 5; + case 5: + if (html !== '0') { + loadedCheerio = (0, cheerio_1.load)(html); + } + chapters = []; + loadedCheerio('.wp-manga-chapter').each(function () { + var chapterName = loadedCheerio(this).find('a').text().trim(); + var releaseDate = null; + releaseDate = loadedCheerio(this) + .find('span.chapter-release-date') + .text() + .trim(); + if (releaseDate) { + releaseDate = (0, parseMadaraDate_1.parseMadaraDate)(releaseDate); + } + else { + /** + * Insert current date + */ + releaseDate = (0, dayjs_1.default)().format('LL'); + } + var chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); + }); + novel.chapters = chapters.reverse(); + return [2 /*return*/, novel]; + } + }); + }); + }; + MadaraPlugin.prototype.parseChapter = function (chapterUrl) { + return __awaiter(this, void 0, void 0, function () { + var body, loadedCheerio, chapterText; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, (0, fetch_1.fetchApi)(chapterUrl).then(function (res) { return res.text(); })]; + case 1: + body = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + chapterText = loadedCheerio('.text-left').html() || + loadedCheerio('.text-right').html() || + loadedCheerio('.entry-content').html() || ""; + return [2 /*return*/, chapterText]; + } + }); + }); + }; + MadaraPlugin.prototype.searchNovels = function (searchTerm, pageNo) { + return __awaiter(this, void 0, void 0, function () { + var novels, url, body, loadedCheerio; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + novels = []; + url = this.site + "?s=" + searchTerm + "&post_type=wp-manga"; + return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })]; + case 1: + body = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.c-tabs-item__content').each(function () { + var novelName = loadedCheerio(this).find('.post-title').text().trim(); + var image = loadedCheerio(this).find('img'); + var novelCover = image.attr('data-src') || image.attr('src'); + var novelUrl = loadedCheerio(this) + .find('.post-title') + .find('a') + .attr('href') || ''; + var novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + novels.push(novel); + }); + return [2 /*return*/, novels]; + } + }); + }); + }; + MadaraPlugin.prototype.fetchImage = function (url) { + return __awaiter(this, void 0, void 0, function () { + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, (0, fetch_1.fetchFile)(url, {})]; + case 1: return [2 /*return*/, _a.sent()]; + } + }); + }); + }; + return MadaraPlugin; +}()); +var plugin = new MadaraPlugin({ "id": "novel4up", "sourceSite": "https://novel4up.com/", "sourceName": "Novel4Up", "filters": [{ "key": "sort", "label": "ترتيب حسب:", "values": [{ "label": "أ-ي", "value": "alphabet" }, { "label": "الأحدث", "value": "latest" }, { "label": "الأكثر مشاهدة", "value": "views" }, { "label": "التقييم", "value": "rating" }, { "label": "الجديد", "value": "new-manga" }, { "label": "الشائع", "value": "trending" }], "inputType": "Picker" }, { "key": "genres", "label": "التصنيفات", "values": [{ "label": "أكشن", "value": "action" }, { "label": "الخارق للطبيعة", "value": "supernatural" }, { "label": "تاريخي", "value": "historical" }, { "label": "تحقيق", "value": "detective" }, { "label": "تراجيديا", "value": "tragedy" }, { "label": "حريم", "value": "harem" }, { "label": "حياة مدرسية", "value": "school-life" }, { "label": "خيال علمي", "value": "sci-fi" }, { "label": "دراما", "value": "drama" }, { "label": "رعب", "value": "horror" }, { "label": "رومانسي", "value": "romance" }, { "label": "رياضة", "value": "sports" }, { "label": "سحر", "value": "magic" }, { "label": "شريحة من الحياة", "value": "slice-of-life" }, { "label": "شوانهوا", "value": "xuanhuan" }, { "label": "شوجو", "value": "shoujo" }, { "label": "شونين", "value": "shounen" }, { "label": "غموض", "value": "mystery" }, { "label": "فانتازيا", "value": "fantasy" }, { "label": "فنون قتال", "value": "martial-arts" }, { "label": "كوميديا", "value": "comedy" }, { "label": "مغامرة", "value": "adventure" }, { "label": "ميكا", "value": "mecha" }, { "label": "نفسي", "value": "psychological" }, { "label": "ون شوت", "value": "one-shot" }, { "label": "ووشيا", "value": "wuxia" }], "inputType": "Picker" }], "options": { "lang": "Arabic" } }); +exports.default = plugin; diff --git a/.js/plugins/arabic/Riwyat[madara].js b/.js/plugins/arabic/Riwyat[madara].js new file mode 100644 index 0000000..d61243c --- /dev/null +++ b/.js/plugins/arabic/Riwyat[madara].js @@ -0,0 +1,269 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __generator = (this && this.__generator) || function (thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (g && (g = 0, op[0] && (_ = 0)), _) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +}; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var fetch_1 = require("@libs/fetch"); +var cheerio_1 = require("cheerio"); +var defaultCover_1 = require("@libs/defaultCover"); +var novelStatus_1 = require("@libs/novelStatus"); +var parseMadaraDate_1 = require("@libs/parseMadaraDate"); +var dayjs_1 = __importDefault(require("dayjs")); +var MadaraDefaultPath = { + novels: 'novel', + novel: 'novel', + chapter: 'novel' +}; +var MadaraPlugin = /** @class */ (function () { + function MadaraPlugin(metadata) { + this.id = metadata.id; + this.name = metadata.sourceName + "[madara]"; + var iconFileName = metadata.sourceName.replace(/\s+/g, "").toLowerCase(); + this.icon = "multisrc/madara/icons/".concat(iconFileName, ".png"); + this.site = metadata.sourceSite; + this.version = "1.0.0"; + this.userAgent = ""; + this.cookieString = ""; + this.options = metadata.options; + this.filter = metadata.filters; + } + MadaraPlugin.prototype.popularNovels = function (pageNo, _a) { + var _b, _c, _d, _e, _f, _g; + var filters = _a.filters, showLatestNovels = _a.showLatestNovels; + return __awaiter(this, void 0, void 0, function () { + var novels, url, body, loadedCheerio; + return __generator(this, function (_h) { + switch (_h.label) { + case 0: + novels = []; + url = this.site; + if ((filters === null || filters === void 0 ? void 0 : filters.genres) && ((_c = (_b = this.options) === null || _b === void 0 ? void 0 : _b.path) === null || _c === void 0 ? void 0 : _c.genres)) { + url += ((_e = (_d = this.options) === null || _d === void 0 ? void 0 : _d.path) === null || _e === void 0 ? void 0 : _e.genres) + filters.genres + '/'; + } + else { + url += ((_g = (_f = this.options) === null || _f === void 0 ? void 0 : _f.path) === null || _g === void 0 ? void 0 : _g.novels) ? this.options.path.novels : MadaraDefaultPath.novels; + } + url += '/page/' + pageNo + '/' + + '?m_orderby=' + (showLatestNovels ? 'latest' : ((filters === null || filters === void 0 ? void 0 : filters.sort) || 'rating')); + return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })]; + case 1: + body = _h.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.manga-title-badges').remove(); + loadedCheerio('.page-item-detail').each(function () { + var novelName = loadedCheerio(this).find('.post-title').text().trim(); + var image = loadedCheerio(this).find('img'); + var novelCover = image.attr('data-src') || image.attr('src'); + var novelUrl = loadedCheerio(this).find('.post-title') + .find('a') + .attr('href') || ''; + var novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + novels.push(novel); + }); + return [2 /*return*/, novels]; + } + }); + }); + }; + MadaraPlugin.prototype.parseNovelAndChapters = function (novelUrl) { + var _a; + return __awaiter(this, void 0, void 0, function () { + var novel, body, loadedCheerio, html, novelId, formData, chapters; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + novel = { + url: novelUrl, + }; + return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl).then(function (res) { return res.text(); })]; + case 1: + body = _b.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.manga-title-badges, #manga-title span').remove(); + novel.name = + loadedCheerio('.post-title h1').text().trim() || + loadedCheerio('#manga-title h1').text(); + novel.cover = + loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || + loadedCheerio('.summary_image > a > img').attr('data-src') || + loadedCheerio('.summary_image > a > img').attr('src') || + defaultCover_1.defaultCover; + loadedCheerio('.post-content_item, .post-content').each(function () { + var detailName = loadedCheerio(this).find('h5').text().trim(); + var detail = loadedCheerio(this).find('.summary-content').text().trim(); + switch (detailName) { + case 'Genre(s)': + case 'التصنيفات': + novel.genres = detail.replace(/[\\t\\n]/g, ','); + break; + case 'Author(s)': + case 'المؤلف': + case 'المؤلف (ين)': + novel.author = detail; + break; + case 'Status': + case 'الحالة': + novel.status = + detail.includes('OnGoing') || detail.includes('مستمرة') + ? novelStatus_1.NovelStatus.Ongoing + : novelStatus_1.NovelStatus.Completed; + break; + } + }); + loadedCheerio('div.summary__content .code-block,script').remove(); + novel.summary = + loadedCheerio('div.summary__content').text().trim() || + loadedCheerio('#tab-manga-about').text().trim() || + loadedCheerio('.post-content_item h5:contains("Summary")').next().text().trim(); + if (!(((_a = this.options) === null || _a === void 0 ? void 0 : _a.useNewChapterEndpoint) !== true)) return [3 /*break*/, 3]; + novelId = loadedCheerio('.rating-post-id').attr('value') || + loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; + formData = new FormData(); + formData.append("action", "manga_get_chapters"); + formData.append("manga", novelId); + return [4 /*yield*/, (0, fetch_1.fetchApi)(this.site + 'wp-admin/admin-ajax.php', { + method: 'POST', + body: formData, + }) + .then(function (res) { return res.text(); })]; + case 2: + html = _b.sent(); + return [3 /*break*/, 5]; + case 3: return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl + 'ajax/chapters/', { method: 'POST' }) + .then(function (res) { return res.text(); })]; + case 4: + html = _b.sent(); + _b.label = 5; + case 5: + if (html !== '0') { + loadedCheerio = (0, cheerio_1.load)(html); + } + chapters = []; + loadedCheerio('.wp-manga-chapter').each(function () { + var chapterName = loadedCheerio(this).find('a').text().trim(); + var releaseDate = null; + releaseDate = loadedCheerio(this) + .find('span.chapter-release-date') + .text() + .trim(); + if (releaseDate) { + releaseDate = (0, parseMadaraDate_1.parseMadaraDate)(releaseDate); + } + else { + /** + * Insert current date + */ + releaseDate = (0, dayjs_1.default)().format('LL'); + } + var chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); + }); + novel.chapters = chapters.reverse(); + return [2 /*return*/, novel]; + } + }); + }); + }; + MadaraPlugin.prototype.parseChapter = function (chapterUrl) { + return __awaiter(this, void 0, void 0, function () { + var body, loadedCheerio, chapterText; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, (0, fetch_1.fetchApi)(chapterUrl).then(function (res) { return res.text(); })]; + case 1: + body = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + chapterText = loadedCheerio('.text-left').html() || + loadedCheerio('.text-right').html() || + loadedCheerio('.entry-content').html() || ""; + return [2 /*return*/, chapterText]; + } + }); + }); + }; + MadaraPlugin.prototype.searchNovels = function (searchTerm, pageNo) { + return __awaiter(this, void 0, void 0, function () { + var novels, url, body, loadedCheerio; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + novels = []; + url = this.site + "?s=" + searchTerm + "&post_type=wp-manga"; + return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })]; + case 1: + body = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.c-tabs-item__content').each(function () { + var novelName = loadedCheerio(this).find('.post-title').text().trim(); + var image = loadedCheerio(this).find('img'); + var novelCover = image.attr('data-src') || image.attr('src'); + var novelUrl = loadedCheerio(this) + .find('.post-title') + .find('a') + .attr('href') || ''; + var novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + novels.push(novel); + }); + return [2 /*return*/, novels]; + } + }); + }); + }; + MadaraPlugin.prototype.fetchImage = function (url) { + return __awaiter(this, void 0, void 0, function () { + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, (0, fetch_1.fetchFile)(url, {})]; + case 1: return [2 /*return*/, _a.sent()]; + } + }); + }); + }; + return MadaraPlugin; +}()); +var plugin = new MadaraPlugin({ "id": "riwyat", "sourceSite": "https://riwyat.com/", "sourceName": "Riwyat", "filters": [{ "key": "sort", "label": "Order by", "values": [{ "label": "Rating", "value": "rating" }, { "label": "A-Z", "value": "alphabet" }, { "label": "Latest", "value": "latest" }, { "label": "Most Views", "value": "views" }, { "label": "New", "value": "new-manga" }, { "label": "Trending", "value": "trending" }], "inputType": "Picker" }, { "key": "genres", "label": "GENRES", "values": [{ "label": "أكشن", "value": "%d8%a3%d9%83%d8%b4%d9%86" }, { "label": "أيتشي", "value": "%d8%a3%d9%8a%d8%aa%d8%b4%d9%8a" }, { "label": "استراتجي", "value": "%d8%a7%d8%b3%d8%aa%d8%b1%d8%a7%d8%aa%d8%ac%d9%8a" }, { "label": "العصر الحديث", "value": "%d8%a7%d9%84%d8%b9%d8%b5%d8%b1-%d8%a7%d9%84%d8%ad%d8%af%d9%8a%d8%ab" }, { "label": "انتقام", "value": "%d8%a7%d9%86%d8%aa%d9%82%d8%a7%d9%85" }, { "label": "بالغ", "value": "%d8%a8%d8%a7%d9%84%d8%ba" }, { "label": "بناء مملكة", "value": "%d8%a8%d9%86%d8%a7%d8%a1-%d9%85%d9%85%d9%84%d9%83%d8%a9" }, { "label": "بوليسي", "value": "%d8%a8%d9%88%d9%84%d9%8a%d8%b3%d9%8a" }, { "label": "تاريخي", "value": "%d8%aa%d8%a7%d8%b1%d9%8a%d8%ae%d9%8a" }, { "label": "جوسي", "value": "%d8%ac%d9%88%d8%b3%d9%8a" }, { "label": "حريم", "value": "%d8%ad%d8%b1%d9%8a%d9%85" }, { "label": "حياة يومية", "value": "%d8%ad%d9%8a%d8%a7%d8%a9-%d9%8a%d9%88%d9%85%d9%8a%d8%a9" }, { "label": "خيال", "value": "%d8%ae%d9%8a%d8%a7%d9%84" }, { "label": "خيال علمي", "value": "%d8%ae%d9%8a%d8%a7%d9%84-%d8%b9%d9%84%d9%85%d9%8a" }, { "label": "دراما", "value": "%d8%af%d8%b1%d8%a7%d9%85%d8%a7" }, { "label": "رعب", "value": "%d8%b1%d8%b9%d8%a8" }, { "label": "رومانسية", "value": "%d8%b1%d9%88%d9%85%d8%a7%d9%86%d8%b3%d9%8a%d8%a9" }, { "label": "رياضي", "value": "%d8%b1%d9%8a%d8%a7%d8%b6%d9%8a" }, { "label": "زيانشيا", "value": "xianxia" }, { "label": "سنين", "value": "%d8%b3%d9%86%d9%8a%d9%86" }, { "label": "شريحة حياة", "value": "%d8%b4%d8%b1%d9%8a%d8%ad%d8%a9-%d8%ad%d9%8a%d8%a7%d8%a9" }, { "label": "شوانهوان", "value": "xuanhuan" }, { "label": "شوجو", "value": "%d8%b4%d9%88%d8%ac%d9%88" }, { "label": "شونين", "value": "%d8%b4%d9%88%d9%86%d9%8a%d9%86" }, { "label": "شيانشيا", "value": "%d8%b4%d9%8a%d8%a7%d9%86%d8%b4%d9%8a%d8%a7" }, { "label": "عسكري", "value": "%d8%b9%d8%b3%d9%83%d8%b1%d9%8a" }, { "label": "غموض", "value": "%d8%ba%d9%85%d9%88%d8%b6" }, { "label": "فانتازيا", "value": "%d9%81%d8%a7%d9%86%d8%aa%d8%a7%d8%b2%d9%8a%d8%a7" }, { "label": "فنون قتالية", "value": "%d9%81%d9%86%d9%88%d9%86-%d9%82%d8%aa%d8%a7%d9%84%d9%8a%d8%a9" }, { "label": "قوى خارقة", "value": "%d9%82%d9%88%d9%89-%d8%ae%d8%a7%d8%b1%d9%82%d8%a9" }, { "label": "كوميديا", "value": "%d9%83%d9%88%d9%85%d9%8a%d8%af%d9%8a%d8%a7" }, { "label": "كوميك", "value": "%d9%83%d9%88%d9%85%d9%8a%d9%83" }, { "label": "للكبار", "value": "%d9%84%d9%84%d9%83%d8%a8%d8%a7%d8%b1" }, { "label": "مأساة", "value": "%d9%85%d8%a3%d8%b3%d8%a7%d8%a9" }, { "label": "مانجا", "value": "%d9%85%d8%a7%d9%86%d8%ac%d8%a7" }, { "label": "مانها", "value": "%d9%85%d8%a7%d9%86%d9%87%d8%a7" }, { "label": "مانهوا", "value": "%d9%85%d8%a7%d9%86%d9%87%d9%88%d8%a7" }, { "label": "مدرسي", "value": "%d9%85%d8%af%d8%b1%d8%b3%d9%8a" }, { "label": "مصاصي دماء", "value": "%d9%85%d8%b5%d8%a7%d8%b5%d9%8a-%d8%af%d9%85%d8%a7%d8%a1" }, { "label": "مغامرة", "value": "%d9%85%d8%ba%d8%a7%d9%85%d8%b1%d8%a9" }, { "label": "مكتملة", "value": "%d9%85%d9%83%d8%aa%d9%85%d9%84%d8%a9" }, { "label": "نفسي", "value": "%d9%86%d9%81%d8%b3%d9%8a" }, { "label": "نهاية العالم", "value": "%d9%86%d9%87%d8%a7%d9%8a%d8%a9-%d8%a7%d9%84%d8%b9%d8%a7%d9%84%d9%85" }, { "label": "واب تون", "value": "%d9%88%d8%a7%d8%a8-%d8%aa%d9%88%d9%86" }, { "label": "وان شوت", "value": "%d9%88%d8%a7%d9%86-%d8%b4%d9%88%d8%aa" }], "inputType": "Picker" }], "options": { "useNewChapterEndpoint": true, "lang": "Arabic" } }); +exports.default = plugin; diff --git a/.js/plugins/arabic/TeamXNovel[madara].js b/.js/plugins/arabic/TeamXNovel[madara].js new file mode 100644 index 0000000..1ce5d3d --- /dev/null +++ b/.js/plugins/arabic/TeamXNovel[madara].js @@ -0,0 +1,269 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __generator = (this && this.__generator) || function (thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (g && (g = 0, op[0] && (_ = 0)), _) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +}; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var fetch_1 = require("@libs/fetch"); +var cheerio_1 = require("cheerio"); +var defaultCover_1 = require("@libs/defaultCover"); +var novelStatus_1 = require("@libs/novelStatus"); +var parseMadaraDate_1 = require("@libs/parseMadaraDate"); +var dayjs_1 = __importDefault(require("dayjs")); +var MadaraDefaultPath = { + novels: 'novel', + novel: 'novel', + chapter: 'novel' +}; +var MadaraPlugin = /** @class */ (function () { + function MadaraPlugin(metadata) { + this.id = metadata.id; + this.name = metadata.sourceName + "[madara]"; + var iconFileName = metadata.sourceName.replace(/\s+/g, "").toLowerCase(); + this.icon = "multisrc/madara/icons/".concat(iconFileName, ".png"); + this.site = metadata.sourceSite; + this.version = "1.0.0"; + this.userAgent = ""; + this.cookieString = ""; + this.options = metadata.options; + this.filter = metadata.filters; + } + MadaraPlugin.prototype.popularNovels = function (pageNo, _a) { + var _b, _c, _d, _e, _f, _g; + var filters = _a.filters, showLatestNovels = _a.showLatestNovels; + return __awaiter(this, void 0, void 0, function () { + var novels, url, body, loadedCheerio; + return __generator(this, function (_h) { + switch (_h.label) { + case 0: + novels = []; + url = this.site; + if ((filters === null || filters === void 0 ? void 0 : filters.genres) && ((_c = (_b = this.options) === null || _b === void 0 ? void 0 : _b.path) === null || _c === void 0 ? void 0 : _c.genres)) { + url += ((_e = (_d = this.options) === null || _d === void 0 ? void 0 : _d.path) === null || _e === void 0 ? void 0 : _e.genres) + filters.genres + '/'; + } + else { + url += ((_g = (_f = this.options) === null || _f === void 0 ? void 0 : _f.path) === null || _g === void 0 ? void 0 : _g.novels) ? this.options.path.novels : MadaraDefaultPath.novels; + } + url += '/page/' + pageNo + '/' + + '?m_orderby=' + (showLatestNovels ? 'latest' : ((filters === null || filters === void 0 ? void 0 : filters.sort) || 'rating')); + return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })]; + case 1: + body = _h.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.manga-title-badges').remove(); + loadedCheerio('.page-item-detail').each(function () { + var novelName = loadedCheerio(this).find('.post-title').text().trim(); + var image = loadedCheerio(this).find('img'); + var novelCover = image.attr('data-src') || image.attr('src'); + var novelUrl = loadedCheerio(this).find('.post-title') + .find('a') + .attr('href') || ''; + var novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + novels.push(novel); + }); + return [2 /*return*/, novels]; + } + }); + }); + }; + MadaraPlugin.prototype.parseNovelAndChapters = function (novelUrl) { + var _a; + return __awaiter(this, void 0, void 0, function () { + var novel, body, loadedCheerio, html, novelId, formData, chapters; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + novel = { + url: novelUrl, + }; + return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl).then(function (res) { return res.text(); })]; + case 1: + body = _b.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.manga-title-badges, #manga-title span').remove(); + novel.name = + loadedCheerio('.post-title h1').text().trim() || + loadedCheerio('#manga-title h1').text(); + novel.cover = + loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || + loadedCheerio('.summary_image > a > img').attr('data-src') || + loadedCheerio('.summary_image > a > img').attr('src') || + defaultCover_1.defaultCover; + loadedCheerio('.post-content_item, .post-content').each(function () { + var detailName = loadedCheerio(this).find('h5').text().trim(); + var detail = loadedCheerio(this).find('.summary-content').text().trim(); + switch (detailName) { + case 'Genre(s)': + case 'التصنيفات': + novel.genres = detail.replace(/[\\t\\n]/g, ','); + break; + case 'Author(s)': + case 'المؤلف': + case 'المؤلف (ين)': + novel.author = detail; + break; + case 'Status': + case 'الحالة': + novel.status = + detail.includes('OnGoing') || detail.includes('مستمرة') + ? novelStatus_1.NovelStatus.Ongoing + : novelStatus_1.NovelStatus.Completed; + break; + } + }); + loadedCheerio('div.summary__content .code-block,script').remove(); + novel.summary = + loadedCheerio('div.summary__content').text().trim() || + loadedCheerio('#tab-manga-about').text().trim() || + loadedCheerio('.post-content_item h5:contains("Summary")').next().text().trim(); + if (!(((_a = this.options) === null || _a === void 0 ? void 0 : _a.useNewChapterEndpoint) !== true)) return [3 /*break*/, 3]; + novelId = loadedCheerio('.rating-post-id').attr('value') || + loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; + formData = new FormData(); + formData.append("action", "manga_get_chapters"); + formData.append("manga", novelId); + return [4 /*yield*/, (0, fetch_1.fetchApi)(this.site + 'wp-admin/admin-ajax.php', { + method: 'POST', + body: formData, + }) + .then(function (res) { return res.text(); })]; + case 2: + html = _b.sent(); + return [3 /*break*/, 5]; + case 3: return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl + 'ajax/chapters/', { method: 'POST' }) + .then(function (res) { return res.text(); })]; + case 4: + html = _b.sent(); + _b.label = 5; + case 5: + if (html !== '0') { + loadedCheerio = (0, cheerio_1.load)(html); + } + chapters = []; + loadedCheerio('.wp-manga-chapter').each(function () { + var chapterName = loadedCheerio(this).find('a').text().trim(); + var releaseDate = null; + releaseDate = loadedCheerio(this) + .find('span.chapter-release-date') + .text() + .trim(); + if (releaseDate) { + releaseDate = (0, parseMadaraDate_1.parseMadaraDate)(releaseDate); + } + else { + /** + * Insert current date + */ + releaseDate = (0, dayjs_1.default)().format('LL'); + } + var chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); + }); + novel.chapters = chapters.reverse(); + return [2 /*return*/, novel]; + } + }); + }); + }; + MadaraPlugin.prototype.parseChapter = function (chapterUrl) { + return __awaiter(this, void 0, void 0, function () { + var body, loadedCheerio, chapterText; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, (0, fetch_1.fetchApi)(chapterUrl).then(function (res) { return res.text(); })]; + case 1: + body = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + chapterText = loadedCheerio('.text-left').html() || + loadedCheerio('.text-right').html() || + loadedCheerio('.entry-content').html() || ""; + return [2 /*return*/, chapterText]; + } + }); + }); + }; + MadaraPlugin.prototype.searchNovels = function (searchTerm, pageNo) { + return __awaiter(this, void 0, void 0, function () { + var novels, url, body, loadedCheerio; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + novels = []; + url = this.site + "?s=" + searchTerm + "&post_type=wp-manga"; + return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })]; + case 1: + body = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.c-tabs-item__content').each(function () { + var novelName = loadedCheerio(this).find('.post-title').text().trim(); + var image = loadedCheerio(this).find('img'); + var novelCover = image.attr('data-src') || image.attr('src'); + var novelUrl = loadedCheerio(this) + .find('.post-title') + .find('a') + .attr('href') || ''; + var novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + novels.push(novel); + }); + return [2 /*return*/, novels]; + } + }); + }); + }; + MadaraPlugin.prototype.fetchImage = function (url) { + return __awaiter(this, void 0, void 0, function () { + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, (0, fetch_1.fetchFile)(url, {})]; + case 1: return [2 /*return*/, _a.sent()]; + } + }); + }); + }; + return MadaraPlugin; +}()); +var plugin = new MadaraPlugin({ "id": "teamxnovel", "sourceSite": "https://teamxnovel.com/", "sourceName": "TeamXNovel", "filters": [], "options": { "useNewChapterEndpoint": true, "lang": "Arabic" } }); +exports.default = plugin; diff --git a/.js/plugins/arabic/kolnovel.js b/.js/plugins/arabic/kolnovel.js new file mode 100644 index 0000000..c57ae46 --- /dev/null +++ b/.js/plugins/arabic/kolnovel.js @@ -0,0 +1,333 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __generator = (this && this.__generator) || function (thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (g && (g = 0, op[0] && (_ = 0)), _) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var cheerio_1 = require("cheerio"); +var fetch_1 = require("@libs/fetch"); +var filterInputs_1 = require("@libs/filterInputs"); +var KolNovel = /** @class */ (function () { + function KolNovel() { + this.id = "kolnovel"; + this.name = "KolNovel"; + this.icon = "multisrc/wpmangastream/icons/kolnovel.png"; + this.site = "https://kolnovel.lol/"; + this.version = "1.0.0"; + this.userAgent = ""; + this.cookieString = ""; + this.filters = [ + { + key: "order", + label: "ترتيب حسب", + values: [ + { label: "الإعداد الأولي", value: "" }, + { label: "A-Z", value: "title" }, + { label: "Z-A", value: "titlereverse" }, + { label: "أخر التحديثات", value: "update" }, + { label: "أخر ما تم إضافته", value: "latest" }, + { label: "الرائجة", value: "popular" }, + ], + inputType: filterInputs_1.FilterInputs.Picker, + }, + { + key: "status", + label: "الحالة", + values: [ + { label: "All", value: "" }, + { label: "Ongoing", value: "ongoing" }, + { label: "Hiatus", value: "hiatus" }, + { label: "Completed", value: "completed" }, + ], + inputType: filterInputs_1.FilterInputs.Picker, + }, + { + key: "type", + label: "النوع", + values: [ + { label: "إنجليزية", value: "english" }, + { label: "روايةلايت", value: "light-novel" }, + { label: "روايةويب", value: "web-novel" }, + { label: "صينية", value: "chinese" }, + { label: "عربية", value: "arabic" }, + { label: "كورية", value: "korean" }, + { label: "يابانية", value: "japanese" }, + ], + inputType: filterInputs_1.FilterInputs.Checkbox, + }, + { + key: "genres", + label: "تصنيف", + values: [ + { label: "Wuxia", value: "wuxia" }, + { label: "Xianxia", value: "xianxia" }, + { label: "XUANHUAN", value: "xuanhuan" }, + { label: "أكشن", value: "action" }, + { label: "إثارة", value: "excitement" }, + { label: "إنتقالالىعالمأخر", value: "isekai" }, + { label: "إيتشي", value: "etchi" }, + { label: "الخيالالعلمي", value: "sci-fi" }, + { label: "بوليسي", value: "policy" }, + { label: "تاريخي", value: "historical" }, + { label: "تحقيقات", value: "%d8%aa%d8%ad%d9%82%d9%8a%d9%82" }, + { label: "تقمصشخصيات", value: "rpg" }, + { label: "جريمة", value: "crime" }, + { label: "جوسى", value: "josei" }, + { label: "حريم", value: "harem" }, + { label: "حياةمدرسية", value: "school-life" }, + { label: "خيالي(فانتازيا)", value: "fantasy" }, + { label: "دراما", value: "drama" }, + { label: "رعب", value: "horror" }, + { label: "رومانسي", value: "romantic" }, + { label: "سحر", value: "magic" }, + { label: "سينن", value: "senen" }, + { label: "شريحةمنالحياة", value: "slice-of-life" }, + { label: "شوجو", value: "shojo" }, + { label: "شونين", value: "shonen" }, + { label: "طبي", value: "medical" }, + { label: "ظواهرخارقةللطبيعة", value: "supernatural" }, + { label: "غموض", value: "mysteries" }, + { label: "فنونالقتال", value: "martial-arts" }, + { label: "قوىخارقة", value: "superpower" }, + { label: "كوميدي", value: "comedy" }, + { label: "مأساوي", value: "tragedy" }, + { label: "مابعدالكارثة", value: "after-the-disaster" }, + { label: "مغامرة", value: "adventure" }, + { label: "ميكا", value: "mechanical" }, + { label: "ناضج", value: "mature" }, + { label: "نفسي", value: "psychological" }, + ], + inputType: filterInputs_1.FilterInputs.Checkbox, + }, + ]; + } + KolNovel.prototype.popularNovels = function (pageNo, _a) { + var filters = _a.filters; + return __awaiter(this, void 0, void 0, function () { + var link, headers, body, loadedCheerio, novels; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + link = "".concat(this.site, "series/?page=").concat(pageNo); + if (filters) { + if (Array.isArray(filters.genres) && filters.genres.length) { + link += filters.genres.map(function (i) { return "&genre[]=".concat(i); }).join(""); + } + if (Array.isArray(filters.type) && filters.type.length) + link += filters.type.map(function (i) { return "&lang[]=".concat(i); }).join(""); + } + link += "&status=" + ((filters === null || filters === void 0 ? void 0 : filters.status) ? filters.status : ""); + link += "&order=" + ((filters === null || filters === void 0 ? void 0 : filters.order) ? filters.order : "popular"); + headers = new Headers(); + if (this.cookieString) { + headers.append("cookie", this.cookieString); + } + return [4 /*yield*/, (0, fetch_1.fetchApi)(link, { headers: headers }).then(function (result) { + return result.text(); + })]; + case 1: + body = _b.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + novels = []; + loadedCheerio("article.maindet").each(function () { + var novelName = loadedCheerio(this).find("h2").text(); + var image = loadedCheerio(this).find("img"); + var novelCover = image.attr("data-src") || image.attr("src"); + var novelUrl = loadedCheerio(this).find("h2 a").attr("href"); + if (!novelUrl) + return; + var novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + novels.push(novel); + }); + return [2 /*return*/, novels]; + } + }); + }); + }; + KolNovel.prototype.parseNovelAndChapters = function (novelUrl) { + return __awaiter(this, void 0, void 0, function () { + var url, headers, result, body, loadedCheerio, novel, chapter; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + url = novelUrl; + headers = new Headers(); + if (this.cookieString) { + headers.append("cookie", this.cookieString); + } + return [4 /*yield*/, fetch(url, { headers: headers })]; + case 1: + result = _a.sent(); + return [4 /*yield*/, result.text()]; + case 2: + body = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + novel = { + url: url, + chapters: [], + }; + novel.name = loadedCheerio("h1.entry-title").text(); + novel.cover = + loadedCheerio("img.wp-post-image").attr("data-src") || + loadedCheerio("img.wp-post-image").attr("src"); + loadedCheerio("div.serl:nth-child(3) > span").each(function () { + var detailName = loadedCheerio(this).text().trim(); + var detail = loadedCheerio(this).next().text().trim(); + switch (detailName) { + case "الكاتب": + case "Author": + novel.author = detail; + break; + } + }); + novel.status = loadedCheerio("div.sertostat > span").attr("class"); + novel.genres = loadedCheerio(".sertogenre") + .children("a") + .map(function (i, el) { return loadedCheerio(el).text(); }) + .toArray() + .join(","); + novel.summary = loadedCheerio(".sersys") + .find("br") + .replaceWith("\n") + .end() + .text(); + chapter = []; + loadedCheerio(".eplister") + .find("li") + .each(function () { + var chapterName = loadedCheerio(this).find(".epl-num").text() + + " - " + + loadedCheerio(this).find(".epl-title").text(); + var releaseDate = loadedCheerio(this) + .find(".epl-date") + .text() + .trim(); + var chapterUrl = loadedCheerio(this).find("a").attr("href"); + if (!chapterUrl) + return; + chapter.push({ + name: chapterName, + releaseTime: releaseDate, + url: chapterUrl, + }); + }); + novel.chapters = chapter.reverse(); + return [2 /*return*/, novel]; + } + }); + }); + }; + KolNovel.prototype.parseChapter = function (chapterUrl) { + var _a; + return __awaiter(this, void 0, void 0, function () { + var headers, result, body, loadedCheerio, ignore, chapterText; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + headers = new Headers(); + if (this.cookieString) { + headers.append("cookie", this.cookieString); + } + return [4 /*yield*/, fetch(chapterUrl, { headers: headers })]; + case 1: + result = _b.sent(); + return [4 /*yield*/, result.text()]; + case 2: + body = _b.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.epcontent > div, i').remove(); + ignore = loadedCheerio('article > style').text().trim().split(','); + ignore.push.apply(ignore, (((_a = ignore.pop()) === null || _a === void 0 ? void 0 : _a.match(/^\.\w+/)) || [])); + ignore.map(function (tag) { return loadedCheerio("p".concat(tag)).remove(); }); + chapterText = loadedCheerio('.epcontent').html() || ""; + return [2 /*return*/, chapterText]; + } + }); + }); + }; + KolNovel.prototype.searchNovels = function (searchTerm, pageNo) { + return __awaiter(this, void 0, void 0, function () { + var url, headers, result, body, loadedCheerio, novels; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + url = "".concat(this.site, "?s=").concat(searchTerm); + headers = new Headers(); + if (this.cookieString) { + headers.append("cookie", this.cookieString); + } + return [4 /*yield*/, (0, fetch_1.fetchApi)(url, { headers: headers })]; + case 1: + result = _a.sent(); + return [4 /*yield*/, result.text()]; + case 2: + body = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + novels = []; + loadedCheerio("article.maindet").each(function () { + var novelName = loadedCheerio(this).find("h2").text(); + var image = loadedCheerio(this).find("img"); + var novelCover = image.attr("data-src") || image.attr("src"); + var novelUrl = loadedCheerio(this).find("h2 a").attr("href"); + if (!novelUrl) + return; + novels.push({ + name: novelName, + url: novelUrl, + cover: novelCover, + }); + }); + return [2 /*return*/, novels]; + } + }); + }); + }; + KolNovel.prototype.fetchImage = function (url) { + return __awaiter(this, void 0, void 0, function () { + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, (0, fetch_1.fetchFile)(url)]; + case 1: return [2 /*return*/, _a.sent()]; + } + }); + }); + }; + return KolNovel; +}()); +exports.default = new KolNovel(); diff --git a/.js/plugins/chinese/linovelib.js b/.js/plugins/chinese/linovelib.js new file mode 100644 index 0000000..9266697 --- /dev/null +++ b/.js/plugins/chinese/linovelib.js @@ -0,0 +1,525 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __generator = (this && this.__generator) || function (thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (g && (g = 0, op[0] && (_ = 0)), _) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var cheerio_1 = require("cheerio"); +var fetch_1 = require("@libs/fetch"); +var filterInputs_1 = require("@libs/filterInputs"); +var showToast_1 = require("@libs/showToast"); +var Linovelib = /** @class */ (function () { + function Linovelib() { + this.id = "linovelib"; + this.name = "Linovelib"; + this.icon = "src/cn/linovelib/icon.png"; + this.site = "https://w.linovelib.com"; + this.version = "1.0.0"; + this.userAgent = ""; + this.cookieString = ""; + this.filters = [ + { + key: "sort", + label: "Sort By", + values: [ + { label: "月点击榜", value: "monthvisit" }, + { label: "周点击榜", value: "weekvisit" }, + { label: "月推荐榜", value: "monthvote" }, + { label: "周推荐榜", value: "weekvote" }, + { label: "月鲜花榜", value: "monthflower" }, + { label: "周鲜花榜", value: "weekflower" }, + { label: "月鸡蛋榜", value: "monthegg" }, + { label: "周鸡蛋榜", value: "weekegg" }, + { label: "最近更新", value: "lastupdate" }, + { label: "最新入库", value: "postdate" }, + { label: "收藏榜", value: "goodnum" }, + { label: "新书榜", value: "newhot" }, + ], + inputType: filterInputs_1.FilterInputs.Picker, + }, + ]; + } + Linovelib.prototype.popularNovels = function (pageNo, _a) { + var filters = _a.filters; + return __awaiter(this, void 0, void 0, function () { + var link, headers, body, loadedCheerio, novels; + var _this = this; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + link = "".concat(this.site, "/top/"); + link += ((filters === null || filters === void 0 ? void 0 : filters.sort) ? filters.sort : "monthvisit"); + link += "/".concat(pageNo, ".html"); + headers = new Headers(); + if (this.cookieString) { + headers.append("cookie", this.cookieString); + } + return [4 /*yield*/, (0, fetch_1.fetchApi)(link, { headers: headers }).then(function (result) { + return result.text(); + })]; + case 1: + body = _b.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + novels = []; + loadedCheerio(".module-rank-booklist .book-layout").each(function (i, el) { + var url = loadedCheerio(el).attr('href'); + var novelName = loadedCheerio(el).find('.book-title').text(); + var novelCover = loadedCheerio(el) + .find('img.book-cover') + .attr('data-src'); + var novelUrl = _this.site + url; + if (!url) + return; + var novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + novels.push(novel); + }); + return [2 /*return*/, novels]; + } + }); + }); + }; + ; + Linovelib.prototype.parseNovelAndChapters = function (novelUrl) { + var _a; + return __awaiter(this, void 0, void 0, function () { + var url, headers, result, body, loadedCheerio, novel, chapter, idPattern, novelId, chaptersUrl, chaptersResult, chaptersBody, chaptersLoadedCheerio, volumeName, chapterId; + var _this = this; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + url = novelUrl; + headers = new Headers(); + if (this.cookieString) { + headers.append("cookie", this.cookieString); + } + return [4 /*yield*/, (0, fetch_1.fetchApi)(url, { headers: headers })]; + case 1: + result = _b.sent(); + return [4 /*yield*/, result.text()]; + case 2: + body = _b.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + novel = { + url: url, + chapters: [], + }; + novel.name = loadedCheerio('#bookDetailWrapper .book-title').text(); + novel.cover = loadedCheerio('#bookDetailWrapper img.book-cover').attr('src'); + novel.summary = loadedCheerio('#bookSummary content').text(); + novel.author = loadedCheerio('#bookDetailWrapper .book-rand-a a').text(); + // TODO: Need some regex and dirty selector to get it + // Need to look into how to translate that message + novel.status = undefined; + novel.genres = loadedCheerio('.tag-small.red') + .children("a") + .map(function (i, el) { return loadedCheerio(el).text(); }) + .toArray() + .join(","); + chapter = []; + idPattern = /\/(\d+)\.html/; + novelId = (_a = url.match(idPattern)) === null || _a === void 0 ? void 0 : _a[1]; + chaptersUrl = this.site + loadedCheerio('#btnReadBook').attr('href'); + return [4 /*yield*/, (0, fetch_1.fetchApi)(chaptersUrl, { headers: headers })]; + case 3: + chaptersResult = _b.sent(); + return [4 /*yield*/, chaptersResult.text()]; + case 4: + chaptersBody = _b.sent(); + chaptersLoadedCheerio = (0, cheerio_1.load)(chaptersBody); + chaptersLoadedCheerio('#volumes .chapter-li').each(function (i, el) { + if (chaptersLoadedCheerio(el).hasClass('chapter-bar')) { + volumeName = chaptersLoadedCheerio(el).text(); + } + else { + var urlPart = chaptersLoadedCheerio(el) + .find('.chapter-li-a') + .attr('href'); + var chapterIdMatch = urlPart === null || urlPart === void 0 ? void 0 : urlPart.match(idPattern); + // Sometimes the href attribute does not contain the url, but javascript:cid(0). + // Increment the previous chapter ID should result in the right URL + if (chapterIdMatch) { + chapterId = +chapterIdMatch[1]; + } + else { + chapterId++; + } + } + var chapterUrl = "".concat(_this.site, "/novel/").concat(novelId, "/").concat(chapterId, ".html"); + var chapterName = volumeName + + ' — ' + + chaptersLoadedCheerio(el).find('.chapter-index').text().trim(); + var releaseDate = null; + if (!chapterId) + return; + chapter.push({ + name: chapterName, + releaseTime: releaseDate, + url: chapterUrl, + }); + }); + novel.chapters = chapter; + return [2 /*return*/, novel]; + } + }); + }); + }; + Linovelib.prototype.parseChapter = function (chapterUrl) { + return __awaiter(this, void 0, void 0, function () { + var headers, chapterName, chapterText, hasNextPage, pageHasNextPage, pageText, pageNumber, skillgg, addPage, loadPage, url, page; + var _this = this; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + headers = new Headers(); + if (this.cookieString) { + headers.append("cookie", this.cookieString); + } + chapterText = "", pageText = ""; + pageNumber = 1; + skillgg = { + '\u201c': '\u300c', + '\u201d': '\u300d', + '\u2018': '\u300e', + '\u2019': '\u300f', + '\ue82c': '\u7684', + '\ue852': '\u4e00', + '\ue82d': '\u662f', + '\ue819': '\u4e86', + '\ue856': '\u6211', + '\ue857': '\u4e0d', + '\ue816': '\u4eba', + '\ue83c': '\u5728', + '\ue830': '\u4ed6', + '\ue82e': '\u6709', + '\ue836': '\u8fd9', + '\ue859': '\u4e2a', + '\ue80a': '\u4e0a', + '\ue855': '\u4eec', + '\ue842': '\u6765', + '\ue858': '\u5230', + '\ue80b': '\u65f6', + '\ue81f': '\u5927', + '\ue84a': '\u5730', + '\ue853': '\u4e3a', + '\ue81e': '\u5b50', + '\ue822': '\u4e2d', + '\ue813': '\u4f60', + '\ue85b': '\u8bf4', + '\ue807': '\u751f', + '\ue818': '\u56fd', + '\ue810': '\u5e74', + '\ue812': '\u7740', + '\ue851': '\u5c31', + '\ue801': '\u90a3', + '\ue80c': '\u548c', + '\ue815': '\u8981', + '\ue84c': '\u5979', + '\ue840': '\u51fa', + '\ue848': '\u4e5f', + '\ue835': '\u5f97', + '\ue800': '\u91cc', + '\ue826': '\u540e', + '\ue863': '\u81ea', + '\ue861': '\u4ee5', + '\ue854': '\u4f1a', + '\ue827': '\u5bb6', + '\ue83b': '\u53ef', + '\ue85d': '\u4e0b', + '\ue84d': '\u800c', + '\ue862': '\u8fc7', + '\ue81c': '\u5929', + '\ue81d': '\u53bb', + '\ue860': '\u80fd', + '\ue843': '\u5bf9', + '\ue82f': '\u5c0f', + '\ue802': '\u591a', + '\ue831': '\u7136', + '\ue84b': '\u4e8e', + '\ue837': '\u5fc3', + '\ue829': '\u5b66', + '\ue85e': '\u4e48', + '\ue83a': '\u4e4b', + '\ue832': '\u90fd', + '\ue808': '\u597d', + '\ue841': '\u770b', + '\ue821': '\u8d77', + '\ue845': '\u53d1', + '\ue803': '\u5f53', + '\ue828': '\u6ca1', + '\ue81b': '\u6210', + '\ue83e': '\u53ea', + '\ue820': '\u5982', + '\ue84e': '\u4e8b', + '\ue85a': '\u628a', + '\ue806': '\u8fd8', + '\ue83f': '\u7528', + '\ue833': '\u7b2c', + '\ue811': '\u6837', + '\ue804': '\u9053', + '\ue814': '\u60f3', + '\ue80f': '\u4f5c', + '\ue84f': '\u79cd', + '\ue80e': '\u5f00', + '\ue823': '\u7f8e', + '\ue849': '\u4e73', + '\ue805': '\u9634', + '\ue809': '\u6db2', + '\ue81a': '\u830e', + '\ue844': '\u6b32', + '\ue847': '\u547b', + '\ue850': '\u8089', + '\ue824': '\u4ea4', + '\ue85f': '\u6027', + '\ue817': '\u80f8', + '\ue85c': '\u79c1', + '\ue838': '\u7a74', + '\ue82a': '\u6deb', + '\ue83d': '\u81c0', + '\ue82b': '\u8214', + '\ue80d': '\u5c04', + '\ue839': '\u8131', + '\ue834': '\u88f8', + '\ue846': '\u9a9a', + '\ue825': '\u5507', + }; + addPage = function (pageCheerio) { return __awaiter(_this, void 0, void 0, function () { + var formatPage; + var _this = this; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + formatPage = function () { return __awaiter(_this, void 0, void 0, function () { + return __generator(this, function (_a) { + // Remove JS + pageCheerio('#ccacontent .cgo').remove(); + // Load lazyloaded images + pageCheerio('#ccacontent img.imagecontent').each(function (i, el) { + // Sometimes images are either in data-src or src + var imgSrc = pageCheerio(el).attr('data-src') || pageCheerio(el).attr('src'); + if (imgSrc) { + // The original CDN URL is locked behind a CF-like challenge, switch the URL to bypass that + // There are no react-native-url-polyfill lib, can't use URL API + var regex = /\/\/.+\.com\//; + var imgUrl = imgSrc.replace(regex, '//img.linovelib.com/'); + // Clean up img element + pageCheerio(el) + .attr('src', imgUrl) + .removeAttr('data-src') + .removeClass('lazyload'); + } + }); + // Recover the original character + pageText = pageCheerio('#ccacontent').html() || ""; + pageText = pageText.replace(/./g, function (char) { return skillgg[char] || char; }); + return [2 /*return*/, Promise.resolve()]; + }); + }); }; + return [4 /*yield*/, formatPage()]; + case 1: + _a.sent(); + chapterName = + pageCheerio('#atitle + h3').text() + + ' — ' + + pageCheerio('#atitle').text(); + if (chapterText === "") { + chapterText = '

' + chapterName + '

'; + } + chapterText += pageText; + return [2 /*return*/]; + } + }); + }); }; + loadPage = function (url) { return __awaiter(_this, void 0, void 0, function () { + var result, body, pageCheerio; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, (0, fetch_1.fetchApi)(url, { headers: headers })]; + case 1: + result = _a.sent(); + return [4 /*yield*/, result.text()]; + case 2: + body = _a.sent(); + pageCheerio = (0, cheerio_1.load)(body); + return [4 /*yield*/, addPage(pageCheerio)]; + case 3: + _a.sent(); + pageHasNextPage = + pageCheerio('#footlink a:last').text() === '下一页' ? true : false; + return [2 /*return*/, { pageCheerio: pageCheerio, pageHasNextPage: pageHasNextPage }]; + } + }); + }); }; + url = chapterUrl; + _a.label = 1; + case 1: return [4 /*yield*/, loadPage(url)]; + case 2: + page = _a.sent(); + hasNextPage = page.pageHasNextPage; + if (hasNextPage === true) { + pageNumber++; + url = chapterUrl.replace(/\.html/gi, "_".concat(pageNumber) + '.html'); + } + _a.label = 3; + case 3: + if (hasNextPage === true) return [3 /*break*/, 1]; + _a.label = 4; + case 4: return [2 /*return*/, chapterText]; + } + }); + }); + }; + Linovelib.prototype.searchNovels = function (searchTerm, pageNo) { + return __awaiter(this, void 0, void 0, function () { + var searchUrl, Term, headers, NextPage, NoNextPage, DeadEnd, novels, addPage, loadPage, url, page; + var _this = this; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + searchUrl = "".concat(this.site, "/search/"); + Term = encodeURI(searchTerm); + headers = new Headers(); + if (this.cookieString) { + headers.append("cookie", this.cookieString); + } + pageNo = 1; + novels = []; + addPage = function (pageCheerio, redirect) { return __awaiter(_this, void 0, void 0, function () { + var loadSearchResults, novelResults, novelName, novelCover, novelUrl; + var _this = this; + var _a; + return __generator(this, function (_b) { + loadSearchResults = function () { + pageCheerio('.book-ol .book-layout').each(function (i, el) { + var nUrl = pageCheerio(el).attr('href'); + var novelName = pageCheerio(el).find('.book-title').text(); + var novelCover = pageCheerio(el) + .find('img.book-cover') + .attr('data-src'); + var novelUrl = _this.site + nUrl; + if (!nUrl) + return; + novels.push({ + name: novelName, + url: novelUrl, + cover: novelCover, + }); + }); + }; + novelResults = pageCheerio('.book-ol a.book-layout'); + if (novelResults.length === 0) { + (0, showToast_1.showToast)('Bypass check by searching in Webview'); + } + else { + loadSearchResults(); + } + if (redirect.length) { + novels.length = 0; + novelName = pageCheerio('#bookDetailWrapper .book-title').text(); + novelCover = pageCheerio('#bookDetailWrapper img.book-cover').attr('src'); + novelUrl = this.site + + ((_a = pageCheerio('#btnReadBook').attr('href')) === null || _a === void 0 ? void 0 : _a.slice(0, -8)) + + '.html'; + novels.push({ + name: novelName, + url: novelUrl, + cover: novelCover, + }); + } + return [2 /*return*/]; + }); + }); }; + loadPage = function (url) { return __awaiter(_this, void 0, void 0, function () { + var result, body, pageCheerio, redirect; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, (0, fetch_1.fetchApi)(url, { headers: headers })]; + case 1: + result = _a.sent(); + return [4 /*yield*/, result.text()]; + case 2: + body = _a.sent(); + pageCheerio = (0, cheerio_1.load)(body); + redirect = pageCheerio('div.book-layout').text(); + return [4 /*yield*/, addPage(pageCheerio, redirect)]; + case 3: + _a.sent(); + NextPage = pageCheerio('.next').attr('href'); + if (!NextPage) { + NoNextPage === true; + } + else { + NoNextPage = NextPage === '#' ? true : false; + } + return [2 /*return*/, { pageCheerio: pageCheerio, NoNextPage: NoNextPage }]; + } + }); + }); }; + url = "".concat(searchUrl).concat(Term, "_").concat(pageNo, ".html"); + _a.label = 1; + case 1: return [4 /*yield*/, loadPage(url)]; + case 2: + page = _a.sent(); + DeadEnd = page.NoNextPage; + if (DeadEnd === false) { + pageNo++; + url = "".concat(searchUrl).concat(Term, "_").concat(pageNo, ".html"); + } + _a.label = 3; + case 3: + if (DeadEnd === false) return [3 /*break*/, 1]; + _a.label = 4; + case 4: return [2 /*return*/, novels]; + } + }); + }); + }; + ; + Linovelib.prototype.fetchImage = function (url) { + return __awaiter(this, void 0, void 0, function () { + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, (0, fetch_1.fetchFile)(url)]; + case 1: return [2 /*return*/, _a.sent()]; + } + }); + }); + }; + return Linovelib; +}()); +exports.default = new Linovelib(); diff --git a/.js/plugins/english/BoxNovel[madara].js b/.js/plugins/english/BoxNovel[madara].js new file mode 100644 index 0000000..f8b862d --- /dev/null +++ b/.js/plugins/english/BoxNovel[madara].js @@ -0,0 +1,269 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __generator = (this && this.__generator) || function (thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (g && (g = 0, op[0] && (_ = 0)), _) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +}; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var fetch_1 = require("@libs/fetch"); +var cheerio_1 = require("cheerio"); +var defaultCover_1 = require("@libs/defaultCover"); +var novelStatus_1 = require("@libs/novelStatus"); +var parseMadaraDate_1 = require("@libs/parseMadaraDate"); +var dayjs_1 = __importDefault(require("dayjs")); +var MadaraDefaultPath = { + novels: 'novel', + novel: 'novel', + chapter: 'novel' +}; +var MadaraPlugin = /** @class */ (function () { + function MadaraPlugin(metadata) { + this.id = metadata.id; + this.name = metadata.sourceName + "[madara]"; + var iconFileName = metadata.sourceName.replace(/\s+/g, "").toLowerCase(); + this.icon = "multisrc/madara/icons/".concat(iconFileName, ".png"); + this.site = metadata.sourceSite; + this.version = "1.0.0"; + this.userAgent = ""; + this.cookieString = ""; + this.options = metadata.options; + this.filter = metadata.filters; + } + MadaraPlugin.prototype.popularNovels = function (pageNo, _a) { + var _b, _c, _d, _e, _f, _g; + var filters = _a.filters, showLatestNovels = _a.showLatestNovels; + return __awaiter(this, void 0, void 0, function () { + var novels, url, body, loadedCheerio; + return __generator(this, function (_h) { + switch (_h.label) { + case 0: + novels = []; + url = this.site; + if ((filters === null || filters === void 0 ? void 0 : filters.genres) && ((_c = (_b = this.options) === null || _b === void 0 ? void 0 : _b.path) === null || _c === void 0 ? void 0 : _c.genres)) { + url += ((_e = (_d = this.options) === null || _d === void 0 ? void 0 : _d.path) === null || _e === void 0 ? void 0 : _e.genres) + filters.genres + '/'; + } + else { + url += ((_g = (_f = this.options) === null || _f === void 0 ? void 0 : _f.path) === null || _g === void 0 ? void 0 : _g.novels) ? this.options.path.novels : MadaraDefaultPath.novels; + } + url += '/page/' + pageNo + '/' + + '?m_orderby=' + (showLatestNovels ? 'latest' : ((filters === null || filters === void 0 ? void 0 : filters.sort) || 'rating')); + return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })]; + case 1: + body = _h.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.manga-title-badges').remove(); + loadedCheerio('.page-item-detail').each(function () { + var novelName = loadedCheerio(this).find('.post-title').text().trim(); + var image = loadedCheerio(this).find('img'); + var novelCover = image.attr('data-src') || image.attr('src'); + var novelUrl = loadedCheerio(this).find('.post-title') + .find('a') + .attr('href') || ''; + var novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + novels.push(novel); + }); + return [2 /*return*/, novels]; + } + }); + }); + }; + MadaraPlugin.prototype.parseNovelAndChapters = function (novelUrl) { + var _a; + return __awaiter(this, void 0, void 0, function () { + var novel, body, loadedCheerio, html, novelId, formData, chapters; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + novel = { + url: novelUrl, + }; + return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl).then(function (res) { return res.text(); })]; + case 1: + body = _b.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.manga-title-badges, #manga-title span').remove(); + novel.name = + loadedCheerio('.post-title h1').text().trim() || + loadedCheerio('#manga-title h1').text(); + novel.cover = + loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || + loadedCheerio('.summary_image > a > img').attr('data-src') || + loadedCheerio('.summary_image > a > img').attr('src') || + defaultCover_1.defaultCover; + loadedCheerio('.post-content_item, .post-content').each(function () { + var detailName = loadedCheerio(this).find('h5').text().trim(); + var detail = loadedCheerio(this).find('.summary-content').text().trim(); + switch (detailName) { + case 'Genre(s)': + case 'التصنيفات': + novel.genres = detail.replace(/[\\t\\n]/g, ','); + break; + case 'Author(s)': + case 'المؤلف': + case 'المؤلف (ين)': + novel.author = detail; + break; + case 'Status': + case 'الحالة': + novel.status = + detail.includes('OnGoing') || detail.includes('مستمرة') + ? novelStatus_1.NovelStatus.Ongoing + : novelStatus_1.NovelStatus.Completed; + break; + } + }); + loadedCheerio('div.summary__content .code-block,script').remove(); + novel.summary = + loadedCheerio('div.summary__content').text().trim() || + loadedCheerio('#tab-manga-about').text().trim() || + loadedCheerio('.post-content_item h5:contains("Summary")').next().text().trim(); + if (!(((_a = this.options) === null || _a === void 0 ? void 0 : _a.useNewChapterEndpoint) !== true)) return [3 /*break*/, 3]; + novelId = loadedCheerio('.rating-post-id').attr('value') || + loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; + formData = new FormData(); + formData.append("action", "manga_get_chapters"); + formData.append("manga", novelId); + return [4 /*yield*/, (0, fetch_1.fetchApi)(this.site + 'wp-admin/admin-ajax.php', { + method: 'POST', + body: formData, + }) + .then(function (res) { return res.text(); })]; + case 2: + html = _b.sent(); + return [3 /*break*/, 5]; + case 3: return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl + 'ajax/chapters/', { method: 'POST' }) + .then(function (res) { return res.text(); })]; + case 4: + html = _b.sent(); + _b.label = 5; + case 5: + if (html !== '0') { + loadedCheerio = (0, cheerio_1.load)(html); + } + chapters = []; + loadedCheerio('.wp-manga-chapter').each(function () { + var chapterName = loadedCheerio(this).find('a').text().trim(); + var releaseDate = null; + releaseDate = loadedCheerio(this) + .find('span.chapter-release-date') + .text() + .trim(); + if (releaseDate) { + releaseDate = (0, parseMadaraDate_1.parseMadaraDate)(releaseDate); + } + else { + /** + * Insert current date + */ + releaseDate = (0, dayjs_1.default)().format('LL'); + } + var chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); + }); + novel.chapters = chapters.reverse(); + return [2 /*return*/, novel]; + } + }); + }); + }; + MadaraPlugin.prototype.parseChapter = function (chapterUrl) { + return __awaiter(this, void 0, void 0, function () { + var body, loadedCheerio, chapterText; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, (0, fetch_1.fetchApi)(chapterUrl).then(function (res) { return res.text(); })]; + case 1: + body = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + chapterText = loadedCheerio('.text-left').html() || + loadedCheerio('.text-right').html() || + loadedCheerio('.entry-content').html() || ""; + return [2 /*return*/, chapterText]; + } + }); + }); + }; + MadaraPlugin.prototype.searchNovels = function (searchTerm, pageNo) { + return __awaiter(this, void 0, void 0, function () { + var novels, url, body, loadedCheerio; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + novels = []; + url = this.site + "?s=" + searchTerm + "&post_type=wp-manga"; + return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })]; + case 1: + body = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.c-tabs-item__content').each(function () { + var novelName = loadedCheerio(this).find('.post-title').text().trim(); + var image = loadedCheerio(this).find('img'); + var novelCover = image.attr('data-src') || image.attr('src'); + var novelUrl = loadedCheerio(this) + .find('.post-title') + .find('a') + .attr('href') || ''; + var novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + novels.push(novel); + }); + return [2 /*return*/, novels]; + } + }); + }); + }; + MadaraPlugin.prototype.fetchImage = function (url) { + return __awaiter(this, void 0, void 0, function () { + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, (0, fetch_1.fetchFile)(url, {})]; + case 1: return [2 /*return*/, _a.sent()]; + } + }); + }); + }; + return MadaraPlugin; +}()); +var plugin = new MadaraPlugin({ "id": "boxnovel", "sourceSite": "https://boxnovel.com/", "sourceName": "BoxNovel", "filters": [{ "key": "sort", "label": "Order by", "values": [{ "label": "Rating", "value": "rating" }, { "label": "A-Z", "value": "alphabet" }, { "label": "Latest", "value": "latest" }, { "label": "Most Views", "value": "views" }, { "label": "New", "value": "new-manga" }, { "label": "Trending", "value": "trending" }], "inputType": "Picker" }, { "key": "genres", "label": "GENRES", "values": [{ "label": "Action", "value": "action" }, { "label": "Adventure", "value": "adventure" }, { "label": "Comedy", "value": "comedy" }, { "label": "Drama", "value": "drama" }, { "label": "Ecchi", "value": "ecchi" }, { "label": "Fantasy", "value": "fantasy" }, { "label": "Gender Bender", "value": "gender-bender" }, { "label": "Harem", "value": "harem" }, { "label": "Historical", "value": "historical" }, { "label": "Horror", "value": "horror" }, { "label": "Josei", "value": "josei" }, { "label": "Martial Arts", "value": "martial-arts" }, { "label": "Mature", "value": "mature" }, { "label": "Mecha", "value": "mecha" }, { "label": "Mystery", "value": "mystery" }, { "label": "Psychological", "value": "psychological" }, { "label": "Romance", "value": "romance" }, { "label": "School Life", "value": "school-life" }, { "label": "Sci-fi", "value": "sci-fi" }, { "label": "Seinen", "value": "seinen" }, { "label": "Shoujo", "value": "shoujo" }, { "label": "Shounen", "value": "shounen" }, { "label": "Slice of Life", "value": "slice-of-life" }, { "label": "Smut", "value": "smut" }, { "label": "Sports", "value": "sports" }, { "label": "Supernatural", "value": "supernatural" }, { "label": "Tragedy", "value": "tragedy" }, { "label": "Wuxia", "value": "wuxia" }, { "label": "Xianxia", "value": "xianxia" }, { "label": "Xuanhuan", "value": "xuanhuan" }, { "label": "Yaoi", "value": "yaoi" }], "inputType": "Picker" }], "options": { "path": { "genres": "manga-genre" }, "useNewChapterEndpoint": true, "lang": "English" } }); +exports.default = plugin; diff --git a/.js/plugins/english/ClickNovel[madara].js b/.js/plugins/english/ClickNovel[madara].js new file mode 100644 index 0000000..c766349 --- /dev/null +++ b/.js/plugins/english/ClickNovel[madara].js @@ -0,0 +1,269 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __generator = (this && this.__generator) || function (thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (g && (g = 0, op[0] && (_ = 0)), _) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +}; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var fetch_1 = require("@libs/fetch"); +var cheerio_1 = require("cheerio"); +var defaultCover_1 = require("@libs/defaultCover"); +var novelStatus_1 = require("@libs/novelStatus"); +var parseMadaraDate_1 = require("@libs/parseMadaraDate"); +var dayjs_1 = __importDefault(require("dayjs")); +var MadaraDefaultPath = { + novels: 'novel', + novel: 'novel', + chapter: 'novel' +}; +var MadaraPlugin = /** @class */ (function () { + function MadaraPlugin(metadata) { + this.id = metadata.id; + this.name = metadata.sourceName + "[madara]"; + var iconFileName = metadata.sourceName.replace(/\s+/g, "").toLowerCase(); + this.icon = "multisrc/madara/icons/".concat(iconFileName, ".png"); + this.site = metadata.sourceSite; + this.version = "1.0.0"; + this.userAgent = ""; + this.cookieString = ""; + this.options = metadata.options; + this.filter = metadata.filters; + } + MadaraPlugin.prototype.popularNovels = function (pageNo, _a) { + var _b, _c, _d, _e, _f, _g; + var filters = _a.filters, showLatestNovels = _a.showLatestNovels; + return __awaiter(this, void 0, void 0, function () { + var novels, url, body, loadedCheerio; + return __generator(this, function (_h) { + switch (_h.label) { + case 0: + novels = []; + url = this.site; + if ((filters === null || filters === void 0 ? void 0 : filters.genres) && ((_c = (_b = this.options) === null || _b === void 0 ? void 0 : _b.path) === null || _c === void 0 ? void 0 : _c.genres)) { + url += ((_e = (_d = this.options) === null || _d === void 0 ? void 0 : _d.path) === null || _e === void 0 ? void 0 : _e.genres) + filters.genres + '/'; + } + else { + url += ((_g = (_f = this.options) === null || _f === void 0 ? void 0 : _f.path) === null || _g === void 0 ? void 0 : _g.novels) ? this.options.path.novels : MadaraDefaultPath.novels; + } + url += '/page/' + pageNo + '/' + + '?m_orderby=' + (showLatestNovels ? 'latest' : ((filters === null || filters === void 0 ? void 0 : filters.sort) || 'rating')); + return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })]; + case 1: + body = _h.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.manga-title-badges').remove(); + loadedCheerio('.page-item-detail').each(function () { + var novelName = loadedCheerio(this).find('.post-title').text().trim(); + var image = loadedCheerio(this).find('img'); + var novelCover = image.attr('data-src') || image.attr('src'); + var novelUrl = loadedCheerio(this).find('.post-title') + .find('a') + .attr('href') || ''; + var novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + novels.push(novel); + }); + return [2 /*return*/, novels]; + } + }); + }); + }; + MadaraPlugin.prototype.parseNovelAndChapters = function (novelUrl) { + var _a; + return __awaiter(this, void 0, void 0, function () { + var novel, body, loadedCheerio, html, novelId, formData, chapters; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + novel = { + url: novelUrl, + }; + return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl).then(function (res) { return res.text(); })]; + case 1: + body = _b.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.manga-title-badges, #manga-title span').remove(); + novel.name = + loadedCheerio('.post-title h1').text().trim() || + loadedCheerio('#manga-title h1').text(); + novel.cover = + loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || + loadedCheerio('.summary_image > a > img').attr('data-src') || + loadedCheerio('.summary_image > a > img').attr('src') || + defaultCover_1.defaultCover; + loadedCheerio('.post-content_item, .post-content').each(function () { + var detailName = loadedCheerio(this).find('h5').text().trim(); + var detail = loadedCheerio(this).find('.summary-content').text().trim(); + switch (detailName) { + case 'Genre(s)': + case 'التصنيفات': + novel.genres = detail.replace(/[\\t\\n]/g, ','); + break; + case 'Author(s)': + case 'المؤلف': + case 'المؤلف (ين)': + novel.author = detail; + break; + case 'Status': + case 'الحالة': + novel.status = + detail.includes('OnGoing') || detail.includes('مستمرة') + ? novelStatus_1.NovelStatus.Ongoing + : novelStatus_1.NovelStatus.Completed; + break; + } + }); + loadedCheerio('div.summary__content .code-block,script').remove(); + novel.summary = + loadedCheerio('div.summary__content').text().trim() || + loadedCheerio('#tab-manga-about').text().trim() || + loadedCheerio('.post-content_item h5:contains("Summary")').next().text().trim(); + if (!(((_a = this.options) === null || _a === void 0 ? void 0 : _a.useNewChapterEndpoint) !== true)) return [3 /*break*/, 3]; + novelId = loadedCheerio('.rating-post-id').attr('value') || + loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; + formData = new FormData(); + formData.append("action", "manga_get_chapters"); + formData.append("manga", novelId); + return [4 /*yield*/, (0, fetch_1.fetchApi)(this.site + 'wp-admin/admin-ajax.php', { + method: 'POST', + body: formData, + }) + .then(function (res) { return res.text(); })]; + case 2: + html = _b.sent(); + return [3 /*break*/, 5]; + case 3: return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl + 'ajax/chapters/', { method: 'POST' }) + .then(function (res) { return res.text(); })]; + case 4: + html = _b.sent(); + _b.label = 5; + case 5: + if (html !== '0') { + loadedCheerio = (0, cheerio_1.load)(html); + } + chapters = []; + loadedCheerio('.wp-manga-chapter').each(function () { + var chapterName = loadedCheerio(this).find('a').text().trim(); + var releaseDate = null; + releaseDate = loadedCheerio(this) + .find('span.chapter-release-date') + .text() + .trim(); + if (releaseDate) { + releaseDate = (0, parseMadaraDate_1.parseMadaraDate)(releaseDate); + } + else { + /** + * Insert current date + */ + releaseDate = (0, dayjs_1.default)().format('LL'); + } + var chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); + }); + novel.chapters = chapters.reverse(); + return [2 /*return*/, novel]; + } + }); + }); + }; + MadaraPlugin.prototype.parseChapter = function (chapterUrl) { + return __awaiter(this, void 0, void 0, function () { + var body, loadedCheerio, chapterText; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, (0, fetch_1.fetchApi)(chapterUrl).then(function (res) { return res.text(); })]; + case 1: + body = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + chapterText = loadedCheerio('.text-left').html() || + loadedCheerio('.text-right').html() || + loadedCheerio('.entry-content').html() || ""; + return [2 /*return*/, chapterText]; + } + }); + }); + }; + MadaraPlugin.prototype.searchNovels = function (searchTerm, pageNo) { + return __awaiter(this, void 0, void 0, function () { + var novels, url, body, loadedCheerio; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + novels = []; + url = this.site + "?s=" + searchTerm + "&post_type=wp-manga"; + return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })]; + case 1: + body = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.c-tabs-item__content').each(function () { + var novelName = loadedCheerio(this).find('.post-title').text().trim(); + var image = loadedCheerio(this).find('img'); + var novelCover = image.attr('data-src') || image.attr('src'); + var novelUrl = loadedCheerio(this) + .find('.post-title') + .find('a') + .attr('href') || ''; + var novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + novels.push(novel); + }); + return [2 /*return*/, novels]; + } + }); + }); + }; + MadaraPlugin.prototype.fetchImage = function (url) { + return __awaiter(this, void 0, void 0, function () { + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, (0, fetch_1.fetchFile)(url, {})]; + case 1: return [2 /*return*/, _a.sent()]; + } + }); + }); + }; + return MadaraPlugin; +}()); +var plugin = new MadaraPlugin({ "id": "clicknovel", "sourceSite": "https://clicknovel.net/", "sourceName": "ClickNovel", "filters": [], "options": { "lang": "English" } }); +exports.default = plugin; diff --git a/.js/plugins/english/CrateNovel[madara].js b/.js/plugins/english/CrateNovel[madara].js new file mode 100644 index 0000000..c8c7bd7 --- /dev/null +++ b/.js/plugins/english/CrateNovel[madara].js @@ -0,0 +1,269 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __generator = (this && this.__generator) || function (thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (g && (g = 0, op[0] && (_ = 0)), _) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +}; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var fetch_1 = require("@libs/fetch"); +var cheerio_1 = require("cheerio"); +var defaultCover_1 = require("@libs/defaultCover"); +var novelStatus_1 = require("@libs/novelStatus"); +var parseMadaraDate_1 = require("@libs/parseMadaraDate"); +var dayjs_1 = __importDefault(require("dayjs")); +var MadaraDefaultPath = { + novels: 'novel', + novel: 'novel', + chapter: 'novel' +}; +var MadaraPlugin = /** @class */ (function () { + function MadaraPlugin(metadata) { + this.id = metadata.id; + this.name = metadata.sourceName + "[madara]"; + var iconFileName = metadata.sourceName.replace(/\s+/g, "").toLowerCase(); + this.icon = "multisrc/madara/icons/".concat(iconFileName, ".png"); + this.site = metadata.sourceSite; + this.version = "1.0.0"; + this.userAgent = ""; + this.cookieString = ""; + this.options = metadata.options; + this.filter = metadata.filters; + } + MadaraPlugin.prototype.popularNovels = function (pageNo, _a) { + var _b, _c, _d, _e, _f, _g; + var filters = _a.filters, showLatestNovels = _a.showLatestNovels; + return __awaiter(this, void 0, void 0, function () { + var novels, url, body, loadedCheerio; + return __generator(this, function (_h) { + switch (_h.label) { + case 0: + novels = []; + url = this.site; + if ((filters === null || filters === void 0 ? void 0 : filters.genres) && ((_c = (_b = this.options) === null || _b === void 0 ? void 0 : _b.path) === null || _c === void 0 ? void 0 : _c.genres)) { + url += ((_e = (_d = this.options) === null || _d === void 0 ? void 0 : _d.path) === null || _e === void 0 ? void 0 : _e.genres) + filters.genres + '/'; + } + else { + url += ((_g = (_f = this.options) === null || _f === void 0 ? void 0 : _f.path) === null || _g === void 0 ? void 0 : _g.novels) ? this.options.path.novels : MadaraDefaultPath.novels; + } + url += '/page/' + pageNo + '/' + + '?m_orderby=' + (showLatestNovels ? 'latest' : ((filters === null || filters === void 0 ? void 0 : filters.sort) || 'rating')); + return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })]; + case 1: + body = _h.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.manga-title-badges').remove(); + loadedCheerio('.page-item-detail').each(function () { + var novelName = loadedCheerio(this).find('.post-title').text().trim(); + var image = loadedCheerio(this).find('img'); + var novelCover = image.attr('data-src') || image.attr('src'); + var novelUrl = loadedCheerio(this).find('.post-title') + .find('a') + .attr('href') || ''; + var novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + novels.push(novel); + }); + return [2 /*return*/, novels]; + } + }); + }); + }; + MadaraPlugin.prototype.parseNovelAndChapters = function (novelUrl) { + var _a; + return __awaiter(this, void 0, void 0, function () { + var novel, body, loadedCheerio, html, novelId, formData, chapters; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + novel = { + url: novelUrl, + }; + return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl).then(function (res) { return res.text(); })]; + case 1: + body = _b.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.manga-title-badges, #manga-title span').remove(); + novel.name = + loadedCheerio('.post-title h1').text().trim() || + loadedCheerio('#manga-title h1').text(); + novel.cover = + loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || + loadedCheerio('.summary_image > a > img').attr('data-src') || + loadedCheerio('.summary_image > a > img').attr('src') || + defaultCover_1.defaultCover; + loadedCheerio('.post-content_item, .post-content').each(function () { + var detailName = loadedCheerio(this).find('h5').text().trim(); + var detail = loadedCheerio(this).find('.summary-content').text().trim(); + switch (detailName) { + case 'Genre(s)': + case 'التصنيفات': + novel.genres = detail.replace(/[\\t\\n]/g, ','); + break; + case 'Author(s)': + case 'المؤلف': + case 'المؤلف (ين)': + novel.author = detail; + break; + case 'Status': + case 'الحالة': + novel.status = + detail.includes('OnGoing') || detail.includes('مستمرة') + ? novelStatus_1.NovelStatus.Ongoing + : novelStatus_1.NovelStatus.Completed; + break; + } + }); + loadedCheerio('div.summary__content .code-block,script').remove(); + novel.summary = + loadedCheerio('div.summary__content').text().trim() || + loadedCheerio('#tab-manga-about').text().trim() || + loadedCheerio('.post-content_item h5:contains("Summary")').next().text().trim(); + if (!(((_a = this.options) === null || _a === void 0 ? void 0 : _a.useNewChapterEndpoint) !== true)) return [3 /*break*/, 3]; + novelId = loadedCheerio('.rating-post-id').attr('value') || + loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; + formData = new FormData(); + formData.append("action", "manga_get_chapters"); + formData.append("manga", novelId); + return [4 /*yield*/, (0, fetch_1.fetchApi)(this.site + 'wp-admin/admin-ajax.php', { + method: 'POST', + body: formData, + }) + .then(function (res) { return res.text(); })]; + case 2: + html = _b.sent(); + return [3 /*break*/, 5]; + case 3: return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl + 'ajax/chapters/', { method: 'POST' }) + .then(function (res) { return res.text(); })]; + case 4: + html = _b.sent(); + _b.label = 5; + case 5: + if (html !== '0') { + loadedCheerio = (0, cheerio_1.load)(html); + } + chapters = []; + loadedCheerio('.wp-manga-chapter').each(function () { + var chapterName = loadedCheerio(this).find('a').text().trim(); + var releaseDate = null; + releaseDate = loadedCheerio(this) + .find('span.chapter-release-date') + .text() + .trim(); + if (releaseDate) { + releaseDate = (0, parseMadaraDate_1.parseMadaraDate)(releaseDate); + } + else { + /** + * Insert current date + */ + releaseDate = (0, dayjs_1.default)().format('LL'); + } + var chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); + }); + novel.chapters = chapters.reverse(); + return [2 /*return*/, novel]; + } + }); + }); + }; + MadaraPlugin.prototype.parseChapter = function (chapterUrl) { + return __awaiter(this, void 0, void 0, function () { + var body, loadedCheerio, chapterText; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, (0, fetch_1.fetchApi)(chapterUrl).then(function (res) { return res.text(); })]; + case 1: + body = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + chapterText = loadedCheerio('.text-left').html() || + loadedCheerio('.text-right').html() || + loadedCheerio('.entry-content').html() || ""; + return [2 /*return*/, chapterText]; + } + }); + }); + }; + MadaraPlugin.prototype.searchNovels = function (searchTerm, pageNo) { + return __awaiter(this, void 0, void 0, function () { + var novels, url, body, loadedCheerio; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + novels = []; + url = this.site + "?s=" + searchTerm + "&post_type=wp-manga"; + return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })]; + case 1: + body = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.c-tabs-item__content').each(function () { + var novelName = loadedCheerio(this).find('.post-title').text().trim(); + var image = loadedCheerio(this).find('img'); + var novelCover = image.attr('data-src') || image.attr('src'); + var novelUrl = loadedCheerio(this) + .find('.post-title') + .find('a') + .attr('href') || ''; + var novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + novels.push(novel); + }); + return [2 /*return*/, novels]; + } + }); + }); + }; + MadaraPlugin.prototype.fetchImage = function (url) { + return __awaiter(this, void 0, void 0, function () { + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, (0, fetch_1.fetchFile)(url, {})]; + case 1: return [2 /*return*/, _a.sent()]; + } + }); + }); + }; + return MadaraPlugin; +}()); +var plugin = new MadaraPlugin({ "id": "cratenovel", "sourceSite": "https://cratenovel.com/", "sourceName": "CrateNovel", "filters": [], "options": { "useNewChapterEndpoint": true, "lang": "English" } }); +exports.default = plugin; diff --git a/.js/plugins/english/DaoNovel[madara].js b/.js/plugins/english/DaoNovel[madara].js new file mode 100644 index 0000000..b6b9db3 --- /dev/null +++ b/.js/plugins/english/DaoNovel[madara].js @@ -0,0 +1,269 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __generator = (this && this.__generator) || function (thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (g && (g = 0, op[0] && (_ = 0)), _) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +}; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var fetch_1 = require("@libs/fetch"); +var cheerio_1 = require("cheerio"); +var defaultCover_1 = require("@libs/defaultCover"); +var novelStatus_1 = require("@libs/novelStatus"); +var parseMadaraDate_1 = require("@libs/parseMadaraDate"); +var dayjs_1 = __importDefault(require("dayjs")); +var MadaraDefaultPath = { + novels: 'novel', + novel: 'novel', + chapter: 'novel' +}; +var MadaraPlugin = /** @class */ (function () { + function MadaraPlugin(metadata) { + this.id = metadata.id; + this.name = metadata.sourceName + "[madara]"; + var iconFileName = metadata.sourceName.replace(/\s+/g, "").toLowerCase(); + this.icon = "multisrc/madara/icons/".concat(iconFileName, ".png"); + this.site = metadata.sourceSite; + this.version = "1.0.0"; + this.userAgent = ""; + this.cookieString = ""; + this.options = metadata.options; + this.filter = metadata.filters; + } + MadaraPlugin.prototype.popularNovels = function (pageNo, _a) { + var _b, _c, _d, _e, _f, _g; + var filters = _a.filters, showLatestNovels = _a.showLatestNovels; + return __awaiter(this, void 0, void 0, function () { + var novels, url, body, loadedCheerio; + return __generator(this, function (_h) { + switch (_h.label) { + case 0: + novels = []; + url = this.site; + if ((filters === null || filters === void 0 ? void 0 : filters.genres) && ((_c = (_b = this.options) === null || _b === void 0 ? void 0 : _b.path) === null || _c === void 0 ? void 0 : _c.genres)) { + url += ((_e = (_d = this.options) === null || _d === void 0 ? void 0 : _d.path) === null || _e === void 0 ? void 0 : _e.genres) + filters.genres + '/'; + } + else { + url += ((_g = (_f = this.options) === null || _f === void 0 ? void 0 : _f.path) === null || _g === void 0 ? void 0 : _g.novels) ? this.options.path.novels : MadaraDefaultPath.novels; + } + url += '/page/' + pageNo + '/' + + '?m_orderby=' + (showLatestNovels ? 'latest' : ((filters === null || filters === void 0 ? void 0 : filters.sort) || 'rating')); + return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })]; + case 1: + body = _h.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.manga-title-badges').remove(); + loadedCheerio('.page-item-detail').each(function () { + var novelName = loadedCheerio(this).find('.post-title').text().trim(); + var image = loadedCheerio(this).find('img'); + var novelCover = image.attr('data-src') || image.attr('src'); + var novelUrl = loadedCheerio(this).find('.post-title') + .find('a') + .attr('href') || ''; + var novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + novels.push(novel); + }); + return [2 /*return*/, novels]; + } + }); + }); + }; + MadaraPlugin.prototype.parseNovelAndChapters = function (novelUrl) { + var _a; + return __awaiter(this, void 0, void 0, function () { + var novel, body, loadedCheerio, html, novelId, formData, chapters; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + novel = { + url: novelUrl, + }; + return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl).then(function (res) { return res.text(); })]; + case 1: + body = _b.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.manga-title-badges, #manga-title span').remove(); + novel.name = + loadedCheerio('.post-title h1').text().trim() || + loadedCheerio('#manga-title h1').text(); + novel.cover = + loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || + loadedCheerio('.summary_image > a > img').attr('data-src') || + loadedCheerio('.summary_image > a > img').attr('src') || + defaultCover_1.defaultCover; + loadedCheerio('.post-content_item, .post-content').each(function () { + var detailName = loadedCheerio(this).find('h5').text().trim(); + var detail = loadedCheerio(this).find('.summary-content').text().trim(); + switch (detailName) { + case 'Genre(s)': + case 'التصنيفات': + novel.genres = detail.replace(/[\\t\\n]/g, ','); + break; + case 'Author(s)': + case 'المؤلف': + case 'المؤلف (ين)': + novel.author = detail; + break; + case 'Status': + case 'الحالة': + novel.status = + detail.includes('OnGoing') || detail.includes('مستمرة') + ? novelStatus_1.NovelStatus.Ongoing + : novelStatus_1.NovelStatus.Completed; + break; + } + }); + loadedCheerio('div.summary__content .code-block,script').remove(); + novel.summary = + loadedCheerio('div.summary__content').text().trim() || + loadedCheerio('#tab-manga-about').text().trim() || + loadedCheerio('.post-content_item h5:contains("Summary")').next().text().trim(); + if (!(((_a = this.options) === null || _a === void 0 ? void 0 : _a.useNewChapterEndpoint) !== true)) return [3 /*break*/, 3]; + novelId = loadedCheerio('.rating-post-id').attr('value') || + loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; + formData = new FormData(); + formData.append("action", "manga_get_chapters"); + formData.append("manga", novelId); + return [4 /*yield*/, (0, fetch_1.fetchApi)(this.site + 'wp-admin/admin-ajax.php', { + method: 'POST', + body: formData, + }) + .then(function (res) { return res.text(); })]; + case 2: + html = _b.sent(); + return [3 /*break*/, 5]; + case 3: return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl + 'ajax/chapters/', { method: 'POST' }) + .then(function (res) { return res.text(); })]; + case 4: + html = _b.sent(); + _b.label = 5; + case 5: + if (html !== '0') { + loadedCheerio = (0, cheerio_1.load)(html); + } + chapters = []; + loadedCheerio('.wp-manga-chapter').each(function () { + var chapterName = loadedCheerio(this).find('a').text().trim(); + var releaseDate = null; + releaseDate = loadedCheerio(this) + .find('span.chapter-release-date') + .text() + .trim(); + if (releaseDate) { + releaseDate = (0, parseMadaraDate_1.parseMadaraDate)(releaseDate); + } + else { + /** + * Insert current date + */ + releaseDate = (0, dayjs_1.default)().format('LL'); + } + var chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); + }); + novel.chapters = chapters.reverse(); + return [2 /*return*/, novel]; + } + }); + }); + }; + MadaraPlugin.prototype.parseChapter = function (chapterUrl) { + return __awaiter(this, void 0, void 0, function () { + var body, loadedCheerio, chapterText; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, (0, fetch_1.fetchApi)(chapterUrl).then(function (res) { return res.text(); })]; + case 1: + body = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + chapterText = loadedCheerio('.text-left').html() || + loadedCheerio('.text-right').html() || + loadedCheerio('.entry-content').html() || ""; + return [2 /*return*/, chapterText]; + } + }); + }); + }; + MadaraPlugin.prototype.searchNovels = function (searchTerm, pageNo) { + return __awaiter(this, void 0, void 0, function () { + var novels, url, body, loadedCheerio; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + novels = []; + url = this.site + "?s=" + searchTerm + "&post_type=wp-manga"; + return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })]; + case 1: + body = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.c-tabs-item__content').each(function () { + var novelName = loadedCheerio(this).find('.post-title').text().trim(); + var image = loadedCheerio(this).find('img'); + var novelCover = image.attr('data-src') || image.attr('src'); + var novelUrl = loadedCheerio(this) + .find('.post-title') + .find('a') + .attr('href') || ''; + var novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + novels.push(novel); + }); + return [2 /*return*/, novels]; + } + }); + }); + }; + MadaraPlugin.prototype.fetchImage = function (url) { + return __awaiter(this, void 0, void 0, function () { + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, (0, fetch_1.fetchFile)(url, {})]; + case 1: return [2 /*return*/, _a.sent()]; + } + }); + }); + }; + return MadaraPlugin; +}()); +var plugin = new MadaraPlugin({ "id": "daonovel", "sourceSite": "https://daonovel.com/", "sourceName": "DaoNovel", "filters": [{ "key": "sort", "label": "Order by", "values": [{ "label": "Rating", "value": "rating" }, { "label": "A-Z", "value": "alphabet" }, { "label": "Latest", "value": "latest" }, { "label": "Most Views", "value": "views" }, { "label": "New", "value": "new-manga" }, { "label": "Trending", "value": "trending" }], "inputType": "Picker" }], "options": { "path": { "novels": "novels-list", "novel": "novels", "chapter": "novels" }, "useNewChapterEndpoint": true, "lang": "English" } }); +exports.default = plugin; diff --git a/.js/plugins/english/FansTranslations[madara].js b/.js/plugins/english/FansTranslations[madara].js new file mode 100644 index 0000000..8b57d94 --- /dev/null +++ b/.js/plugins/english/FansTranslations[madara].js @@ -0,0 +1,269 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __generator = (this && this.__generator) || function (thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (g && (g = 0, op[0] && (_ = 0)), _) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +}; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var fetch_1 = require("@libs/fetch"); +var cheerio_1 = require("cheerio"); +var defaultCover_1 = require("@libs/defaultCover"); +var novelStatus_1 = require("@libs/novelStatus"); +var parseMadaraDate_1 = require("@libs/parseMadaraDate"); +var dayjs_1 = __importDefault(require("dayjs")); +var MadaraDefaultPath = { + novels: 'novel', + novel: 'novel', + chapter: 'novel' +}; +var MadaraPlugin = /** @class */ (function () { + function MadaraPlugin(metadata) { + this.id = metadata.id; + this.name = metadata.sourceName + "[madara]"; + var iconFileName = metadata.sourceName.replace(/\s+/g, "").toLowerCase(); + this.icon = "multisrc/madara/icons/".concat(iconFileName, ".png"); + this.site = metadata.sourceSite; + this.version = "1.0.0"; + this.userAgent = ""; + this.cookieString = ""; + this.options = metadata.options; + this.filter = metadata.filters; + } + MadaraPlugin.prototype.popularNovels = function (pageNo, _a) { + var _b, _c, _d, _e, _f, _g; + var filters = _a.filters, showLatestNovels = _a.showLatestNovels; + return __awaiter(this, void 0, void 0, function () { + var novels, url, body, loadedCheerio; + return __generator(this, function (_h) { + switch (_h.label) { + case 0: + novels = []; + url = this.site; + if ((filters === null || filters === void 0 ? void 0 : filters.genres) && ((_c = (_b = this.options) === null || _b === void 0 ? void 0 : _b.path) === null || _c === void 0 ? void 0 : _c.genres)) { + url += ((_e = (_d = this.options) === null || _d === void 0 ? void 0 : _d.path) === null || _e === void 0 ? void 0 : _e.genres) + filters.genres + '/'; + } + else { + url += ((_g = (_f = this.options) === null || _f === void 0 ? void 0 : _f.path) === null || _g === void 0 ? void 0 : _g.novels) ? this.options.path.novels : MadaraDefaultPath.novels; + } + url += '/page/' + pageNo + '/' + + '?m_orderby=' + (showLatestNovels ? 'latest' : ((filters === null || filters === void 0 ? void 0 : filters.sort) || 'rating')); + return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })]; + case 1: + body = _h.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.manga-title-badges').remove(); + loadedCheerio('.page-item-detail').each(function () { + var novelName = loadedCheerio(this).find('.post-title').text().trim(); + var image = loadedCheerio(this).find('img'); + var novelCover = image.attr('data-src') || image.attr('src'); + var novelUrl = loadedCheerio(this).find('.post-title') + .find('a') + .attr('href') || ''; + var novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + novels.push(novel); + }); + return [2 /*return*/, novels]; + } + }); + }); + }; + MadaraPlugin.prototype.parseNovelAndChapters = function (novelUrl) { + var _a; + return __awaiter(this, void 0, void 0, function () { + var novel, body, loadedCheerio, html, novelId, formData, chapters; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + novel = { + url: novelUrl, + }; + return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl).then(function (res) { return res.text(); })]; + case 1: + body = _b.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.manga-title-badges, #manga-title span').remove(); + novel.name = + loadedCheerio('.post-title h1').text().trim() || + loadedCheerio('#manga-title h1').text(); + novel.cover = + loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || + loadedCheerio('.summary_image > a > img').attr('data-src') || + loadedCheerio('.summary_image > a > img').attr('src') || + defaultCover_1.defaultCover; + loadedCheerio('.post-content_item, .post-content').each(function () { + var detailName = loadedCheerio(this).find('h5').text().trim(); + var detail = loadedCheerio(this).find('.summary-content').text().trim(); + switch (detailName) { + case 'Genre(s)': + case 'التصنيفات': + novel.genres = detail.replace(/[\\t\\n]/g, ','); + break; + case 'Author(s)': + case 'المؤلف': + case 'المؤلف (ين)': + novel.author = detail; + break; + case 'Status': + case 'الحالة': + novel.status = + detail.includes('OnGoing') || detail.includes('مستمرة') + ? novelStatus_1.NovelStatus.Ongoing + : novelStatus_1.NovelStatus.Completed; + break; + } + }); + loadedCheerio('div.summary__content .code-block,script').remove(); + novel.summary = + loadedCheerio('div.summary__content').text().trim() || + loadedCheerio('#tab-manga-about').text().trim() || + loadedCheerio('.post-content_item h5:contains("Summary")').next().text().trim(); + if (!(((_a = this.options) === null || _a === void 0 ? void 0 : _a.useNewChapterEndpoint) !== true)) return [3 /*break*/, 3]; + novelId = loadedCheerio('.rating-post-id').attr('value') || + loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; + formData = new FormData(); + formData.append("action", "manga_get_chapters"); + formData.append("manga", novelId); + return [4 /*yield*/, (0, fetch_1.fetchApi)(this.site + 'wp-admin/admin-ajax.php', { + method: 'POST', + body: formData, + }) + .then(function (res) { return res.text(); })]; + case 2: + html = _b.sent(); + return [3 /*break*/, 5]; + case 3: return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl + 'ajax/chapters/', { method: 'POST' }) + .then(function (res) { return res.text(); })]; + case 4: + html = _b.sent(); + _b.label = 5; + case 5: + if (html !== '0') { + loadedCheerio = (0, cheerio_1.load)(html); + } + chapters = []; + loadedCheerio('.wp-manga-chapter').each(function () { + var chapterName = loadedCheerio(this).find('a').text().trim(); + var releaseDate = null; + releaseDate = loadedCheerio(this) + .find('span.chapter-release-date') + .text() + .trim(); + if (releaseDate) { + releaseDate = (0, parseMadaraDate_1.parseMadaraDate)(releaseDate); + } + else { + /** + * Insert current date + */ + releaseDate = (0, dayjs_1.default)().format('LL'); + } + var chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); + }); + novel.chapters = chapters.reverse(); + return [2 /*return*/, novel]; + } + }); + }); + }; + MadaraPlugin.prototype.parseChapter = function (chapterUrl) { + return __awaiter(this, void 0, void 0, function () { + var body, loadedCheerio, chapterText; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, (0, fetch_1.fetchApi)(chapterUrl).then(function (res) { return res.text(); })]; + case 1: + body = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + chapterText = loadedCheerio('.text-left').html() || + loadedCheerio('.text-right').html() || + loadedCheerio('.entry-content').html() || ""; + return [2 /*return*/, chapterText]; + } + }); + }); + }; + MadaraPlugin.prototype.searchNovels = function (searchTerm, pageNo) { + return __awaiter(this, void 0, void 0, function () { + var novels, url, body, loadedCheerio; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + novels = []; + url = this.site + "?s=" + searchTerm + "&post_type=wp-manga"; + return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })]; + case 1: + body = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.c-tabs-item__content').each(function () { + var novelName = loadedCheerio(this).find('.post-title').text().trim(); + var image = loadedCheerio(this).find('img'); + var novelCover = image.attr('data-src') || image.attr('src'); + var novelUrl = loadedCheerio(this) + .find('.post-title') + .find('a') + .attr('href') || ''; + var novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + novels.push(novel); + }); + return [2 /*return*/, novels]; + } + }); + }); + }; + MadaraPlugin.prototype.fetchImage = function (url) { + return __awaiter(this, void 0, void 0, function () { + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, (0, fetch_1.fetchFile)(url, {})]; + case 1: return [2 /*return*/, _a.sent()]; + } + }); + }); + }; + return MadaraPlugin; +}()); +var plugin = new MadaraPlugin({ "id": "fanTLS", "sourceSite": "https://fanstranslations.com/", "sourceName": "Fans Translations", "filters": [{ "key": "sort", "label": "Order by", "values": [{ "label": "Rating", "value": "rating" }, { "label": "A-Z", "value": "alphabet" }, { "label": "Latest", "value": "latest" }, { "label": "Most Views", "value": "views" }, { "label": "New", "value": "new-manga" }, { "label": "Trending", "value": "trending" }], "inputType": "Picker" }], "options": { "useNewChapterEndpoint": true, "lang": "English" } }); +exports.default = plugin; diff --git a/.js/plugins/english/FirstKissNovel[madara].js b/.js/plugins/english/FirstKissNovel[madara].js new file mode 100644 index 0000000..1329250 --- /dev/null +++ b/.js/plugins/english/FirstKissNovel[madara].js @@ -0,0 +1,269 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __generator = (this && this.__generator) || function (thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (g && (g = 0, op[0] && (_ = 0)), _) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +}; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var fetch_1 = require("@libs/fetch"); +var cheerio_1 = require("cheerio"); +var defaultCover_1 = require("@libs/defaultCover"); +var novelStatus_1 = require("@libs/novelStatus"); +var parseMadaraDate_1 = require("@libs/parseMadaraDate"); +var dayjs_1 = __importDefault(require("dayjs")); +var MadaraDefaultPath = { + novels: 'novel', + novel: 'novel', + chapter: 'novel' +}; +var MadaraPlugin = /** @class */ (function () { + function MadaraPlugin(metadata) { + this.id = metadata.id; + this.name = metadata.sourceName + "[madara]"; + var iconFileName = metadata.sourceName.replace(/\s+/g, "").toLowerCase(); + this.icon = "multisrc/madara/icons/".concat(iconFileName, ".png"); + this.site = metadata.sourceSite; + this.version = "1.0.0"; + this.userAgent = ""; + this.cookieString = ""; + this.options = metadata.options; + this.filter = metadata.filters; + } + MadaraPlugin.prototype.popularNovels = function (pageNo, _a) { + var _b, _c, _d, _e, _f, _g; + var filters = _a.filters, showLatestNovels = _a.showLatestNovels; + return __awaiter(this, void 0, void 0, function () { + var novels, url, body, loadedCheerio; + return __generator(this, function (_h) { + switch (_h.label) { + case 0: + novels = []; + url = this.site; + if ((filters === null || filters === void 0 ? void 0 : filters.genres) && ((_c = (_b = this.options) === null || _b === void 0 ? void 0 : _b.path) === null || _c === void 0 ? void 0 : _c.genres)) { + url += ((_e = (_d = this.options) === null || _d === void 0 ? void 0 : _d.path) === null || _e === void 0 ? void 0 : _e.genres) + filters.genres + '/'; + } + else { + url += ((_g = (_f = this.options) === null || _f === void 0 ? void 0 : _f.path) === null || _g === void 0 ? void 0 : _g.novels) ? this.options.path.novels : MadaraDefaultPath.novels; + } + url += '/page/' + pageNo + '/' + + '?m_orderby=' + (showLatestNovels ? 'latest' : ((filters === null || filters === void 0 ? void 0 : filters.sort) || 'rating')); + return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })]; + case 1: + body = _h.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.manga-title-badges').remove(); + loadedCheerio('.page-item-detail').each(function () { + var novelName = loadedCheerio(this).find('.post-title').text().trim(); + var image = loadedCheerio(this).find('img'); + var novelCover = image.attr('data-src') || image.attr('src'); + var novelUrl = loadedCheerio(this).find('.post-title') + .find('a') + .attr('href') || ''; + var novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + novels.push(novel); + }); + return [2 /*return*/, novels]; + } + }); + }); + }; + MadaraPlugin.prototype.parseNovelAndChapters = function (novelUrl) { + var _a; + return __awaiter(this, void 0, void 0, function () { + var novel, body, loadedCheerio, html, novelId, formData, chapters; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + novel = { + url: novelUrl, + }; + return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl).then(function (res) { return res.text(); })]; + case 1: + body = _b.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.manga-title-badges, #manga-title span').remove(); + novel.name = + loadedCheerio('.post-title h1').text().trim() || + loadedCheerio('#manga-title h1').text(); + novel.cover = + loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || + loadedCheerio('.summary_image > a > img').attr('data-src') || + loadedCheerio('.summary_image > a > img').attr('src') || + defaultCover_1.defaultCover; + loadedCheerio('.post-content_item, .post-content').each(function () { + var detailName = loadedCheerio(this).find('h5').text().trim(); + var detail = loadedCheerio(this).find('.summary-content').text().trim(); + switch (detailName) { + case 'Genre(s)': + case 'التصنيفات': + novel.genres = detail.replace(/[\\t\\n]/g, ','); + break; + case 'Author(s)': + case 'المؤلف': + case 'المؤلف (ين)': + novel.author = detail; + break; + case 'Status': + case 'الحالة': + novel.status = + detail.includes('OnGoing') || detail.includes('مستمرة') + ? novelStatus_1.NovelStatus.Ongoing + : novelStatus_1.NovelStatus.Completed; + break; + } + }); + loadedCheerio('div.summary__content .code-block,script').remove(); + novel.summary = + loadedCheerio('div.summary__content').text().trim() || + loadedCheerio('#tab-manga-about').text().trim() || + loadedCheerio('.post-content_item h5:contains("Summary")').next().text().trim(); + if (!(((_a = this.options) === null || _a === void 0 ? void 0 : _a.useNewChapterEndpoint) !== true)) return [3 /*break*/, 3]; + novelId = loadedCheerio('.rating-post-id').attr('value') || + loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; + formData = new FormData(); + formData.append("action", "manga_get_chapters"); + formData.append("manga", novelId); + return [4 /*yield*/, (0, fetch_1.fetchApi)(this.site + 'wp-admin/admin-ajax.php', { + method: 'POST', + body: formData, + }) + .then(function (res) { return res.text(); })]; + case 2: + html = _b.sent(); + return [3 /*break*/, 5]; + case 3: return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl + 'ajax/chapters/', { method: 'POST' }) + .then(function (res) { return res.text(); })]; + case 4: + html = _b.sent(); + _b.label = 5; + case 5: + if (html !== '0') { + loadedCheerio = (0, cheerio_1.load)(html); + } + chapters = []; + loadedCheerio('.wp-manga-chapter').each(function () { + var chapterName = loadedCheerio(this).find('a').text().trim(); + var releaseDate = null; + releaseDate = loadedCheerio(this) + .find('span.chapter-release-date') + .text() + .trim(); + if (releaseDate) { + releaseDate = (0, parseMadaraDate_1.parseMadaraDate)(releaseDate); + } + else { + /** + * Insert current date + */ + releaseDate = (0, dayjs_1.default)().format('LL'); + } + var chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); + }); + novel.chapters = chapters.reverse(); + return [2 /*return*/, novel]; + } + }); + }); + }; + MadaraPlugin.prototype.parseChapter = function (chapterUrl) { + return __awaiter(this, void 0, void 0, function () { + var body, loadedCheerio, chapterText; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, (0, fetch_1.fetchApi)(chapterUrl).then(function (res) { return res.text(); })]; + case 1: + body = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + chapterText = loadedCheerio('.text-left').html() || + loadedCheerio('.text-right').html() || + loadedCheerio('.entry-content').html() || ""; + return [2 /*return*/, chapterText]; + } + }); + }); + }; + MadaraPlugin.prototype.searchNovels = function (searchTerm, pageNo) { + return __awaiter(this, void 0, void 0, function () { + var novels, url, body, loadedCheerio; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + novels = []; + url = this.site + "?s=" + searchTerm + "&post_type=wp-manga"; + return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })]; + case 1: + body = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.c-tabs-item__content').each(function () { + var novelName = loadedCheerio(this).find('.post-title').text().trim(); + var image = loadedCheerio(this).find('img'); + var novelCover = image.attr('data-src') || image.attr('src'); + var novelUrl = loadedCheerio(this) + .find('.post-title') + .find('a') + .attr('href') || ''; + var novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + novels.push(novel); + }); + return [2 /*return*/, novels]; + } + }); + }); + }; + MadaraPlugin.prototype.fetchImage = function (url) { + return __awaiter(this, void 0, void 0, function () { + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, (0, fetch_1.fetchFile)(url, {})]; + case 1: return [2 /*return*/, _a.sent()]; + } + }); + }); + }; + return MadaraPlugin; +}()); +var plugin = new MadaraPlugin({ "id": "1stkissnovel", "sourceSite": "https://1stkissnovel.org/", "sourceName": "FirstKissNovel", "filters": [{ "key": "sort", "label": "Order by", "values": [{ "label": "Rating", "value": "rating" }, { "label": "A-Z", "value": "alphabet" }, { "label": "Latest", "value": "latest" }, { "label": "Most Views", "value": "views" }, { "label": "New", "value": "new-manga" }, { "label": "Trending", "value": "trending" }], "inputType": "Picker" }, { "key": "genres", "label": "GENRES", "values": [{ "label": "Action", "value": "action" }, { "label": "Adult", "value": "adult" }, { "label": "Adventure", "value": "adventure" }, { "label": "Anime", "value": "anime" }, { "label": "Apocalypse", "value": "apocalypse" }, { "label": "Boy's Love", "value": "boys-love" }, { "label": "Comedy", "value": "comedy" }, { "label": "Completed", "value": "completed" }, { "label": "Cooking", "value": "cooking" }, { "label": "Demons", "value": "demons" }, { "label": "Detective", "value": "detective" }, { "label": "Drama", "value": "drama" }, { "label": "Ecchi", "value": "ecchi" }, { "label": "Fan-Fiction", "value": "fan-fiction" }, { "label": "Fantasy", "value": "fantasy" }, { "label": "Food", "value": "food" }, { "label": "Game", "value": "game" }, { "label": "Gender Bender", "value": "gender-bender" }, { "label": "Girls Love", "value": "girls-love" }, { "label": "Harem", "value": "harem" }, { "label": "Historical", "value": "historical" }, { "label": "Horror", "value": "horror" }, { "label": "Humor", "value": "humor" }, { "label": "Isekai", "value": "isekai" }, { "label": "Josei", "value": "josei" }, { "label": "Magic", "value": "magic" }, { "label": "Magical", "value": "magical" }, { "label": "Manhua", "value": "manhua" }, { "label": "Manhwa", "value": "manhwa" }, { "label": "Martial Arts", "value": "martial-arts" }, { "label": "Mature", "value": "mature" }, { "label": "Mecha", "value": "mecha" }, { "label": "Medical", "value": "medical" }, { "label": "Military", "value": "military" }, { "label": "Moder", "value": "moder" }, { "label": "Modern", "value": "modern" }, { "label": "Murim", "value": "murim" }, { "label": "Music", "value": "music" }, { "label": "Mystery", "value": "mystery" }, { "label": "Psychological", "value": "psychological" }, { "label": "Reverse", "value": "reverse" }, { "label": "Reverse harem", "value": "reverse-harem" }, { "label": "Romance", "value": "romance" }, { "label": "School Life", "value": "school-life" }, { "label": "Sci-fi", "value": "sci-fi" }, { "label": "Seinen", "value": "seinen" }, { "label": "Shoujo", "value": "shoujo" }, { "label": "Shoujo Ai", "value": "shoujo-ai" }, { "label": "Shounen", "value": "shounen" }, { "label": "Shounen Ai", "value": "shounen-ai" }, { "label": "Slice of Life", "value": "slice-of-life" }, { "label": "Smut", "value": "smut" }, { "label": "Sports", "value": "sports" }, { "label": "Super power", "value": "super-power" }, { "label": "Superhero", "value": "superhero" }, { "label": "Supernatural", "value": "supernatural" }, { "label": "Thriller", "value": "thriller" }, { "label": "Tragedy", "value": "tragedy" }, { "label": "Urban Life", "value": "urban-life" }, { "label": "Vampire", "value": "vampire" }, { "label": "Webtoons", "value": "webtoons" }, { "label": "Wuxia", "value": "wuxia" }, { "label": "Xianxia", "value": "xianxia" }, { "label": "Xuanhuan", "value": "xuanhuan" }, { "label": "Yaoi", "value": "yaoi" }, { "label": "Yuri", "value": "yuri" }], "inputType": "Picker" }], "options": { "useNewChapterEndpoint": true, "lang": "English" } }); +exports.default = plugin; diff --git a/.js/plugins/english/FreeNovelMe[madara].js b/.js/plugins/english/FreeNovelMe[madara].js new file mode 100644 index 0000000..d4ad448 --- /dev/null +++ b/.js/plugins/english/FreeNovelMe[madara].js @@ -0,0 +1,269 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __generator = (this && this.__generator) || function (thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (g && (g = 0, op[0] && (_ = 0)), _) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +}; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var fetch_1 = require("@libs/fetch"); +var cheerio_1 = require("cheerio"); +var defaultCover_1 = require("@libs/defaultCover"); +var novelStatus_1 = require("@libs/novelStatus"); +var parseMadaraDate_1 = require("@libs/parseMadaraDate"); +var dayjs_1 = __importDefault(require("dayjs")); +var MadaraDefaultPath = { + novels: 'novel', + novel: 'novel', + chapter: 'novel' +}; +var MadaraPlugin = /** @class */ (function () { + function MadaraPlugin(metadata) { + this.id = metadata.id; + this.name = metadata.sourceName + "[madara]"; + var iconFileName = metadata.sourceName.replace(/\s+/g, "").toLowerCase(); + this.icon = "multisrc/madara/icons/".concat(iconFileName, ".png"); + this.site = metadata.sourceSite; + this.version = "1.0.0"; + this.userAgent = ""; + this.cookieString = ""; + this.options = metadata.options; + this.filter = metadata.filters; + } + MadaraPlugin.prototype.popularNovels = function (pageNo, _a) { + var _b, _c, _d, _e, _f, _g; + var filters = _a.filters, showLatestNovels = _a.showLatestNovels; + return __awaiter(this, void 0, void 0, function () { + var novels, url, body, loadedCheerio; + return __generator(this, function (_h) { + switch (_h.label) { + case 0: + novels = []; + url = this.site; + if ((filters === null || filters === void 0 ? void 0 : filters.genres) && ((_c = (_b = this.options) === null || _b === void 0 ? void 0 : _b.path) === null || _c === void 0 ? void 0 : _c.genres)) { + url += ((_e = (_d = this.options) === null || _d === void 0 ? void 0 : _d.path) === null || _e === void 0 ? void 0 : _e.genres) + filters.genres + '/'; + } + else { + url += ((_g = (_f = this.options) === null || _f === void 0 ? void 0 : _f.path) === null || _g === void 0 ? void 0 : _g.novels) ? this.options.path.novels : MadaraDefaultPath.novels; + } + url += '/page/' + pageNo + '/' + + '?m_orderby=' + (showLatestNovels ? 'latest' : ((filters === null || filters === void 0 ? void 0 : filters.sort) || 'rating')); + return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })]; + case 1: + body = _h.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.manga-title-badges').remove(); + loadedCheerio('.page-item-detail').each(function () { + var novelName = loadedCheerio(this).find('.post-title').text().trim(); + var image = loadedCheerio(this).find('img'); + var novelCover = image.attr('data-src') || image.attr('src'); + var novelUrl = loadedCheerio(this).find('.post-title') + .find('a') + .attr('href') || ''; + var novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + novels.push(novel); + }); + return [2 /*return*/, novels]; + } + }); + }); + }; + MadaraPlugin.prototype.parseNovelAndChapters = function (novelUrl) { + var _a; + return __awaiter(this, void 0, void 0, function () { + var novel, body, loadedCheerio, html, novelId, formData, chapters; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + novel = { + url: novelUrl, + }; + return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl).then(function (res) { return res.text(); })]; + case 1: + body = _b.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.manga-title-badges, #manga-title span').remove(); + novel.name = + loadedCheerio('.post-title h1').text().trim() || + loadedCheerio('#manga-title h1').text(); + novel.cover = + loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || + loadedCheerio('.summary_image > a > img').attr('data-src') || + loadedCheerio('.summary_image > a > img').attr('src') || + defaultCover_1.defaultCover; + loadedCheerio('.post-content_item, .post-content').each(function () { + var detailName = loadedCheerio(this).find('h5').text().trim(); + var detail = loadedCheerio(this).find('.summary-content').text().trim(); + switch (detailName) { + case 'Genre(s)': + case 'التصنيفات': + novel.genres = detail.replace(/[\\t\\n]/g, ','); + break; + case 'Author(s)': + case 'المؤلف': + case 'المؤلف (ين)': + novel.author = detail; + break; + case 'Status': + case 'الحالة': + novel.status = + detail.includes('OnGoing') || detail.includes('مستمرة') + ? novelStatus_1.NovelStatus.Ongoing + : novelStatus_1.NovelStatus.Completed; + break; + } + }); + loadedCheerio('div.summary__content .code-block,script').remove(); + novel.summary = + loadedCheerio('div.summary__content').text().trim() || + loadedCheerio('#tab-manga-about').text().trim() || + loadedCheerio('.post-content_item h5:contains("Summary")').next().text().trim(); + if (!(((_a = this.options) === null || _a === void 0 ? void 0 : _a.useNewChapterEndpoint) !== true)) return [3 /*break*/, 3]; + novelId = loadedCheerio('.rating-post-id').attr('value') || + loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; + formData = new FormData(); + formData.append("action", "manga_get_chapters"); + formData.append("manga", novelId); + return [4 /*yield*/, (0, fetch_1.fetchApi)(this.site + 'wp-admin/admin-ajax.php', { + method: 'POST', + body: formData, + }) + .then(function (res) { return res.text(); })]; + case 2: + html = _b.sent(); + return [3 /*break*/, 5]; + case 3: return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl + 'ajax/chapters/', { method: 'POST' }) + .then(function (res) { return res.text(); })]; + case 4: + html = _b.sent(); + _b.label = 5; + case 5: + if (html !== '0') { + loadedCheerio = (0, cheerio_1.load)(html); + } + chapters = []; + loadedCheerio('.wp-manga-chapter').each(function () { + var chapterName = loadedCheerio(this).find('a').text().trim(); + var releaseDate = null; + releaseDate = loadedCheerio(this) + .find('span.chapter-release-date') + .text() + .trim(); + if (releaseDate) { + releaseDate = (0, parseMadaraDate_1.parseMadaraDate)(releaseDate); + } + else { + /** + * Insert current date + */ + releaseDate = (0, dayjs_1.default)().format('LL'); + } + var chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); + }); + novel.chapters = chapters.reverse(); + return [2 /*return*/, novel]; + } + }); + }); + }; + MadaraPlugin.prototype.parseChapter = function (chapterUrl) { + return __awaiter(this, void 0, void 0, function () { + var body, loadedCheerio, chapterText; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, (0, fetch_1.fetchApi)(chapterUrl).then(function (res) { return res.text(); })]; + case 1: + body = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + chapterText = loadedCheerio('.text-left').html() || + loadedCheerio('.text-right').html() || + loadedCheerio('.entry-content').html() || ""; + return [2 /*return*/, chapterText]; + } + }); + }); + }; + MadaraPlugin.prototype.searchNovels = function (searchTerm, pageNo) { + return __awaiter(this, void 0, void 0, function () { + var novels, url, body, loadedCheerio; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + novels = []; + url = this.site + "?s=" + searchTerm + "&post_type=wp-manga"; + return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })]; + case 1: + body = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.c-tabs-item__content').each(function () { + var novelName = loadedCheerio(this).find('.post-title').text().trim(); + var image = loadedCheerio(this).find('img'); + var novelCover = image.attr('data-src') || image.attr('src'); + var novelUrl = loadedCheerio(this) + .find('.post-title') + .find('a') + .attr('href') || ''; + var novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + novels.push(novel); + }); + return [2 /*return*/, novels]; + } + }); + }); + }; + MadaraPlugin.prototype.fetchImage = function (url) { + return __awaiter(this, void 0, void 0, function () { + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, (0, fetch_1.fetchFile)(url, {})]; + case 1: return [2 /*return*/, _a.sent()]; + } + }); + }); + }; + return MadaraPlugin; +}()); +var plugin = new MadaraPlugin({ "id": "freenovel.me", "sourceSite": "https://freenovel.me/", "sourceName": "FreeNovelMe", "filters": [{ "key": "sort", "label": "Order by", "values": [{ "label": "Rating", "value": "rating" }, { "label": "A-Z", "value": "alphabet" }, { "label": "Latest", "value": "latest" }, { "label": "Most Views", "value": "views" }, { "label": "New", "value": "new-manga" }, { "label": "Trending", "value": "trending" }], "inputType": "Picker" }, { "key": "genres", "label": "GENRES", "values": [{ "label": "Action", "value": "action" }, { "label": "Adult", "value": "adult" }, { "label": "Adventure", "value": "adventure" }, { "label": "Cartoon", "value": "cartoon" }, { "label": "Comedy", "value": "comedy" }, { "label": "Cooking", "value": "cooking" }, { "label": "Detective", "value": "detective" }, { "label": "Drama", "value": "drama" }, { "label": "Fantasy", "value": "fantasy" }, { "label": "Game", "value": "game" }, { "label": "Gender Bender", "value": "gender-bender" }, { "label": "Historical", "value": "historical" }, { "label": "History", "value": "history" }, { "label": "Horror", "value": "horror" }, { "label": "Josei", "value": "josei" }, { "label": "Live action", "value": "live-action" }, { "label": "Martial", "value": "martial" }, { "label": "Martial Arts", "value": "martial-arts" }, { "label": "Mature", "value": "mature" }, { "label": "Mecha", "value": "mecha" }, { "label": "Mystery", "value": "mystery" }, { "label": "One shot", "value": "one-shot" }, { "label": "Premium", "value": "premium" }, { "label": "Psychological", "value": "psychological" }, { "label": "Reincarnation", "value": "reincarnation" }, { "label": "Romance", "value": "romance" }, { "label": "School Life", "value": "school-life" }, { "label": "Sci-fi", "value": "sci-fi" }, { "label": "Slice of Life", "value": "slice-of-life" }, { "label": "Smut", "value": "smut" }, { "label": "Sports", "value": "sports" }, { "label": "Supernatural", "value": "supernatural" }, { "label": "Tragedy", "value": "tragedy" }, { "label": "Wuxia", "value": "wuxia" }, { "label": "Xianxia", "value": "xianxia" }, { "label": "Xuanhuan", "value": "xuanhuan" }], "inputType": "Picker" }], "options": { "lang": "English" } }); +exports.default = plugin; diff --git a/.js/plugins/english/Guavaread[madara].js b/.js/plugins/english/Guavaread[madara].js new file mode 100644 index 0000000..81a00aa --- /dev/null +++ b/.js/plugins/english/Guavaread[madara].js @@ -0,0 +1,269 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __generator = (this && this.__generator) || function (thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (g && (g = 0, op[0] && (_ = 0)), _) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +}; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var fetch_1 = require("@libs/fetch"); +var cheerio_1 = require("cheerio"); +var defaultCover_1 = require("@libs/defaultCover"); +var novelStatus_1 = require("@libs/novelStatus"); +var parseMadaraDate_1 = require("@libs/parseMadaraDate"); +var dayjs_1 = __importDefault(require("dayjs")); +var MadaraDefaultPath = { + novels: 'novel', + novel: 'novel', + chapter: 'novel' +}; +var MadaraPlugin = /** @class */ (function () { + function MadaraPlugin(metadata) { + this.id = metadata.id; + this.name = metadata.sourceName + "[madara]"; + var iconFileName = metadata.sourceName.replace(/\s+/g, "").toLowerCase(); + this.icon = "multisrc/madara/icons/".concat(iconFileName, ".png"); + this.site = metadata.sourceSite; + this.version = "1.0.0"; + this.userAgent = ""; + this.cookieString = ""; + this.options = metadata.options; + this.filter = metadata.filters; + } + MadaraPlugin.prototype.popularNovels = function (pageNo, _a) { + var _b, _c, _d, _e, _f, _g; + var filters = _a.filters, showLatestNovels = _a.showLatestNovels; + return __awaiter(this, void 0, void 0, function () { + var novels, url, body, loadedCheerio; + return __generator(this, function (_h) { + switch (_h.label) { + case 0: + novels = []; + url = this.site; + if ((filters === null || filters === void 0 ? void 0 : filters.genres) && ((_c = (_b = this.options) === null || _b === void 0 ? void 0 : _b.path) === null || _c === void 0 ? void 0 : _c.genres)) { + url += ((_e = (_d = this.options) === null || _d === void 0 ? void 0 : _d.path) === null || _e === void 0 ? void 0 : _e.genres) + filters.genres + '/'; + } + else { + url += ((_g = (_f = this.options) === null || _f === void 0 ? void 0 : _f.path) === null || _g === void 0 ? void 0 : _g.novels) ? this.options.path.novels : MadaraDefaultPath.novels; + } + url += '/page/' + pageNo + '/' + + '?m_orderby=' + (showLatestNovels ? 'latest' : ((filters === null || filters === void 0 ? void 0 : filters.sort) || 'rating')); + return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })]; + case 1: + body = _h.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.manga-title-badges').remove(); + loadedCheerio('.page-item-detail').each(function () { + var novelName = loadedCheerio(this).find('.post-title').text().trim(); + var image = loadedCheerio(this).find('img'); + var novelCover = image.attr('data-src') || image.attr('src'); + var novelUrl = loadedCheerio(this).find('.post-title') + .find('a') + .attr('href') || ''; + var novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + novels.push(novel); + }); + return [2 /*return*/, novels]; + } + }); + }); + }; + MadaraPlugin.prototype.parseNovelAndChapters = function (novelUrl) { + var _a; + return __awaiter(this, void 0, void 0, function () { + var novel, body, loadedCheerio, html, novelId, formData, chapters; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + novel = { + url: novelUrl, + }; + return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl).then(function (res) { return res.text(); })]; + case 1: + body = _b.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.manga-title-badges, #manga-title span').remove(); + novel.name = + loadedCheerio('.post-title h1').text().trim() || + loadedCheerio('#manga-title h1').text(); + novel.cover = + loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || + loadedCheerio('.summary_image > a > img').attr('data-src') || + loadedCheerio('.summary_image > a > img').attr('src') || + defaultCover_1.defaultCover; + loadedCheerio('.post-content_item, .post-content').each(function () { + var detailName = loadedCheerio(this).find('h5').text().trim(); + var detail = loadedCheerio(this).find('.summary-content').text().trim(); + switch (detailName) { + case 'Genre(s)': + case 'التصنيفات': + novel.genres = detail.replace(/[\\t\\n]/g, ','); + break; + case 'Author(s)': + case 'المؤلف': + case 'المؤلف (ين)': + novel.author = detail; + break; + case 'Status': + case 'الحالة': + novel.status = + detail.includes('OnGoing') || detail.includes('مستمرة') + ? novelStatus_1.NovelStatus.Ongoing + : novelStatus_1.NovelStatus.Completed; + break; + } + }); + loadedCheerio('div.summary__content .code-block,script').remove(); + novel.summary = + loadedCheerio('div.summary__content').text().trim() || + loadedCheerio('#tab-manga-about').text().trim() || + loadedCheerio('.post-content_item h5:contains("Summary")').next().text().trim(); + if (!(((_a = this.options) === null || _a === void 0 ? void 0 : _a.useNewChapterEndpoint) !== true)) return [3 /*break*/, 3]; + novelId = loadedCheerio('.rating-post-id').attr('value') || + loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; + formData = new FormData(); + formData.append("action", "manga_get_chapters"); + formData.append("manga", novelId); + return [4 /*yield*/, (0, fetch_1.fetchApi)(this.site + 'wp-admin/admin-ajax.php', { + method: 'POST', + body: formData, + }) + .then(function (res) { return res.text(); })]; + case 2: + html = _b.sent(); + return [3 /*break*/, 5]; + case 3: return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl + 'ajax/chapters/', { method: 'POST' }) + .then(function (res) { return res.text(); })]; + case 4: + html = _b.sent(); + _b.label = 5; + case 5: + if (html !== '0') { + loadedCheerio = (0, cheerio_1.load)(html); + } + chapters = []; + loadedCheerio('.wp-manga-chapter').each(function () { + var chapterName = loadedCheerio(this).find('a').text().trim(); + var releaseDate = null; + releaseDate = loadedCheerio(this) + .find('span.chapter-release-date') + .text() + .trim(); + if (releaseDate) { + releaseDate = (0, parseMadaraDate_1.parseMadaraDate)(releaseDate); + } + else { + /** + * Insert current date + */ + releaseDate = (0, dayjs_1.default)().format('LL'); + } + var chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); + }); + novel.chapters = chapters.reverse(); + return [2 /*return*/, novel]; + } + }); + }); + }; + MadaraPlugin.prototype.parseChapter = function (chapterUrl) { + return __awaiter(this, void 0, void 0, function () { + var body, loadedCheerio, chapterText; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, (0, fetch_1.fetchApi)(chapterUrl).then(function (res) { return res.text(); })]; + case 1: + body = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + chapterText = loadedCheerio('.text-left').html() || + loadedCheerio('.text-right').html() || + loadedCheerio('.entry-content').html() || ""; + return [2 /*return*/, chapterText]; + } + }); + }); + }; + MadaraPlugin.prototype.searchNovels = function (searchTerm, pageNo) { + return __awaiter(this, void 0, void 0, function () { + var novels, url, body, loadedCheerio; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + novels = []; + url = this.site + "?s=" + searchTerm + "&post_type=wp-manga"; + return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })]; + case 1: + body = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.c-tabs-item__content').each(function () { + var novelName = loadedCheerio(this).find('.post-title').text().trim(); + var image = loadedCheerio(this).find('img'); + var novelCover = image.attr('data-src') || image.attr('src'); + var novelUrl = loadedCheerio(this) + .find('.post-title') + .find('a') + .attr('href') || ''; + var novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + novels.push(novel); + }); + return [2 /*return*/, novels]; + } + }); + }); + }; + MadaraPlugin.prototype.fetchImage = function (url) { + return __awaiter(this, void 0, void 0, function () { + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, (0, fetch_1.fetchFile)(url, {})]; + case 1: return [2 /*return*/, _a.sent()]; + } + }); + }); + }; + return MadaraPlugin; +}()); +var plugin = new MadaraPlugin({ "id": "guavaread", "sourceSite": "https://guavaread.com/", "sourceName": "Guavaread", "filters": [{ "key": "sort", "label": "Order by", "values": [{ "label": "Rating", "value": "rating" }, { "label": "A-Z", "value": "alphabet" }, { "label": "Latest", "value": "latest" }, { "label": "Most Views", "value": "views" }, { "label": "New", "value": "new-manga" }, { "label": "Trending", "value": "trending" }], "inputType": "Picker" }, { "key": "genres", "label": "GENRES", "values": [{ "label": "Action", "value": "action" }, { "label": "Adult", "value": "adult" }, { "label": "Adventure", "value": "adventure" }, { "label": "Comedy", "value": "comedy" }, { "label": "Complete", "value": "complete" }, { "label": "Cooking", "value": "cooking" }, { "label": "Detective", "value": "detective" }, { "label": "Drama", "value": "drama" }, { "label": "Dropped", "value": "dropped" }, { "label": "Ecchi", "value": "ecchi" }, { "label": "Fantasy", "value": "fantasy" }, { "label": "Gender Bender", "value": "gender-bender" }, { "label": "Historical", "value": "historical" }, { "label": "Horror", "value": "horror" }, { "label": "Josei", "value": "josei" }, { "label": "Mature", "value": "mature" }, { "label": "Mystery", "value": "mystery" }, { "label": "Original Story", "value": "original-story" }, { "label": "Pilot", "value": "pilot" }, { "label": "Psychological", "value": "psychological" }, { "label": "R-15", "value": "r-15" }, { "label": "R-19", "value": "r-19" }, { "label": "Reverse Harem", "value": "reverse-harem" }, { "label": "Romance", "value": "romance" }, { "label": "School Life", "value": "school-life" }, { "label": "Sci-fi", "value": "sci-fi" }, { "label": "Shoujo", "value": "shoujo" }, { "label": "Slice of Life", "value": "slice-of-life" }, { "label": "Smut", "value": "smut" }, { "label": "Supernatural", "value": "supernatural" }, { "label": "Tragedy", "value": "tragedy" }], "inputType": "Picker" }], "options": { "useNewChapterEndpoint": true, "lang": "English" } }); +exports.default = plugin; diff --git a/.js/plugins/english/LightNovelHeaven[madara].js b/.js/plugins/english/LightNovelHeaven[madara].js new file mode 100644 index 0000000..75b392c --- /dev/null +++ b/.js/plugins/english/LightNovelHeaven[madara].js @@ -0,0 +1,269 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __generator = (this && this.__generator) || function (thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (g && (g = 0, op[0] && (_ = 0)), _) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +}; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var fetch_1 = require("@libs/fetch"); +var cheerio_1 = require("cheerio"); +var defaultCover_1 = require("@libs/defaultCover"); +var novelStatus_1 = require("@libs/novelStatus"); +var parseMadaraDate_1 = require("@libs/parseMadaraDate"); +var dayjs_1 = __importDefault(require("dayjs")); +var MadaraDefaultPath = { + novels: 'novel', + novel: 'novel', + chapter: 'novel' +}; +var MadaraPlugin = /** @class */ (function () { + function MadaraPlugin(metadata) { + this.id = metadata.id; + this.name = metadata.sourceName + "[madara]"; + var iconFileName = metadata.sourceName.replace(/\s+/g, "").toLowerCase(); + this.icon = "multisrc/madara/icons/".concat(iconFileName, ".png"); + this.site = metadata.sourceSite; + this.version = "1.0.0"; + this.userAgent = ""; + this.cookieString = ""; + this.options = metadata.options; + this.filter = metadata.filters; + } + MadaraPlugin.prototype.popularNovels = function (pageNo, _a) { + var _b, _c, _d, _e, _f, _g; + var filters = _a.filters, showLatestNovels = _a.showLatestNovels; + return __awaiter(this, void 0, void 0, function () { + var novels, url, body, loadedCheerio; + return __generator(this, function (_h) { + switch (_h.label) { + case 0: + novels = []; + url = this.site; + if ((filters === null || filters === void 0 ? void 0 : filters.genres) && ((_c = (_b = this.options) === null || _b === void 0 ? void 0 : _b.path) === null || _c === void 0 ? void 0 : _c.genres)) { + url += ((_e = (_d = this.options) === null || _d === void 0 ? void 0 : _d.path) === null || _e === void 0 ? void 0 : _e.genres) + filters.genres + '/'; + } + else { + url += ((_g = (_f = this.options) === null || _f === void 0 ? void 0 : _f.path) === null || _g === void 0 ? void 0 : _g.novels) ? this.options.path.novels : MadaraDefaultPath.novels; + } + url += '/page/' + pageNo + '/' + + '?m_orderby=' + (showLatestNovels ? 'latest' : ((filters === null || filters === void 0 ? void 0 : filters.sort) || 'rating')); + return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })]; + case 1: + body = _h.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.manga-title-badges').remove(); + loadedCheerio('.page-item-detail').each(function () { + var novelName = loadedCheerio(this).find('.post-title').text().trim(); + var image = loadedCheerio(this).find('img'); + var novelCover = image.attr('data-src') || image.attr('src'); + var novelUrl = loadedCheerio(this).find('.post-title') + .find('a') + .attr('href') || ''; + var novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + novels.push(novel); + }); + return [2 /*return*/, novels]; + } + }); + }); + }; + MadaraPlugin.prototype.parseNovelAndChapters = function (novelUrl) { + var _a; + return __awaiter(this, void 0, void 0, function () { + var novel, body, loadedCheerio, html, novelId, formData, chapters; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + novel = { + url: novelUrl, + }; + return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl).then(function (res) { return res.text(); })]; + case 1: + body = _b.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.manga-title-badges, #manga-title span').remove(); + novel.name = + loadedCheerio('.post-title h1').text().trim() || + loadedCheerio('#manga-title h1').text(); + novel.cover = + loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || + loadedCheerio('.summary_image > a > img').attr('data-src') || + loadedCheerio('.summary_image > a > img').attr('src') || + defaultCover_1.defaultCover; + loadedCheerio('.post-content_item, .post-content').each(function () { + var detailName = loadedCheerio(this).find('h5').text().trim(); + var detail = loadedCheerio(this).find('.summary-content').text().trim(); + switch (detailName) { + case 'Genre(s)': + case 'التصنيفات': + novel.genres = detail.replace(/[\\t\\n]/g, ','); + break; + case 'Author(s)': + case 'المؤلف': + case 'المؤلف (ين)': + novel.author = detail; + break; + case 'Status': + case 'الحالة': + novel.status = + detail.includes('OnGoing') || detail.includes('مستمرة') + ? novelStatus_1.NovelStatus.Ongoing + : novelStatus_1.NovelStatus.Completed; + break; + } + }); + loadedCheerio('div.summary__content .code-block,script').remove(); + novel.summary = + loadedCheerio('div.summary__content').text().trim() || + loadedCheerio('#tab-manga-about').text().trim() || + loadedCheerio('.post-content_item h5:contains("Summary")').next().text().trim(); + if (!(((_a = this.options) === null || _a === void 0 ? void 0 : _a.useNewChapterEndpoint) !== true)) return [3 /*break*/, 3]; + novelId = loadedCheerio('.rating-post-id').attr('value') || + loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; + formData = new FormData(); + formData.append("action", "manga_get_chapters"); + formData.append("manga", novelId); + return [4 /*yield*/, (0, fetch_1.fetchApi)(this.site + 'wp-admin/admin-ajax.php', { + method: 'POST', + body: formData, + }) + .then(function (res) { return res.text(); })]; + case 2: + html = _b.sent(); + return [3 /*break*/, 5]; + case 3: return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl + 'ajax/chapters/', { method: 'POST' }) + .then(function (res) { return res.text(); })]; + case 4: + html = _b.sent(); + _b.label = 5; + case 5: + if (html !== '0') { + loadedCheerio = (0, cheerio_1.load)(html); + } + chapters = []; + loadedCheerio('.wp-manga-chapter').each(function () { + var chapterName = loadedCheerio(this).find('a').text().trim(); + var releaseDate = null; + releaseDate = loadedCheerio(this) + .find('span.chapter-release-date') + .text() + .trim(); + if (releaseDate) { + releaseDate = (0, parseMadaraDate_1.parseMadaraDate)(releaseDate); + } + else { + /** + * Insert current date + */ + releaseDate = (0, dayjs_1.default)().format('LL'); + } + var chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); + }); + novel.chapters = chapters.reverse(); + return [2 /*return*/, novel]; + } + }); + }); + }; + MadaraPlugin.prototype.parseChapter = function (chapterUrl) { + return __awaiter(this, void 0, void 0, function () { + var body, loadedCheerio, chapterText; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, (0, fetch_1.fetchApi)(chapterUrl).then(function (res) { return res.text(); })]; + case 1: + body = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + chapterText = loadedCheerio('.text-left').html() || + loadedCheerio('.text-right').html() || + loadedCheerio('.entry-content').html() || ""; + return [2 /*return*/, chapterText]; + } + }); + }); + }; + MadaraPlugin.prototype.searchNovels = function (searchTerm, pageNo) { + return __awaiter(this, void 0, void 0, function () { + var novels, url, body, loadedCheerio; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + novels = []; + url = this.site + "?s=" + searchTerm + "&post_type=wp-manga"; + return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })]; + case 1: + body = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.c-tabs-item__content').each(function () { + var novelName = loadedCheerio(this).find('.post-title').text().trim(); + var image = loadedCheerio(this).find('img'); + var novelCover = image.attr('data-src') || image.attr('src'); + var novelUrl = loadedCheerio(this) + .find('.post-title') + .find('a') + .attr('href') || ''; + var novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + novels.push(novel); + }); + return [2 /*return*/, novels]; + } + }); + }); + }; + MadaraPlugin.prototype.fetchImage = function (url) { + return __awaiter(this, void 0, void 0, function () { + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, (0, fetch_1.fetchFile)(url, {})]; + case 1: return [2 /*return*/, _a.sent()]; + } + }); + }); + }; + return MadaraPlugin; +}()); +var plugin = new MadaraPlugin({ "id": "lnheaven", "sourceSite": "https://lightnovelheaven.com/", "sourceName": "LightNovelHeaven", "filters": [{ "key": "sort", "label": "Order by", "values": [{ "label": "Rating", "value": "rating" }, { "label": "A-Z", "value": "alphabet" }, { "label": "Latest", "value": "latest" }, { "label": "Most Views", "value": "views" }, { "label": "New", "value": "new-manga" }, { "label": "Trending", "value": "trending" }], "inputType": "Picker" }], "options": { "path": { "novels": "series", "novel": "series", "chapter": "series" }, "useNewChapterEndpoint": true, "lang": "English" } }); +exports.default = plugin; diff --git a/.js/plugins/english/LunarLetters[madara].js b/.js/plugins/english/LunarLetters[madara].js new file mode 100644 index 0000000..9187e6c --- /dev/null +++ b/.js/plugins/english/LunarLetters[madara].js @@ -0,0 +1,269 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __generator = (this && this.__generator) || function (thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (g && (g = 0, op[0] && (_ = 0)), _) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +}; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var fetch_1 = require("@libs/fetch"); +var cheerio_1 = require("cheerio"); +var defaultCover_1 = require("@libs/defaultCover"); +var novelStatus_1 = require("@libs/novelStatus"); +var parseMadaraDate_1 = require("@libs/parseMadaraDate"); +var dayjs_1 = __importDefault(require("dayjs")); +var MadaraDefaultPath = { + novels: 'novel', + novel: 'novel', + chapter: 'novel' +}; +var MadaraPlugin = /** @class */ (function () { + function MadaraPlugin(metadata) { + this.id = metadata.id; + this.name = metadata.sourceName + "[madara]"; + var iconFileName = metadata.sourceName.replace(/\s+/g, "").toLowerCase(); + this.icon = "multisrc/madara/icons/".concat(iconFileName, ".png"); + this.site = metadata.sourceSite; + this.version = "1.0.0"; + this.userAgent = ""; + this.cookieString = ""; + this.options = metadata.options; + this.filter = metadata.filters; + } + MadaraPlugin.prototype.popularNovels = function (pageNo, _a) { + var _b, _c, _d, _e, _f, _g; + var filters = _a.filters, showLatestNovels = _a.showLatestNovels; + return __awaiter(this, void 0, void 0, function () { + var novels, url, body, loadedCheerio; + return __generator(this, function (_h) { + switch (_h.label) { + case 0: + novels = []; + url = this.site; + if ((filters === null || filters === void 0 ? void 0 : filters.genres) && ((_c = (_b = this.options) === null || _b === void 0 ? void 0 : _b.path) === null || _c === void 0 ? void 0 : _c.genres)) { + url += ((_e = (_d = this.options) === null || _d === void 0 ? void 0 : _d.path) === null || _e === void 0 ? void 0 : _e.genres) + filters.genres + '/'; + } + else { + url += ((_g = (_f = this.options) === null || _f === void 0 ? void 0 : _f.path) === null || _g === void 0 ? void 0 : _g.novels) ? this.options.path.novels : MadaraDefaultPath.novels; + } + url += '/page/' + pageNo + '/' + + '?m_orderby=' + (showLatestNovels ? 'latest' : ((filters === null || filters === void 0 ? void 0 : filters.sort) || 'rating')); + return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })]; + case 1: + body = _h.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.manga-title-badges').remove(); + loadedCheerio('.page-item-detail').each(function () { + var novelName = loadedCheerio(this).find('.post-title').text().trim(); + var image = loadedCheerio(this).find('img'); + var novelCover = image.attr('data-src') || image.attr('src'); + var novelUrl = loadedCheerio(this).find('.post-title') + .find('a') + .attr('href') || ''; + var novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + novels.push(novel); + }); + return [2 /*return*/, novels]; + } + }); + }); + }; + MadaraPlugin.prototype.parseNovelAndChapters = function (novelUrl) { + var _a; + return __awaiter(this, void 0, void 0, function () { + var novel, body, loadedCheerio, html, novelId, formData, chapters; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + novel = { + url: novelUrl, + }; + return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl).then(function (res) { return res.text(); })]; + case 1: + body = _b.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.manga-title-badges, #manga-title span').remove(); + novel.name = + loadedCheerio('.post-title h1').text().trim() || + loadedCheerio('#manga-title h1').text(); + novel.cover = + loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || + loadedCheerio('.summary_image > a > img').attr('data-src') || + loadedCheerio('.summary_image > a > img').attr('src') || + defaultCover_1.defaultCover; + loadedCheerio('.post-content_item, .post-content').each(function () { + var detailName = loadedCheerio(this).find('h5').text().trim(); + var detail = loadedCheerio(this).find('.summary-content').text().trim(); + switch (detailName) { + case 'Genre(s)': + case 'التصنيفات': + novel.genres = detail.replace(/[\\t\\n]/g, ','); + break; + case 'Author(s)': + case 'المؤلف': + case 'المؤلف (ين)': + novel.author = detail; + break; + case 'Status': + case 'الحالة': + novel.status = + detail.includes('OnGoing') || detail.includes('مستمرة') + ? novelStatus_1.NovelStatus.Ongoing + : novelStatus_1.NovelStatus.Completed; + break; + } + }); + loadedCheerio('div.summary__content .code-block,script').remove(); + novel.summary = + loadedCheerio('div.summary__content').text().trim() || + loadedCheerio('#tab-manga-about').text().trim() || + loadedCheerio('.post-content_item h5:contains("Summary")').next().text().trim(); + if (!(((_a = this.options) === null || _a === void 0 ? void 0 : _a.useNewChapterEndpoint) !== true)) return [3 /*break*/, 3]; + novelId = loadedCheerio('.rating-post-id').attr('value') || + loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; + formData = new FormData(); + formData.append("action", "manga_get_chapters"); + formData.append("manga", novelId); + return [4 /*yield*/, (0, fetch_1.fetchApi)(this.site + 'wp-admin/admin-ajax.php', { + method: 'POST', + body: formData, + }) + .then(function (res) { return res.text(); })]; + case 2: + html = _b.sent(); + return [3 /*break*/, 5]; + case 3: return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl + 'ajax/chapters/', { method: 'POST' }) + .then(function (res) { return res.text(); })]; + case 4: + html = _b.sent(); + _b.label = 5; + case 5: + if (html !== '0') { + loadedCheerio = (0, cheerio_1.load)(html); + } + chapters = []; + loadedCheerio('.wp-manga-chapter').each(function () { + var chapterName = loadedCheerio(this).find('a').text().trim(); + var releaseDate = null; + releaseDate = loadedCheerio(this) + .find('span.chapter-release-date') + .text() + .trim(); + if (releaseDate) { + releaseDate = (0, parseMadaraDate_1.parseMadaraDate)(releaseDate); + } + else { + /** + * Insert current date + */ + releaseDate = (0, dayjs_1.default)().format('LL'); + } + var chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); + }); + novel.chapters = chapters.reverse(); + return [2 /*return*/, novel]; + } + }); + }); + }; + MadaraPlugin.prototype.parseChapter = function (chapterUrl) { + return __awaiter(this, void 0, void 0, function () { + var body, loadedCheerio, chapterText; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, (0, fetch_1.fetchApi)(chapterUrl).then(function (res) { return res.text(); })]; + case 1: + body = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + chapterText = loadedCheerio('.text-left').html() || + loadedCheerio('.text-right').html() || + loadedCheerio('.entry-content').html() || ""; + return [2 /*return*/, chapterText]; + } + }); + }); + }; + MadaraPlugin.prototype.searchNovels = function (searchTerm, pageNo) { + return __awaiter(this, void 0, void 0, function () { + var novels, url, body, loadedCheerio; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + novels = []; + url = this.site + "?s=" + searchTerm + "&post_type=wp-manga"; + return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })]; + case 1: + body = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.c-tabs-item__content').each(function () { + var novelName = loadedCheerio(this).find('.post-title').text().trim(); + var image = loadedCheerio(this).find('img'); + var novelCover = image.attr('data-src') || image.attr('src'); + var novelUrl = loadedCheerio(this) + .find('.post-title') + .find('a') + .attr('href') || ''; + var novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + novels.push(novel); + }); + return [2 /*return*/, novels]; + } + }); + }); + }; + MadaraPlugin.prototype.fetchImage = function (url) { + return __awaiter(this, void 0, void 0, function () { + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, (0, fetch_1.fetchFile)(url, {})]; + case 1: return [2 /*return*/, _a.sent()]; + } + }); + }); + }; + return MadaraPlugin; +}()); +var plugin = new MadaraPlugin({ "id": "lunarletters", "sourceSite": "https://www.lunarletters.com/", "sourceName": "LunarLetters", "filters": [{ "key": "sort", "label": "Order by", "values": [{ "label": "Rating", "value": "rating" }, { "label": "A-Z", "value": "alphabet" }, { "label": "Latest", "value": "latest" }, { "label": "Most Views", "value": "views" }, { "label": "New", "value": "new-manga" }, { "label": "Trending", "value": "trending" }], "inputType": "Picker" }], "options": { "path": { "novels": "series", "novel": "series", "chapter": "series" }, "useNewChapterEndpoint": true, "lang": "English" } }); +exports.default = plugin; diff --git a/.js/plugins/english/MTLNovelClub[madara].js b/.js/plugins/english/MTLNovelClub[madara].js new file mode 100644 index 0000000..e178575 --- /dev/null +++ b/.js/plugins/english/MTLNovelClub[madara].js @@ -0,0 +1,269 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __generator = (this && this.__generator) || function (thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (g && (g = 0, op[0] && (_ = 0)), _) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +}; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var fetch_1 = require("@libs/fetch"); +var cheerio_1 = require("cheerio"); +var defaultCover_1 = require("@libs/defaultCover"); +var novelStatus_1 = require("@libs/novelStatus"); +var parseMadaraDate_1 = require("@libs/parseMadaraDate"); +var dayjs_1 = __importDefault(require("dayjs")); +var MadaraDefaultPath = { + novels: 'novel', + novel: 'novel', + chapter: 'novel' +}; +var MadaraPlugin = /** @class */ (function () { + function MadaraPlugin(metadata) { + this.id = metadata.id; + this.name = metadata.sourceName + "[madara]"; + var iconFileName = metadata.sourceName.replace(/\s+/g, "").toLowerCase(); + this.icon = "multisrc/madara/icons/".concat(iconFileName, ".png"); + this.site = metadata.sourceSite; + this.version = "1.0.0"; + this.userAgent = ""; + this.cookieString = ""; + this.options = metadata.options; + this.filter = metadata.filters; + } + MadaraPlugin.prototype.popularNovels = function (pageNo, _a) { + var _b, _c, _d, _e, _f, _g; + var filters = _a.filters, showLatestNovels = _a.showLatestNovels; + return __awaiter(this, void 0, void 0, function () { + var novels, url, body, loadedCheerio; + return __generator(this, function (_h) { + switch (_h.label) { + case 0: + novels = []; + url = this.site; + if ((filters === null || filters === void 0 ? void 0 : filters.genres) && ((_c = (_b = this.options) === null || _b === void 0 ? void 0 : _b.path) === null || _c === void 0 ? void 0 : _c.genres)) { + url += ((_e = (_d = this.options) === null || _d === void 0 ? void 0 : _d.path) === null || _e === void 0 ? void 0 : _e.genres) + filters.genres + '/'; + } + else { + url += ((_g = (_f = this.options) === null || _f === void 0 ? void 0 : _f.path) === null || _g === void 0 ? void 0 : _g.novels) ? this.options.path.novels : MadaraDefaultPath.novels; + } + url += '/page/' + pageNo + '/' + + '?m_orderby=' + (showLatestNovels ? 'latest' : ((filters === null || filters === void 0 ? void 0 : filters.sort) || 'rating')); + return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })]; + case 1: + body = _h.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.manga-title-badges').remove(); + loadedCheerio('.page-item-detail').each(function () { + var novelName = loadedCheerio(this).find('.post-title').text().trim(); + var image = loadedCheerio(this).find('img'); + var novelCover = image.attr('data-src') || image.attr('src'); + var novelUrl = loadedCheerio(this).find('.post-title') + .find('a') + .attr('href') || ''; + var novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + novels.push(novel); + }); + return [2 /*return*/, novels]; + } + }); + }); + }; + MadaraPlugin.prototype.parseNovelAndChapters = function (novelUrl) { + var _a; + return __awaiter(this, void 0, void 0, function () { + var novel, body, loadedCheerio, html, novelId, formData, chapters; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + novel = { + url: novelUrl, + }; + return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl).then(function (res) { return res.text(); })]; + case 1: + body = _b.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.manga-title-badges, #manga-title span').remove(); + novel.name = + loadedCheerio('.post-title h1').text().trim() || + loadedCheerio('#manga-title h1').text(); + novel.cover = + loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || + loadedCheerio('.summary_image > a > img').attr('data-src') || + loadedCheerio('.summary_image > a > img').attr('src') || + defaultCover_1.defaultCover; + loadedCheerio('.post-content_item, .post-content').each(function () { + var detailName = loadedCheerio(this).find('h5').text().trim(); + var detail = loadedCheerio(this).find('.summary-content').text().trim(); + switch (detailName) { + case 'Genre(s)': + case 'التصنيفات': + novel.genres = detail.replace(/[\\t\\n]/g, ','); + break; + case 'Author(s)': + case 'المؤلف': + case 'المؤلف (ين)': + novel.author = detail; + break; + case 'Status': + case 'الحالة': + novel.status = + detail.includes('OnGoing') || detail.includes('مستمرة') + ? novelStatus_1.NovelStatus.Ongoing + : novelStatus_1.NovelStatus.Completed; + break; + } + }); + loadedCheerio('div.summary__content .code-block,script').remove(); + novel.summary = + loadedCheerio('div.summary__content').text().trim() || + loadedCheerio('#tab-manga-about').text().trim() || + loadedCheerio('.post-content_item h5:contains("Summary")').next().text().trim(); + if (!(((_a = this.options) === null || _a === void 0 ? void 0 : _a.useNewChapterEndpoint) !== true)) return [3 /*break*/, 3]; + novelId = loadedCheerio('.rating-post-id').attr('value') || + loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; + formData = new FormData(); + formData.append("action", "manga_get_chapters"); + formData.append("manga", novelId); + return [4 /*yield*/, (0, fetch_1.fetchApi)(this.site + 'wp-admin/admin-ajax.php', { + method: 'POST', + body: formData, + }) + .then(function (res) { return res.text(); })]; + case 2: + html = _b.sent(); + return [3 /*break*/, 5]; + case 3: return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl + 'ajax/chapters/', { method: 'POST' }) + .then(function (res) { return res.text(); })]; + case 4: + html = _b.sent(); + _b.label = 5; + case 5: + if (html !== '0') { + loadedCheerio = (0, cheerio_1.load)(html); + } + chapters = []; + loadedCheerio('.wp-manga-chapter').each(function () { + var chapterName = loadedCheerio(this).find('a').text().trim(); + var releaseDate = null; + releaseDate = loadedCheerio(this) + .find('span.chapter-release-date') + .text() + .trim(); + if (releaseDate) { + releaseDate = (0, parseMadaraDate_1.parseMadaraDate)(releaseDate); + } + else { + /** + * Insert current date + */ + releaseDate = (0, dayjs_1.default)().format('LL'); + } + var chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); + }); + novel.chapters = chapters.reverse(); + return [2 /*return*/, novel]; + } + }); + }); + }; + MadaraPlugin.prototype.parseChapter = function (chapterUrl) { + return __awaiter(this, void 0, void 0, function () { + var body, loadedCheerio, chapterText; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, (0, fetch_1.fetchApi)(chapterUrl).then(function (res) { return res.text(); })]; + case 1: + body = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + chapterText = loadedCheerio('.text-left').html() || + loadedCheerio('.text-right').html() || + loadedCheerio('.entry-content').html() || ""; + return [2 /*return*/, chapterText]; + } + }); + }); + }; + MadaraPlugin.prototype.searchNovels = function (searchTerm, pageNo) { + return __awaiter(this, void 0, void 0, function () { + var novels, url, body, loadedCheerio; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + novels = []; + url = this.site + "?s=" + searchTerm + "&post_type=wp-manga"; + return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })]; + case 1: + body = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.c-tabs-item__content').each(function () { + var novelName = loadedCheerio(this).find('.post-title').text().trim(); + var image = loadedCheerio(this).find('img'); + var novelCover = image.attr('data-src') || image.attr('src'); + var novelUrl = loadedCheerio(this) + .find('.post-title') + .find('a') + .attr('href') || ''; + var novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + novels.push(novel); + }); + return [2 /*return*/, novels]; + } + }); + }); + }; + MadaraPlugin.prototype.fetchImage = function (url) { + return __awaiter(this, void 0, void 0, function () { + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, (0, fetch_1.fetchFile)(url, {})]; + case 1: return [2 /*return*/, _a.sent()]; + } + }); + }); + }; + return MadaraPlugin; +}()); +var plugin = new MadaraPlugin({ "id": "mtlnovel.club", "sourceSite": "https://mtlnovel.club/", "sourceName": "MTLNovel.Club", "filters": [], "options": { "useNewChapterEndpoint": true, "lang": "English" } }); +exports.default = plugin; diff --git a/.js/plugins/english/MTLNovel[madara].js b/.js/plugins/english/MTLNovel[madara].js new file mode 100644 index 0000000..fef3caa --- /dev/null +++ b/.js/plugins/english/MTLNovel[madara].js @@ -0,0 +1,269 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __generator = (this && this.__generator) || function (thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (g && (g = 0, op[0] && (_ = 0)), _) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +}; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var fetch_1 = require("@libs/fetch"); +var cheerio_1 = require("cheerio"); +var defaultCover_1 = require("@libs/defaultCover"); +var novelStatus_1 = require("@libs/novelStatus"); +var parseMadaraDate_1 = require("@libs/parseMadaraDate"); +var dayjs_1 = __importDefault(require("dayjs")); +var MadaraDefaultPath = { + novels: 'novel', + novel: 'novel', + chapter: 'novel' +}; +var MadaraPlugin = /** @class */ (function () { + function MadaraPlugin(metadata) { + this.id = metadata.id; + this.name = metadata.sourceName + "[madara]"; + var iconFileName = metadata.sourceName.replace(/\s+/g, "").toLowerCase(); + this.icon = "multisrc/madara/icons/".concat(iconFileName, ".png"); + this.site = metadata.sourceSite; + this.version = "1.0.0"; + this.userAgent = ""; + this.cookieString = ""; + this.options = metadata.options; + this.filter = metadata.filters; + } + MadaraPlugin.prototype.popularNovels = function (pageNo, _a) { + var _b, _c, _d, _e, _f, _g; + var filters = _a.filters, showLatestNovels = _a.showLatestNovels; + return __awaiter(this, void 0, void 0, function () { + var novels, url, body, loadedCheerio; + return __generator(this, function (_h) { + switch (_h.label) { + case 0: + novels = []; + url = this.site; + if ((filters === null || filters === void 0 ? void 0 : filters.genres) && ((_c = (_b = this.options) === null || _b === void 0 ? void 0 : _b.path) === null || _c === void 0 ? void 0 : _c.genres)) { + url += ((_e = (_d = this.options) === null || _d === void 0 ? void 0 : _d.path) === null || _e === void 0 ? void 0 : _e.genres) + filters.genres + '/'; + } + else { + url += ((_g = (_f = this.options) === null || _f === void 0 ? void 0 : _f.path) === null || _g === void 0 ? void 0 : _g.novels) ? this.options.path.novels : MadaraDefaultPath.novels; + } + url += '/page/' + pageNo + '/' + + '?m_orderby=' + (showLatestNovels ? 'latest' : ((filters === null || filters === void 0 ? void 0 : filters.sort) || 'rating')); + return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })]; + case 1: + body = _h.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.manga-title-badges').remove(); + loadedCheerio('.page-item-detail').each(function () { + var novelName = loadedCheerio(this).find('.post-title').text().trim(); + var image = loadedCheerio(this).find('img'); + var novelCover = image.attr('data-src') || image.attr('src'); + var novelUrl = loadedCheerio(this).find('.post-title') + .find('a') + .attr('href') || ''; + var novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + novels.push(novel); + }); + return [2 /*return*/, novels]; + } + }); + }); + }; + MadaraPlugin.prototype.parseNovelAndChapters = function (novelUrl) { + var _a; + return __awaiter(this, void 0, void 0, function () { + var novel, body, loadedCheerio, html, novelId, formData, chapters; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + novel = { + url: novelUrl, + }; + return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl).then(function (res) { return res.text(); })]; + case 1: + body = _b.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.manga-title-badges, #manga-title span').remove(); + novel.name = + loadedCheerio('.post-title h1').text().trim() || + loadedCheerio('#manga-title h1').text(); + novel.cover = + loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || + loadedCheerio('.summary_image > a > img').attr('data-src') || + loadedCheerio('.summary_image > a > img').attr('src') || + defaultCover_1.defaultCover; + loadedCheerio('.post-content_item, .post-content').each(function () { + var detailName = loadedCheerio(this).find('h5').text().trim(); + var detail = loadedCheerio(this).find('.summary-content').text().trim(); + switch (detailName) { + case 'Genre(s)': + case 'التصنيفات': + novel.genres = detail.replace(/[\\t\\n]/g, ','); + break; + case 'Author(s)': + case 'المؤلف': + case 'المؤلف (ين)': + novel.author = detail; + break; + case 'Status': + case 'الحالة': + novel.status = + detail.includes('OnGoing') || detail.includes('مستمرة') + ? novelStatus_1.NovelStatus.Ongoing + : novelStatus_1.NovelStatus.Completed; + break; + } + }); + loadedCheerio('div.summary__content .code-block,script').remove(); + novel.summary = + loadedCheerio('div.summary__content').text().trim() || + loadedCheerio('#tab-manga-about').text().trim() || + loadedCheerio('.post-content_item h5:contains("Summary")').next().text().trim(); + if (!(((_a = this.options) === null || _a === void 0 ? void 0 : _a.useNewChapterEndpoint) !== true)) return [3 /*break*/, 3]; + novelId = loadedCheerio('.rating-post-id').attr('value') || + loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; + formData = new FormData(); + formData.append("action", "manga_get_chapters"); + formData.append("manga", novelId); + return [4 /*yield*/, (0, fetch_1.fetchApi)(this.site + 'wp-admin/admin-ajax.php', { + method: 'POST', + body: formData, + }) + .then(function (res) { return res.text(); })]; + case 2: + html = _b.sent(); + return [3 /*break*/, 5]; + case 3: return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl + 'ajax/chapters/', { method: 'POST' }) + .then(function (res) { return res.text(); })]; + case 4: + html = _b.sent(); + _b.label = 5; + case 5: + if (html !== '0') { + loadedCheerio = (0, cheerio_1.load)(html); + } + chapters = []; + loadedCheerio('.wp-manga-chapter').each(function () { + var chapterName = loadedCheerio(this).find('a').text().trim(); + var releaseDate = null; + releaseDate = loadedCheerio(this) + .find('span.chapter-release-date') + .text() + .trim(); + if (releaseDate) { + releaseDate = (0, parseMadaraDate_1.parseMadaraDate)(releaseDate); + } + else { + /** + * Insert current date + */ + releaseDate = (0, dayjs_1.default)().format('LL'); + } + var chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); + }); + novel.chapters = chapters.reverse(); + return [2 /*return*/, novel]; + } + }); + }); + }; + MadaraPlugin.prototype.parseChapter = function (chapterUrl) { + return __awaiter(this, void 0, void 0, function () { + var body, loadedCheerio, chapterText; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, (0, fetch_1.fetchApi)(chapterUrl).then(function (res) { return res.text(); })]; + case 1: + body = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + chapterText = loadedCheerio('.text-left').html() || + loadedCheerio('.text-right').html() || + loadedCheerio('.entry-content').html() || ""; + return [2 /*return*/, chapterText]; + } + }); + }); + }; + MadaraPlugin.prototype.searchNovels = function (searchTerm, pageNo) { + return __awaiter(this, void 0, void 0, function () { + var novels, url, body, loadedCheerio; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + novels = []; + url = this.site + "?s=" + searchTerm + "&post_type=wp-manga"; + return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })]; + case 1: + body = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.c-tabs-item__content').each(function () { + var novelName = loadedCheerio(this).find('.post-title').text().trim(); + var image = loadedCheerio(this).find('img'); + var novelCover = image.attr('data-src') || image.attr('src'); + var novelUrl = loadedCheerio(this) + .find('.post-title') + .find('a') + .attr('href') || ''; + var novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + novels.push(novel); + }); + return [2 /*return*/, novels]; + } + }); + }); + }; + MadaraPlugin.prototype.fetchImage = function (url) { + return __awaiter(this, void 0, void 0, function () { + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, (0, fetch_1.fetchFile)(url, {})]; + case 1: return [2 /*return*/, _a.sent()]; + } + }); + }); + }; + return MadaraPlugin; +}()); +var plugin = new MadaraPlugin({ "id": "mtl-novel", "sourceSite": "https://mtl-novel.com/", "sourceName": "MTL-Novel", "filters": [{ "key": "sort", "label": "Order by", "values": [{ "label": "Rating", "value": "rating" }, { "label": "A-Z", "value": "alphabet" }, { "label": "Latest", "value": "latest" }, { "label": "Most Views", "value": "views" }, { "label": "New", "value": "new-manga" }, { "label": "Trending", "value": "trending" }], "inputType": "Picker" }, { "key": "genres", "label": "GENRES", "values": [{ "label": "Action", "value": "action" }, { "label": "Adult", "value": "adult" }, { "label": "Adventure", "value": "adventure" }, { "label": "Chinese", "value": "chinese" }, { "label": "Comedy", "value": "comedy" }, { "label": "Conan", "value": "conan" }, { "label": "Drama", "value": "drama" }, { "label": "Erciyuan", "value": "erciyuan" }, { "label": "Fairy Tail", "value": "fairy-tail" }, { "label": "Faloo", "value": "faloo" }, { "label": "Fan-Fiction", "value": "fan-fiction" }, { "label": "Fantasy", "value": "fantasy" }, { "label": "FoodWars!", "value": "foodwars" }, { "label": "Game", "value": "game" }, { "label": "Gender Bender", "value": "gender-bender" }, { "label": "Harem", "value": "harem" }, { "label": "Historical", "value": "historical" }, { "label": "Horror", "value": "horror" }, { "label": "Hunter x Hunter", "value": "hunter-x-hunter" }, { "label": "Japanese", "value": "japanese" }, { "label": "Jojo", "value": "jojo" }, { "label": "Josei", "value": "josei" }, { "label": "Korean", "value": "korean" }, { "label": "Martial Arts", "value": "martial-arts" }, { "label": "Marvel", "value": "marvel" }, { "label": "Mature", "value": "mature" }, { "label": "Mecha", "value": "mecha" }, { "label": "Military", "value": "military" }, { "label": "Mystery", "value": "mystery" }, { "label": "Naruto", "value": "naruto" }, { "label": "One piece", "value": "one-piece" }, { "label": "Pokemon", "value": "pokemon" }, { "label": "Psychological", "value": "psychological" }, { "label": "Romance", "value": "romance" }, { "label": "School Life", "value": "school-life" }, { "label": "Sci-fi", "value": "sci-fi" }, { "label": "Seinen", "value": "seinen" }, { "label": "Shoujo", "value": "shoujo" }, { "label": "Shoujo Ai", "value": "shoujo-ai" }, { "label": "Shounen Ai", "value": "shounen-ai" }, { "label": "Slice of Life", "value": "slice-of-life" }, { "label": "Smut", "value": "smut" }, { "label": "Sport", "value": "sport" }, { "label": "Sports", "value": "sports" }, { "label": "Supernatural", "value": "supernatural" }, { "label": "System", "value": "system" }, { "label": "Tragedy", "value": "tragedy" }, { "label": "Urban", "value": "urban" }, { "label": "Urban Life", "value": "urban-life" }, { "label": "Wuxia", "value": "wuxia" }, { "label": "Xianxia", "value": "xianxia" }, { "label": "Xuanhuan", "value": "xuanhuan" }, { "label": "Yaoi", "value": "yaoi" }, { "label": "Yuri", "value": "yuri" }], "inputType": "Picker" }], "options": { "path": { "genres": "manga-genre" }, "useNewChapterEndpoint": true, "lang": "English" } }); +exports.default = plugin; diff --git a/.js/plugins/english/MostNovel[madara].js b/.js/plugins/english/MostNovel[madara].js new file mode 100644 index 0000000..95263f5 --- /dev/null +++ b/.js/plugins/english/MostNovel[madara].js @@ -0,0 +1,269 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __generator = (this && this.__generator) || function (thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (g && (g = 0, op[0] && (_ = 0)), _) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +}; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var fetch_1 = require("@libs/fetch"); +var cheerio_1 = require("cheerio"); +var defaultCover_1 = require("@libs/defaultCover"); +var novelStatus_1 = require("@libs/novelStatus"); +var parseMadaraDate_1 = require("@libs/parseMadaraDate"); +var dayjs_1 = __importDefault(require("dayjs")); +var MadaraDefaultPath = { + novels: 'novel', + novel: 'novel', + chapter: 'novel' +}; +var MadaraPlugin = /** @class */ (function () { + function MadaraPlugin(metadata) { + this.id = metadata.id; + this.name = metadata.sourceName + "[madara]"; + var iconFileName = metadata.sourceName.replace(/\s+/g, "").toLowerCase(); + this.icon = "multisrc/madara/icons/".concat(iconFileName, ".png"); + this.site = metadata.sourceSite; + this.version = "1.0.0"; + this.userAgent = ""; + this.cookieString = ""; + this.options = metadata.options; + this.filter = metadata.filters; + } + MadaraPlugin.prototype.popularNovels = function (pageNo, _a) { + var _b, _c, _d, _e, _f, _g; + var filters = _a.filters, showLatestNovels = _a.showLatestNovels; + return __awaiter(this, void 0, void 0, function () { + var novels, url, body, loadedCheerio; + return __generator(this, function (_h) { + switch (_h.label) { + case 0: + novels = []; + url = this.site; + if ((filters === null || filters === void 0 ? void 0 : filters.genres) && ((_c = (_b = this.options) === null || _b === void 0 ? void 0 : _b.path) === null || _c === void 0 ? void 0 : _c.genres)) { + url += ((_e = (_d = this.options) === null || _d === void 0 ? void 0 : _d.path) === null || _e === void 0 ? void 0 : _e.genres) + filters.genres + '/'; + } + else { + url += ((_g = (_f = this.options) === null || _f === void 0 ? void 0 : _f.path) === null || _g === void 0 ? void 0 : _g.novels) ? this.options.path.novels : MadaraDefaultPath.novels; + } + url += '/page/' + pageNo + '/' + + '?m_orderby=' + (showLatestNovels ? 'latest' : ((filters === null || filters === void 0 ? void 0 : filters.sort) || 'rating')); + return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })]; + case 1: + body = _h.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.manga-title-badges').remove(); + loadedCheerio('.page-item-detail').each(function () { + var novelName = loadedCheerio(this).find('.post-title').text().trim(); + var image = loadedCheerio(this).find('img'); + var novelCover = image.attr('data-src') || image.attr('src'); + var novelUrl = loadedCheerio(this).find('.post-title') + .find('a') + .attr('href') || ''; + var novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + novels.push(novel); + }); + return [2 /*return*/, novels]; + } + }); + }); + }; + MadaraPlugin.prototype.parseNovelAndChapters = function (novelUrl) { + var _a; + return __awaiter(this, void 0, void 0, function () { + var novel, body, loadedCheerio, html, novelId, formData, chapters; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + novel = { + url: novelUrl, + }; + return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl).then(function (res) { return res.text(); })]; + case 1: + body = _b.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.manga-title-badges, #manga-title span').remove(); + novel.name = + loadedCheerio('.post-title h1').text().trim() || + loadedCheerio('#manga-title h1').text(); + novel.cover = + loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || + loadedCheerio('.summary_image > a > img').attr('data-src') || + loadedCheerio('.summary_image > a > img').attr('src') || + defaultCover_1.defaultCover; + loadedCheerio('.post-content_item, .post-content').each(function () { + var detailName = loadedCheerio(this).find('h5').text().trim(); + var detail = loadedCheerio(this).find('.summary-content').text().trim(); + switch (detailName) { + case 'Genre(s)': + case 'التصنيفات': + novel.genres = detail.replace(/[\\t\\n]/g, ','); + break; + case 'Author(s)': + case 'المؤلف': + case 'المؤلف (ين)': + novel.author = detail; + break; + case 'Status': + case 'الحالة': + novel.status = + detail.includes('OnGoing') || detail.includes('مستمرة') + ? novelStatus_1.NovelStatus.Ongoing + : novelStatus_1.NovelStatus.Completed; + break; + } + }); + loadedCheerio('div.summary__content .code-block,script').remove(); + novel.summary = + loadedCheerio('div.summary__content').text().trim() || + loadedCheerio('#tab-manga-about').text().trim() || + loadedCheerio('.post-content_item h5:contains("Summary")').next().text().trim(); + if (!(((_a = this.options) === null || _a === void 0 ? void 0 : _a.useNewChapterEndpoint) !== true)) return [3 /*break*/, 3]; + novelId = loadedCheerio('.rating-post-id').attr('value') || + loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; + formData = new FormData(); + formData.append("action", "manga_get_chapters"); + formData.append("manga", novelId); + return [4 /*yield*/, (0, fetch_1.fetchApi)(this.site + 'wp-admin/admin-ajax.php', { + method: 'POST', + body: formData, + }) + .then(function (res) { return res.text(); })]; + case 2: + html = _b.sent(); + return [3 /*break*/, 5]; + case 3: return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl + 'ajax/chapters/', { method: 'POST' }) + .then(function (res) { return res.text(); })]; + case 4: + html = _b.sent(); + _b.label = 5; + case 5: + if (html !== '0') { + loadedCheerio = (0, cheerio_1.load)(html); + } + chapters = []; + loadedCheerio('.wp-manga-chapter').each(function () { + var chapterName = loadedCheerio(this).find('a').text().trim(); + var releaseDate = null; + releaseDate = loadedCheerio(this) + .find('span.chapter-release-date') + .text() + .trim(); + if (releaseDate) { + releaseDate = (0, parseMadaraDate_1.parseMadaraDate)(releaseDate); + } + else { + /** + * Insert current date + */ + releaseDate = (0, dayjs_1.default)().format('LL'); + } + var chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); + }); + novel.chapters = chapters.reverse(); + return [2 /*return*/, novel]; + } + }); + }); + }; + MadaraPlugin.prototype.parseChapter = function (chapterUrl) { + return __awaiter(this, void 0, void 0, function () { + var body, loadedCheerio, chapterText; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, (0, fetch_1.fetchApi)(chapterUrl).then(function (res) { return res.text(); })]; + case 1: + body = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + chapterText = loadedCheerio('.text-left').html() || + loadedCheerio('.text-right').html() || + loadedCheerio('.entry-content').html() || ""; + return [2 /*return*/, chapterText]; + } + }); + }); + }; + MadaraPlugin.prototype.searchNovels = function (searchTerm, pageNo) { + return __awaiter(this, void 0, void 0, function () { + var novels, url, body, loadedCheerio; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + novels = []; + url = this.site + "?s=" + searchTerm + "&post_type=wp-manga"; + return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })]; + case 1: + body = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.c-tabs-item__content').each(function () { + var novelName = loadedCheerio(this).find('.post-title').text().trim(); + var image = loadedCheerio(this).find('img'); + var novelCover = image.attr('data-src') || image.attr('src'); + var novelUrl = loadedCheerio(this) + .find('.post-title') + .find('a') + .attr('href') || ''; + var novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + novels.push(novel); + }); + return [2 /*return*/, novels]; + } + }); + }); + }; + MadaraPlugin.prototype.fetchImage = function (url) { + return __awaiter(this, void 0, void 0, function () { + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, (0, fetch_1.fetchFile)(url, {})]; + case 1: return [2 /*return*/, _a.sent()]; + } + }); + }); + }; + return MadaraPlugin; +}()); +var plugin = new MadaraPlugin({ "id": "mostnovel", "sourceSite": "https://mostnovel.com/", "sourceName": "MostNovel", "filters": [{ "key": "sort", "label": "Order by", "values": [{ "label": "Rating", "value": "rating" }, { "label": "A-Z", "value": "alphabet" }, { "label": "Latest", "value": "latest" }, { "label": "Most Views", "value": "views" }, { "label": "New", "value": "new-manga" }, { "label": "Trending", "value": "trending" }], "inputType": "Picker" }, { "key": "genres", "label": "GENRES", "values": [{ "label": "ACG", "value": "acg" }, { "label": "Action", "value": "action" }, { "label": "Adult", "value": "adult" }, { "label": "Adventure", "value": "adventure" }, { "label": "AGA", "value": "aga" }, { "label": "Anime", "value": "anime" }, { "label": "Anime & Comics", "value": "anime-comics" }, { "label": "Bender", "value": "bender" }, { "label": "BL", "value": "bl" }, { "label": "Cartoon", "value": "cartoon" }, { "label": "Comedy", "value": "comedy" }, { "label": "Comic", "value": "comic" }, { "label": "Contemporary Romance", "value": "contemporary-romance" }, { "label": "Cooking", "value": "cooking" }, { "label": "Cultivation", "value": "cultivation" }, { "label": "Detective", "value": "detective" }, { "label": "Doujinshi", "value": "doujinshi" }, { "label": "Drama", "value": "drama" }, { "label": "Eastern Fantasy", "value": "eastern-fantasy" }, { "label": "Ecchi", "value": "ecchi" }, { "label": "Fantasy", "value": "fantasy" }, { "label": "Gender Bender", "value": "gender-bender" }, { "label": "Harem", "value": "harem" }, { "label": "Historical", "value": "historical" }, { "label": "Horror", "value": "horror" }, { "label": "Horror&Thriller", "value": "horrorthriller" }, { "label": "Josei", "value": "josei" }, { "label": "Live action", "value": "live-action" }, { "label": "Magical Realism", "value": "magical-realism" }, { "label": "Manga", "value": "manga" }, { "label": "Manhua", "value": "manhua" }, { "label": "Manhwa", "value": "manhwa" }, { "label": "Martial Arts", "value": "martial-arts" }, { "label": "Mature", "value": "mature" }, { "label": "Mecha", "value": "mecha" }, { "label": "Modern", "value": "modern" }, { "label": "Movies", "value": "movies" }, { "label": "Mystery", "value": "mystery" }, { "label": "One shot", "value": "one-shot" }, { "label": "Psychological", "value": "psychological" }, { "label": "Romance", "value": "romance" }, { "label": "School Life", "value": "school-life" }, { "label": "Sci-fi", "value": "sci-fi" }, { "label": "Seinen", "value": "seinen" }, { "label": "Shoujo", "value": "shoujo" }, { "label": "Shoujo Ai", "value": "shoujo-ai" }, { "label": "Shounen", "value": "shounen" }, { "label": "Shounen Ai", "value": "shounen-ai" }, { "label": "Slice of Life", "value": "slice-of-life" }, { "label": "Smart MC", "value": "smart-mc" }, { "label": "Smut", "value": "smut" }, { "label": "Soft Yaoi", "value": "soft-yaoi" }, { "label": "Soft Yuri", "value": "soft-yuri" }, { "label": "Sports", "value": "sports" }, { "label": "Supernatural", "value": "supernatural" }, { "label": "Tragedy", "value": "tragedy" }, { "label": "Urban Life", "value": "urban-life" }, { "label": "Video Games", "value": "video-games" }, { "label": "Webtoon", "value": "webtoon" }, { "label": "Wuxia", "value": "wuxia" }, { "label": "Xianxia", "value": "xianxia" }, { "label": "Xuanhuan", "value": "xuanhuan" }, { "label": "Yaoi", "value": "yaoi" }, { "label": "Yuri", "value": "yuri" }], "inputType": "Picker" }], "options": { "path": { "novels": "manga", "novel": "manga", "chapter": "manga", "genres": "manga-genre" }, "lang": "English" } }); +exports.default = plugin; diff --git a/.js/plugins/english/MysticalSeries[madara].js b/.js/plugins/english/MysticalSeries[madara].js new file mode 100644 index 0000000..829e1fb --- /dev/null +++ b/.js/plugins/english/MysticalSeries[madara].js @@ -0,0 +1,269 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __generator = (this && this.__generator) || function (thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (g && (g = 0, op[0] && (_ = 0)), _) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +}; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var fetch_1 = require("@libs/fetch"); +var cheerio_1 = require("cheerio"); +var defaultCover_1 = require("@libs/defaultCover"); +var novelStatus_1 = require("@libs/novelStatus"); +var parseMadaraDate_1 = require("@libs/parseMadaraDate"); +var dayjs_1 = __importDefault(require("dayjs")); +var MadaraDefaultPath = { + novels: 'novel', + novel: 'novel', + chapter: 'novel' +}; +var MadaraPlugin = /** @class */ (function () { + function MadaraPlugin(metadata) { + this.id = metadata.id; + this.name = metadata.sourceName + "[madara]"; + var iconFileName = metadata.sourceName.replace(/\s+/g, "").toLowerCase(); + this.icon = "multisrc/madara/icons/".concat(iconFileName, ".png"); + this.site = metadata.sourceSite; + this.version = "1.0.0"; + this.userAgent = ""; + this.cookieString = ""; + this.options = metadata.options; + this.filter = metadata.filters; + } + MadaraPlugin.prototype.popularNovels = function (pageNo, _a) { + var _b, _c, _d, _e, _f, _g; + var filters = _a.filters, showLatestNovels = _a.showLatestNovels; + return __awaiter(this, void 0, void 0, function () { + var novels, url, body, loadedCheerio; + return __generator(this, function (_h) { + switch (_h.label) { + case 0: + novels = []; + url = this.site; + if ((filters === null || filters === void 0 ? void 0 : filters.genres) && ((_c = (_b = this.options) === null || _b === void 0 ? void 0 : _b.path) === null || _c === void 0 ? void 0 : _c.genres)) { + url += ((_e = (_d = this.options) === null || _d === void 0 ? void 0 : _d.path) === null || _e === void 0 ? void 0 : _e.genres) + filters.genres + '/'; + } + else { + url += ((_g = (_f = this.options) === null || _f === void 0 ? void 0 : _f.path) === null || _g === void 0 ? void 0 : _g.novels) ? this.options.path.novels : MadaraDefaultPath.novels; + } + url += '/page/' + pageNo + '/' + + '?m_orderby=' + (showLatestNovels ? 'latest' : ((filters === null || filters === void 0 ? void 0 : filters.sort) || 'rating')); + return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })]; + case 1: + body = _h.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.manga-title-badges').remove(); + loadedCheerio('.page-item-detail').each(function () { + var novelName = loadedCheerio(this).find('.post-title').text().trim(); + var image = loadedCheerio(this).find('img'); + var novelCover = image.attr('data-src') || image.attr('src'); + var novelUrl = loadedCheerio(this).find('.post-title') + .find('a') + .attr('href') || ''; + var novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + novels.push(novel); + }); + return [2 /*return*/, novels]; + } + }); + }); + }; + MadaraPlugin.prototype.parseNovelAndChapters = function (novelUrl) { + var _a; + return __awaiter(this, void 0, void 0, function () { + var novel, body, loadedCheerio, html, novelId, formData, chapters; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + novel = { + url: novelUrl, + }; + return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl).then(function (res) { return res.text(); })]; + case 1: + body = _b.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.manga-title-badges, #manga-title span').remove(); + novel.name = + loadedCheerio('.post-title h1').text().trim() || + loadedCheerio('#manga-title h1').text(); + novel.cover = + loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || + loadedCheerio('.summary_image > a > img').attr('data-src') || + loadedCheerio('.summary_image > a > img').attr('src') || + defaultCover_1.defaultCover; + loadedCheerio('.post-content_item, .post-content').each(function () { + var detailName = loadedCheerio(this).find('h5').text().trim(); + var detail = loadedCheerio(this).find('.summary-content').text().trim(); + switch (detailName) { + case 'Genre(s)': + case 'التصنيفات': + novel.genres = detail.replace(/[\\t\\n]/g, ','); + break; + case 'Author(s)': + case 'المؤلف': + case 'المؤلف (ين)': + novel.author = detail; + break; + case 'Status': + case 'الحالة': + novel.status = + detail.includes('OnGoing') || detail.includes('مستمرة') + ? novelStatus_1.NovelStatus.Ongoing + : novelStatus_1.NovelStatus.Completed; + break; + } + }); + loadedCheerio('div.summary__content .code-block,script').remove(); + novel.summary = + loadedCheerio('div.summary__content').text().trim() || + loadedCheerio('#tab-manga-about').text().trim() || + loadedCheerio('.post-content_item h5:contains("Summary")').next().text().trim(); + if (!(((_a = this.options) === null || _a === void 0 ? void 0 : _a.useNewChapterEndpoint) !== true)) return [3 /*break*/, 3]; + novelId = loadedCheerio('.rating-post-id').attr('value') || + loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; + formData = new FormData(); + formData.append("action", "manga_get_chapters"); + formData.append("manga", novelId); + return [4 /*yield*/, (0, fetch_1.fetchApi)(this.site + 'wp-admin/admin-ajax.php', { + method: 'POST', + body: formData, + }) + .then(function (res) { return res.text(); })]; + case 2: + html = _b.sent(); + return [3 /*break*/, 5]; + case 3: return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl + 'ajax/chapters/', { method: 'POST' }) + .then(function (res) { return res.text(); })]; + case 4: + html = _b.sent(); + _b.label = 5; + case 5: + if (html !== '0') { + loadedCheerio = (0, cheerio_1.load)(html); + } + chapters = []; + loadedCheerio('.wp-manga-chapter').each(function () { + var chapterName = loadedCheerio(this).find('a').text().trim(); + var releaseDate = null; + releaseDate = loadedCheerio(this) + .find('span.chapter-release-date') + .text() + .trim(); + if (releaseDate) { + releaseDate = (0, parseMadaraDate_1.parseMadaraDate)(releaseDate); + } + else { + /** + * Insert current date + */ + releaseDate = (0, dayjs_1.default)().format('LL'); + } + var chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); + }); + novel.chapters = chapters.reverse(); + return [2 /*return*/, novel]; + } + }); + }); + }; + MadaraPlugin.prototype.parseChapter = function (chapterUrl) { + return __awaiter(this, void 0, void 0, function () { + var body, loadedCheerio, chapterText; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, (0, fetch_1.fetchApi)(chapterUrl).then(function (res) { return res.text(); })]; + case 1: + body = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + chapterText = loadedCheerio('.text-left').html() || + loadedCheerio('.text-right').html() || + loadedCheerio('.entry-content').html() || ""; + return [2 /*return*/, chapterText]; + } + }); + }); + }; + MadaraPlugin.prototype.searchNovels = function (searchTerm, pageNo) { + return __awaiter(this, void 0, void 0, function () { + var novels, url, body, loadedCheerio; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + novels = []; + url = this.site + "?s=" + searchTerm + "&post_type=wp-manga"; + return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })]; + case 1: + body = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.c-tabs-item__content').each(function () { + var novelName = loadedCheerio(this).find('.post-title').text().trim(); + var image = loadedCheerio(this).find('img'); + var novelCover = image.attr('data-src') || image.attr('src'); + var novelUrl = loadedCheerio(this) + .find('.post-title') + .find('a') + .attr('href') || ''; + var novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + novels.push(novel); + }); + return [2 /*return*/, novels]; + } + }); + }); + }; + MadaraPlugin.prototype.fetchImage = function (url) { + return __awaiter(this, void 0, void 0, function () { + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, (0, fetch_1.fetchFile)(url, {})]; + case 1: return [2 /*return*/, _a.sent()]; + } + }); + }); + }; + return MadaraPlugin; +}()); +var plugin = new MadaraPlugin({ "id": "mysticalmerries", "sourceSite": "https://mysticalmerries.com/", "sourceName": "MysticalSeries", "filters": [{ "key": "sort", "label": "Order by", "values": [{ "label": "Rating", "value": "rating" }, { "label": "A-Z", "value": "alphabet" }, { "label": "Latest", "value": "latest" }, { "label": "Most Views", "value": "views" }, { "label": "New", "value": "new-manga" }, { "label": "Trending", "value": "trending" }], "inputType": "Picker" }, { "key": "genres", "label": "GENRES", "values": [{ "label": "Action", "value": "action" }, { "label": "Adaptation", "value": "adaptation" }, { "label": "Adventure", "value": "adventure" }, { "label": "bilibili", "value": "bilibili" }, { "label": "Chinese Novel", "value": "chinese-novel" }, { "label": "Comedy", "value": "comedy" }, { "label": "Crossdressing", "value": "crossdressing" }, { "label": "Drama", "value": "drama" }, { "label": "Dropped", "value": "dropped" }, { "label": "Family", "value": "family" }, { "label": "Fantasy", "value": "fantasy" }, { "label": "Gender Bender", "value": "gender-bender" }, { "label": "Historical", "value": "historical" }, { "label": "Horror", "value": "horror" }, { "label": "Isekai", "value": "isekai" }, { "label": "Korean Novel", "value": "korean-novell" }, { "label": "Manga", "value": "manga" }, { "label": "Manhua", "value": "manhua" }, { "label": "Manhwa", "value": "manhwa" }, { "label": "Modern Romance", "value": "modern-romance" }, { "label": "Mystery", "value": "mystery" }, { "label": "Office Workers", "value": "office-workers" }, { "label": "One shot", "value": "one-shot" }, { "label": "Pilot Novel", "value": "pilot-novel" }, { "label": "R15", "value": "r15" }, { "label": "R19", "value": "r19" }, { "label": "Regression", "value": "regression" }, { "label": "Reincarnation", "value": "reincarnation" }, { "label": "Reverse Harem", "value": "reverse-harem" }, { "label": "Romance Fantasy", "value": "romance-fantasy" }, { "label": "School Life", "value": "school-life" }, { "label": "Sci-fi", "value": "sci-fi" }, { "label": "Slice of Life", "value": "slice-of-life" }, { "label": "Smut", "value": "smut" }, { "label": "Supernatural", "value": "supernatural" }, { "label": "Violence", "value": "violence" }], "inputType": "Picker" }], "options": { "path": { "novels": "series", "novel": "series", "chapter": "series", "genres": "genre" }, "useNewChapterEndpoint": true, "lang": "English" } }); +exports.default = plugin; diff --git a/.js/plugins/english/NeoSekaiTranslations[madara].js b/.js/plugins/english/NeoSekaiTranslations[madara].js new file mode 100644 index 0000000..2264b0f --- /dev/null +++ b/.js/plugins/english/NeoSekaiTranslations[madara].js @@ -0,0 +1,269 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __generator = (this && this.__generator) || function (thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (g && (g = 0, op[0] && (_ = 0)), _) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +}; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var fetch_1 = require("@libs/fetch"); +var cheerio_1 = require("cheerio"); +var defaultCover_1 = require("@libs/defaultCover"); +var novelStatus_1 = require("@libs/novelStatus"); +var parseMadaraDate_1 = require("@libs/parseMadaraDate"); +var dayjs_1 = __importDefault(require("dayjs")); +var MadaraDefaultPath = { + novels: 'novel', + novel: 'novel', + chapter: 'novel' +}; +var MadaraPlugin = /** @class */ (function () { + function MadaraPlugin(metadata) { + this.id = metadata.id; + this.name = metadata.sourceName + "[madara]"; + var iconFileName = metadata.sourceName.replace(/\s+/g, "").toLowerCase(); + this.icon = "multisrc/madara/icons/".concat(iconFileName, ".png"); + this.site = metadata.sourceSite; + this.version = "1.0.0"; + this.userAgent = ""; + this.cookieString = ""; + this.options = metadata.options; + this.filter = metadata.filters; + } + MadaraPlugin.prototype.popularNovels = function (pageNo, _a) { + var _b, _c, _d, _e, _f, _g; + var filters = _a.filters, showLatestNovels = _a.showLatestNovels; + return __awaiter(this, void 0, void 0, function () { + var novels, url, body, loadedCheerio; + return __generator(this, function (_h) { + switch (_h.label) { + case 0: + novels = []; + url = this.site; + if ((filters === null || filters === void 0 ? void 0 : filters.genres) && ((_c = (_b = this.options) === null || _b === void 0 ? void 0 : _b.path) === null || _c === void 0 ? void 0 : _c.genres)) { + url += ((_e = (_d = this.options) === null || _d === void 0 ? void 0 : _d.path) === null || _e === void 0 ? void 0 : _e.genres) + filters.genres + '/'; + } + else { + url += ((_g = (_f = this.options) === null || _f === void 0 ? void 0 : _f.path) === null || _g === void 0 ? void 0 : _g.novels) ? this.options.path.novels : MadaraDefaultPath.novels; + } + url += '/page/' + pageNo + '/' + + '?m_orderby=' + (showLatestNovels ? 'latest' : ((filters === null || filters === void 0 ? void 0 : filters.sort) || 'rating')); + return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })]; + case 1: + body = _h.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.manga-title-badges').remove(); + loadedCheerio('.page-item-detail').each(function () { + var novelName = loadedCheerio(this).find('.post-title').text().trim(); + var image = loadedCheerio(this).find('img'); + var novelCover = image.attr('data-src') || image.attr('src'); + var novelUrl = loadedCheerio(this).find('.post-title') + .find('a') + .attr('href') || ''; + var novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + novels.push(novel); + }); + return [2 /*return*/, novels]; + } + }); + }); + }; + MadaraPlugin.prototype.parseNovelAndChapters = function (novelUrl) { + var _a; + return __awaiter(this, void 0, void 0, function () { + var novel, body, loadedCheerio, html, novelId, formData, chapters; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + novel = { + url: novelUrl, + }; + return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl).then(function (res) { return res.text(); })]; + case 1: + body = _b.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.manga-title-badges, #manga-title span').remove(); + novel.name = + loadedCheerio('.post-title h1').text().trim() || + loadedCheerio('#manga-title h1').text(); + novel.cover = + loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || + loadedCheerio('.summary_image > a > img').attr('data-src') || + loadedCheerio('.summary_image > a > img').attr('src') || + defaultCover_1.defaultCover; + loadedCheerio('.post-content_item, .post-content').each(function () { + var detailName = loadedCheerio(this).find('h5').text().trim(); + var detail = loadedCheerio(this).find('.summary-content').text().trim(); + switch (detailName) { + case 'Genre(s)': + case 'التصنيفات': + novel.genres = detail.replace(/[\\t\\n]/g, ','); + break; + case 'Author(s)': + case 'المؤلف': + case 'المؤلف (ين)': + novel.author = detail; + break; + case 'Status': + case 'الحالة': + novel.status = + detail.includes('OnGoing') || detail.includes('مستمرة') + ? novelStatus_1.NovelStatus.Ongoing + : novelStatus_1.NovelStatus.Completed; + break; + } + }); + loadedCheerio('div.summary__content .code-block,script').remove(); + novel.summary = + loadedCheerio('div.summary__content').text().trim() || + loadedCheerio('#tab-manga-about').text().trim() || + loadedCheerio('.post-content_item h5:contains("Summary")').next().text().trim(); + if (!(((_a = this.options) === null || _a === void 0 ? void 0 : _a.useNewChapterEndpoint) !== true)) return [3 /*break*/, 3]; + novelId = loadedCheerio('.rating-post-id').attr('value') || + loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; + formData = new FormData(); + formData.append("action", "manga_get_chapters"); + formData.append("manga", novelId); + return [4 /*yield*/, (0, fetch_1.fetchApi)(this.site + 'wp-admin/admin-ajax.php', { + method: 'POST', + body: formData, + }) + .then(function (res) { return res.text(); })]; + case 2: + html = _b.sent(); + return [3 /*break*/, 5]; + case 3: return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl + 'ajax/chapters/', { method: 'POST' }) + .then(function (res) { return res.text(); })]; + case 4: + html = _b.sent(); + _b.label = 5; + case 5: + if (html !== '0') { + loadedCheerio = (0, cheerio_1.load)(html); + } + chapters = []; + loadedCheerio('.wp-manga-chapter').each(function () { + var chapterName = loadedCheerio(this).find('a').text().trim(); + var releaseDate = null; + releaseDate = loadedCheerio(this) + .find('span.chapter-release-date') + .text() + .trim(); + if (releaseDate) { + releaseDate = (0, parseMadaraDate_1.parseMadaraDate)(releaseDate); + } + else { + /** + * Insert current date + */ + releaseDate = (0, dayjs_1.default)().format('LL'); + } + var chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); + }); + novel.chapters = chapters.reverse(); + return [2 /*return*/, novel]; + } + }); + }); + }; + MadaraPlugin.prototype.parseChapter = function (chapterUrl) { + return __awaiter(this, void 0, void 0, function () { + var body, loadedCheerio, chapterText; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, (0, fetch_1.fetchApi)(chapterUrl).then(function (res) { return res.text(); })]; + case 1: + body = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + chapterText = loadedCheerio('.text-left').html() || + loadedCheerio('.text-right').html() || + loadedCheerio('.entry-content').html() || ""; + return [2 /*return*/, chapterText]; + } + }); + }); + }; + MadaraPlugin.prototype.searchNovels = function (searchTerm, pageNo) { + return __awaiter(this, void 0, void 0, function () { + var novels, url, body, loadedCheerio; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + novels = []; + url = this.site + "?s=" + searchTerm + "&post_type=wp-manga"; + return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })]; + case 1: + body = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.c-tabs-item__content').each(function () { + var novelName = loadedCheerio(this).find('.post-title').text().trim(); + var image = loadedCheerio(this).find('img'); + var novelCover = image.attr('data-src') || image.attr('src'); + var novelUrl = loadedCheerio(this) + .find('.post-title') + .find('a') + .attr('href') || ''; + var novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + novels.push(novel); + }); + return [2 /*return*/, novels]; + } + }); + }); + }; + MadaraPlugin.prototype.fetchImage = function (url) { + return __awaiter(this, void 0, void 0, function () { + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, (0, fetch_1.fetchFile)(url, {})]; + case 1: return [2 /*return*/, _a.sent()]; + } + }); + }); + }; + return MadaraPlugin; +}()); +var plugin = new MadaraPlugin({ "id": "neosekaiTLS", "sourceSite": "https://www.neosekaitranslations.com/", "sourceName": "NeoSekai Translations", "filters": [{ "key": "sort", "label": "Order by", "values": [{ "label": "Rating", "value": "rating" }, { "label": "A-Z", "value": "alphabet" }, { "label": "Latest", "value": "latest" }, { "label": "Most Views", "value": "views" }, { "label": "New", "value": "new-manga" }, { "label": "Trending", "value": "trending" }], "inputType": "Picker" }, { "key": "genres", "label": "GENRES", "values": [{ "label": "Action", "value": "action" }, { "label": "Adventure", "value": "adventure" }, { "label": "Comedy", "value": "comedy" }, { "label": "Drama", "value": "drama" }, { "label": "Fantasy", "value": "fantasy" }, { "label": "Harem", "value": "harem" }, { "label": "Horror", "value": "horror" }, { "label": "Mature", "value": "mature" }, { "label": "Mecha", "value": "mecha" }, { "label": "Mystery", "value": "mystery" }, { "label": "Psychological", "value": "psychological" }, { "label": "Romance", "value": "romance" }, { "label": "School Life", "value": "school-life" }, { "label": "Sci-Fi", "value": "sci-fi" }, { "label": "Slice of Life", "value": "slice-of-life" }], "inputType": "Picker" }], "options": { "lang": "English" } }); +exports.default = plugin; diff --git a/.js/plugins/english/NocturneTranslations[madara].js b/.js/plugins/english/NocturneTranslations[madara].js new file mode 100644 index 0000000..b096667 --- /dev/null +++ b/.js/plugins/english/NocturneTranslations[madara].js @@ -0,0 +1,269 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __generator = (this && this.__generator) || function (thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (g && (g = 0, op[0] && (_ = 0)), _) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +}; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var fetch_1 = require("@libs/fetch"); +var cheerio_1 = require("cheerio"); +var defaultCover_1 = require("@libs/defaultCover"); +var novelStatus_1 = require("@libs/novelStatus"); +var parseMadaraDate_1 = require("@libs/parseMadaraDate"); +var dayjs_1 = __importDefault(require("dayjs")); +var MadaraDefaultPath = { + novels: 'novel', + novel: 'novel', + chapter: 'novel' +}; +var MadaraPlugin = /** @class */ (function () { + function MadaraPlugin(metadata) { + this.id = metadata.id; + this.name = metadata.sourceName + "[madara]"; + var iconFileName = metadata.sourceName.replace(/\s+/g, "").toLowerCase(); + this.icon = "multisrc/madara/icons/".concat(iconFileName, ".png"); + this.site = metadata.sourceSite; + this.version = "1.0.0"; + this.userAgent = ""; + this.cookieString = ""; + this.options = metadata.options; + this.filter = metadata.filters; + } + MadaraPlugin.prototype.popularNovels = function (pageNo, _a) { + var _b, _c, _d, _e, _f, _g; + var filters = _a.filters, showLatestNovels = _a.showLatestNovels; + return __awaiter(this, void 0, void 0, function () { + var novels, url, body, loadedCheerio; + return __generator(this, function (_h) { + switch (_h.label) { + case 0: + novels = []; + url = this.site; + if ((filters === null || filters === void 0 ? void 0 : filters.genres) && ((_c = (_b = this.options) === null || _b === void 0 ? void 0 : _b.path) === null || _c === void 0 ? void 0 : _c.genres)) { + url += ((_e = (_d = this.options) === null || _d === void 0 ? void 0 : _d.path) === null || _e === void 0 ? void 0 : _e.genres) + filters.genres + '/'; + } + else { + url += ((_g = (_f = this.options) === null || _f === void 0 ? void 0 : _f.path) === null || _g === void 0 ? void 0 : _g.novels) ? this.options.path.novels : MadaraDefaultPath.novels; + } + url += '/page/' + pageNo + '/' + + '?m_orderby=' + (showLatestNovels ? 'latest' : ((filters === null || filters === void 0 ? void 0 : filters.sort) || 'rating')); + return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })]; + case 1: + body = _h.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.manga-title-badges').remove(); + loadedCheerio('.page-item-detail').each(function () { + var novelName = loadedCheerio(this).find('.post-title').text().trim(); + var image = loadedCheerio(this).find('img'); + var novelCover = image.attr('data-src') || image.attr('src'); + var novelUrl = loadedCheerio(this).find('.post-title') + .find('a') + .attr('href') || ''; + var novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + novels.push(novel); + }); + return [2 /*return*/, novels]; + } + }); + }); + }; + MadaraPlugin.prototype.parseNovelAndChapters = function (novelUrl) { + var _a; + return __awaiter(this, void 0, void 0, function () { + var novel, body, loadedCheerio, html, novelId, formData, chapters; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + novel = { + url: novelUrl, + }; + return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl).then(function (res) { return res.text(); })]; + case 1: + body = _b.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.manga-title-badges, #manga-title span').remove(); + novel.name = + loadedCheerio('.post-title h1').text().trim() || + loadedCheerio('#manga-title h1').text(); + novel.cover = + loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || + loadedCheerio('.summary_image > a > img').attr('data-src') || + loadedCheerio('.summary_image > a > img').attr('src') || + defaultCover_1.defaultCover; + loadedCheerio('.post-content_item, .post-content').each(function () { + var detailName = loadedCheerio(this).find('h5').text().trim(); + var detail = loadedCheerio(this).find('.summary-content').text().trim(); + switch (detailName) { + case 'Genre(s)': + case 'التصنيفات': + novel.genres = detail.replace(/[\\t\\n]/g, ','); + break; + case 'Author(s)': + case 'المؤلف': + case 'المؤلف (ين)': + novel.author = detail; + break; + case 'Status': + case 'الحالة': + novel.status = + detail.includes('OnGoing') || detail.includes('مستمرة') + ? novelStatus_1.NovelStatus.Ongoing + : novelStatus_1.NovelStatus.Completed; + break; + } + }); + loadedCheerio('div.summary__content .code-block,script').remove(); + novel.summary = + loadedCheerio('div.summary__content').text().trim() || + loadedCheerio('#tab-manga-about').text().trim() || + loadedCheerio('.post-content_item h5:contains("Summary")').next().text().trim(); + if (!(((_a = this.options) === null || _a === void 0 ? void 0 : _a.useNewChapterEndpoint) !== true)) return [3 /*break*/, 3]; + novelId = loadedCheerio('.rating-post-id').attr('value') || + loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; + formData = new FormData(); + formData.append("action", "manga_get_chapters"); + formData.append("manga", novelId); + return [4 /*yield*/, (0, fetch_1.fetchApi)(this.site + 'wp-admin/admin-ajax.php', { + method: 'POST', + body: formData, + }) + .then(function (res) { return res.text(); })]; + case 2: + html = _b.sent(); + return [3 /*break*/, 5]; + case 3: return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl + 'ajax/chapters/', { method: 'POST' }) + .then(function (res) { return res.text(); })]; + case 4: + html = _b.sent(); + _b.label = 5; + case 5: + if (html !== '0') { + loadedCheerio = (0, cheerio_1.load)(html); + } + chapters = []; + loadedCheerio('.wp-manga-chapter').each(function () { + var chapterName = loadedCheerio(this).find('a').text().trim(); + var releaseDate = null; + releaseDate = loadedCheerio(this) + .find('span.chapter-release-date') + .text() + .trim(); + if (releaseDate) { + releaseDate = (0, parseMadaraDate_1.parseMadaraDate)(releaseDate); + } + else { + /** + * Insert current date + */ + releaseDate = (0, dayjs_1.default)().format('LL'); + } + var chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); + }); + novel.chapters = chapters.reverse(); + return [2 /*return*/, novel]; + } + }); + }); + }; + MadaraPlugin.prototype.parseChapter = function (chapterUrl) { + return __awaiter(this, void 0, void 0, function () { + var body, loadedCheerio, chapterText; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, (0, fetch_1.fetchApi)(chapterUrl).then(function (res) { return res.text(); })]; + case 1: + body = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + chapterText = loadedCheerio('.text-left').html() || + loadedCheerio('.text-right').html() || + loadedCheerio('.entry-content').html() || ""; + return [2 /*return*/, chapterText]; + } + }); + }); + }; + MadaraPlugin.prototype.searchNovels = function (searchTerm, pageNo) { + return __awaiter(this, void 0, void 0, function () { + var novels, url, body, loadedCheerio; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + novels = []; + url = this.site + "?s=" + searchTerm + "&post_type=wp-manga"; + return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })]; + case 1: + body = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.c-tabs-item__content').each(function () { + var novelName = loadedCheerio(this).find('.post-title').text().trim(); + var image = loadedCheerio(this).find('img'); + var novelCover = image.attr('data-src') || image.attr('src'); + var novelUrl = loadedCheerio(this) + .find('.post-title') + .find('a') + .attr('href') || ''; + var novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + novels.push(novel); + }); + return [2 /*return*/, novels]; + } + }); + }); + }; + MadaraPlugin.prototype.fetchImage = function (url) { + return __awaiter(this, void 0, void 0, function () { + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, (0, fetch_1.fetchFile)(url, {})]; + case 1: return [2 /*return*/, _a.sent()]; + } + }); + }); + }; + return MadaraPlugin; +}()); +var plugin = new MadaraPlugin({ "id": "nocturneTLS", "sourceSite": "https://nocturnetls.net/", "sourceName": "Nocturne Translations", "filters": [{ "key": "sort", "label": "Order by", "values": [{ "label": "Rating", "value": "rating" }, { "label": "A-Z", "value": "alphabet" }, { "label": "Latest", "value": "latest" }, { "label": "Most Views", "value": "views" }, { "label": "New", "value": "new-manga" }, { "label": "Trending", "value": "trending" }], "inputType": "Picker" }, { "key": "genres", "label": "GENRES", "values": [{ "label": "Action", "value": "action" }, { "label": "Adult", "value": "adult" }, { "label": "Adventure", "value": "adventure" }, { "label": "Anime", "value": "anime" }, { "label": "Cartoon", "value": "cartoon" }, { "label": "Comedy", "value": "comedy" }, { "label": "Comic", "value": "comic" }, { "label": "Cooking", "value": "cooking" }, { "label": "Detective", "value": "detective" }, { "label": "Doujinshi", "value": "doujinshi" }, { "label": "Drama", "value": "drama" }, { "label": "Ecchi", "value": "ecchi" }, { "label": "Fantasy", "value": "fantasy" }, { "label": "Gender Bender", "value": "gender-bender" }, { "label": "Harem", "value": "harem" }, { "label": "Historical", "value": "historical" }, { "label": "Horror", "value": "horror" }, { "label": "Josei", "value": "josei" }, { "label": "Live action", "value": "live-action" }, { "label": "Manga", "value": "manga" }, { "label": "Manhua", "value": "manhua" }, { "label": "Manhwa", "value": "manhwa" }, { "label": "Martial Arts", "value": "martial-arts" }, { "label": "Mature", "value": "mature" }, { "label": "Mecha", "value": "mecha" }, { "label": "Mystery", "value": "mystery" }, { "label": "One shot", "value": "one-shot" }, { "label": "Psychological", "value": "psychological" }, { "label": "Romance", "value": "romance" }, { "label": "School Life", "value": "school-life" }, { "label": "Sci-fi", "value": "sci-fi" }, { "label": "Seinen", "value": "seinen" }, { "label": "Shoujo", "value": "shoujo" }, { "label": "Shoujo Ai", "value": "shoujo-ai" }, { "label": "Shounen", "value": "shounen" }, { "label": "Shounen Ai", "value": "shounen-ai" }, { "label": "Slice of Life", "value": "slice-of-life" }, { "label": "Smut", "value": "smut" }, { "label": "Soft Yaoi", "value": "soft-yaoi" }, { "label": "Soft Yuri", "value": "soft-yuri" }, { "label": "Sports", "value": "sports" }, { "label": "Supernatural", "value": "supernatural" }, { "label": "Tragedy", "value": "tragedy" }, { "label": "Webtoon", "value": "webtoon" }, { "label": "Yaoi", "value": "yaoi" }, { "label": "Yuri", "value": "yuri" }], "inputType": "Picker" }], "options": { "path": { "novels": "novels", "novel": "novels", "chapter": "novels", "genres": "manga-genre" }, "lang": "English" } }); +exports.default = plugin; diff --git a/.js/plugins/english/NoobchanTranslation[madara].js b/.js/plugins/english/NoobchanTranslation[madara].js new file mode 100644 index 0000000..d9aa474 --- /dev/null +++ b/.js/plugins/english/NoobchanTranslation[madara].js @@ -0,0 +1,269 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __generator = (this && this.__generator) || function (thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (g && (g = 0, op[0] && (_ = 0)), _) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +}; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var fetch_1 = require("@libs/fetch"); +var cheerio_1 = require("cheerio"); +var defaultCover_1 = require("@libs/defaultCover"); +var novelStatus_1 = require("@libs/novelStatus"); +var parseMadaraDate_1 = require("@libs/parseMadaraDate"); +var dayjs_1 = __importDefault(require("dayjs")); +var MadaraDefaultPath = { + novels: 'novel', + novel: 'novel', + chapter: 'novel' +}; +var MadaraPlugin = /** @class */ (function () { + function MadaraPlugin(metadata) { + this.id = metadata.id; + this.name = metadata.sourceName + "[madara]"; + var iconFileName = metadata.sourceName.replace(/\s+/g, "").toLowerCase(); + this.icon = "multisrc/madara/icons/".concat(iconFileName, ".png"); + this.site = metadata.sourceSite; + this.version = "1.0.0"; + this.userAgent = ""; + this.cookieString = ""; + this.options = metadata.options; + this.filter = metadata.filters; + } + MadaraPlugin.prototype.popularNovels = function (pageNo, _a) { + var _b, _c, _d, _e, _f, _g; + var filters = _a.filters, showLatestNovels = _a.showLatestNovels; + return __awaiter(this, void 0, void 0, function () { + var novels, url, body, loadedCheerio; + return __generator(this, function (_h) { + switch (_h.label) { + case 0: + novels = []; + url = this.site; + if ((filters === null || filters === void 0 ? void 0 : filters.genres) && ((_c = (_b = this.options) === null || _b === void 0 ? void 0 : _b.path) === null || _c === void 0 ? void 0 : _c.genres)) { + url += ((_e = (_d = this.options) === null || _d === void 0 ? void 0 : _d.path) === null || _e === void 0 ? void 0 : _e.genres) + filters.genres + '/'; + } + else { + url += ((_g = (_f = this.options) === null || _f === void 0 ? void 0 : _f.path) === null || _g === void 0 ? void 0 : _g.novels) ? this.options.path.novels : MadaraDefaultPath.novels; + } + url += '/page/' + pageNo + '/' + + '?m_orderby=' + (showLatestNovels ? 'latest' : ((filters === null || filters === void 0 ? void 0 : filters.sort) || 'rating')); + return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })]; + case 1: + body = _h.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.manga-title-badges').remove(); + loadedCheerio('.page-item-detail').each(function () { + var novelName = loadedCheerio(this).find('.post-title').text().trim(); + var image = loadedCheerio(this).find('img'); + var novelCover = image.attr('data-src') || image.attr('src'); + var novelUrl = loadedCheerio(this).find('.post-title') + .find('a') + .attr('href') || ''; + var novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + novels.push(novel); + }); + return [2 /*return*/, novels]; + } + }); + }); + }; + MadaraPlugin.prototype.parseNovelAndChapters = function (novelUrl) { + var _a; + return __awaiter(this, void 0, void 0, function () { + var novel, body, loadedCheerio, html, novelId, formData, chapters; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + novel = { + url: novelUrl, + }; + return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl).then(function (res) { return res.text(); })]; + case 1: + body = _b.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.manga-title-badges, #manga-title span').remove(); + novel.name = + loadedCheerio('.post-title h1').text().trim() || + loadedCheerio('#manga-title h1').text(); + novel.cover = + loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || + loadedCheerio('.summary_image > a > img').attr('data-src') || + loadedCheerio('.summary_image > a > img').attr('src') || + defaultCover_1.defaultCover; + loadedCheerio('.post-content_item, .post-content').each(function () { + var detailName = loadedCheerio(this).find('h5').text().trim(); + var detail = loadedCheerio(this).find('.summary-content').text().trim(); + switch (detailName) { + case 'Genre(s)': + case 'التصنيفات': + novel.genres = detail.replace(/[\\t\\n]/g, ','); + break; + case 'Author(s)': + case 'المؤلف': + case 'المؤلف (ين)': + novel.author = detail; + break; + case 'Status': + case 'الحالة': + novel.status = + detail.includes('OnGoing') || detail.includes('مستمرة') + ? novelStatus_1.NovelStatus.Ongoing + : novelStatus_1.NovelStatus.Completed; + break; + } + }); + loadedCheerio('div.summary__content .code-block,script').remove(); + novel.summary = + loadedCheerio('div.summary__content').text().trim() || + loadedCheerio('#tab-manga-about').text().trim() || + loadedCheerio('.post-content_item h5:contains("Summary")').next().text().trim(); + if (!(((_a = this.options) === null || _a === void 0 ? void 0 : _a.useNewChapterEndpoint) !== true)) return [3 /*break*/, 3]; + novelId = loadedCheerio('.rating-post-id').attr('value') || + loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; + formData = new FormData(); + formData.append("action", "manga_get_chapters"); + formData.append("manga", novelId); + return [4 /*yield*/, (0, fetch_1.fetchApi)(this.site + 'wp-admin/admin-ajax.php', { + method: 'POST', + body: formData, + }) + .then(function (res) { return res.text(); })]; + case 2: + html = _b.sent(); + return [3 /*break*/, 5]; + case 3: return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl + 'ajax/chapters/', { method: 'POST' }) + .then(function (res) { return res.text(); })]; + case 4: + html = _b.sent(); + _b.label = 5; + case 5: + if (html !== '0') { + loadedCheerio = (0, cheerio_1.load)(html); + } + chapters = []; + loadedCheerio('.wp-manga-chapter').each(function () { + var chapterName = loadedCheerio(this).find('a').text().trim(); + var releaseDate = null; + releaseDate = loadedCheerio(this) + .find('span.chapter-release-date') + .text() + .trim(); + if (releaseDate) { + releaseDate = (0, parseMadaraDate_1.parseMadaraDate)(releaseDate); + } + else { + /** + * Insert current date + */ + releaseDate = (0, dayjs_1.default)().format('LL'); + } + var chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); + }); + novel.chapters = chapters.reverse(); + return [2 /*return*/, novel]; + } + }); + }); + }; + MadaraPlugin.prototype.parseChapter = function (chapterUrl) { + return __awaiter(this, void 0, void 0, function () { + var body, loadedCheerio, chapterText; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, (0, fetch_1.fetchApi)(chapterUrl).then(function (res) { return res.text(); })]; + case 1: + body = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + chapterText = loadedCheerio('.text-left').html() || + loadedCheerio('.text-right').html() || + loadedCheerio('.entry-content').html() || ""; + return [2 /*return*/, chapterText]; + } + }); + }); + }; + MadaraPlugin.prototype.searchNovels = function (searchTerm, pageNo) { + return __awaiter(this, void 0, void 0, function () { + var novels, url, body, loadedCheerio; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + novels = []; + url = this.site + "?s=" + searchTerm + "&post_type=wp-manga"; + return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })]; + case 1: + body = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.c-tabs-item__content').each(function () { + var novelName = loadedCheerio(this).find('.post-title').text().trim(); + var image = loadedCheerio(this).find('img'); + var novelCover = image.attr('data-src') || image.attr('src'); + var novelUrl = loadedCheerio(this) + .find('.post-title') + .find('a') + .attr('href') || ''; + var novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + novels.push(novel); + }); + return [2 /*return*/, novels]; + } + }); + }); + }; + MadaraPlugin.prototype.fetchImage = function (url) { + return __awaiter(this, void 0, void 0, function () { + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, (0, fetch_1.fetchFile)(url, {})]; + case 1: return [2 /*return*/, _a.sent()]; + } + }); + }); + }; + return MadaraPlugin; +}()); +var plugin = new MadaraPlugin({ "id": "noobchanTL", "sourceSite": "https://noobchan.xyz/", "sourceName": "Noobchan Translation", "filters": [], "options": { "useNewChapterEndpoint": true, "lang": "English" } }); +exports.default = plugin; diff --git a/.js/plugins/english/NovelMultiverse[madara].js b/.js/plugins/english/NovelMultiverse[madara].js new file mode 100644 index 0000000..545d558 --- /dev/null +++ b/.js/plugins/english/NovelMultiverse[madara].js @@ -0,0 +1,269 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __generator = (this && this.__generator) || function (thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (g && (g = 0, op[0] && (_ = 0)), _) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +}; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var fetch_1 = require("@libs/fetch"); +var cheerio_1 = require("cheerio"); +var defaultCover_1 = require("@libs/defaultCover"); +var novelStatus_1 = require("@libs/novelStatus"); +var parseMadaraDate_1 = require("@libs/parseMadaraDate"); +var dayjs_1 = __importDefault(require("dayjs")); +var MadaraDefaultPath = { + novels: 'novel', + novel: 'novel', + chapter: 'novel' +}; +var MadaraPlugin = /** @class */ (function () { + function MadaraPlugin(metadata) { + this.id = metadata.id; + this.name = metadata.sourceName + "[madara]"; + var iconFileName = metadata.sourceName.replace(/\s+/g, "").toLowerCase(); + this.icon = "multisrc/madara/icons/".concat(iconFileName, ".png"); + this.site = metadata.sourceSite; + this.version = "1.0.0"; + this.userAgent = ""; + this.cookieString = ""; + this.options = metadata.options; + this.filter = metadata.filters; + } + MadaraPlugin.prototype.popularNovels = function (pageNo, _a) { + var _b, _c, _d, _e, _f, _g; + var filters = _a.filters, showLatestNovels = _a.showLatestNovels; + return __awaiter(this, void 0, void 0, function () { + var novels, url, body, loadedCheerio; + return __generator(this, function (_h) { + switch (_h.label) { + case 0: + novels = []; + url = this.site; + if ((filters === null || filters === void 0 ? void 0 : filters.genres) && ((_c = (_b = this.options) === null || _b === void 0 ? void 0 : _b.path) === null || _c === void 0 ? void 0 : _c.genres)) { + url += ((_e = (_d = this.options) === null || _d === void 0 ? void 0 : _d.path) === null || _e === void 0 ? void 0 : _e.genres) + filters.genres + '/'; + } + else { + url += ((_g = (_f = this.options) === null || _f === void 0 ? void 0 : _f.path) === null || _g === void 0 ? void 0 : _g.novels) ? this.options.path.novels : MadaraDefaultPath.novels; + } + url += '/page/' + pageNo + '/' + + '?m_orderby=' + (showLatestNovels ? 'latest' : ((filters === null || filters === void 0 ? void 0 : filters.sort) || 'rating')); + return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })]; + case 1: + body = _h.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.manga-title-badges').remove(); + loadedCheerio('.page-item-detail').each(function () { + var novelName = loadedCheerio(this).find('.post-title').text().trim(); + var image = loadedCheerio(this).find('img'); + var novelCover = image.attr('data-src') || image.attr('src'); + var novelUrl = loadedCheerio(this).find('.post-title') + .find('a') + .attr('href') || ''; + var novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + novels.push(novel); + }); + return [2 /*return*/, novels]; + } + }); + }); + }; + MadaraPlugin.prototype.parseNovelAndChapters = function (novelUrl) { + var _a; + return __awaiter(this, void 0, void 0, function () { + var novel, body, loadedCheerio, html, novelId, formData, chapters; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + novel = { + url: novelUrl, + }; + return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl).then(function (res) { return res.text(); })]; + case 1: + body = _b.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.manga-title-badges, #manga-title span').remove(); + novel.name = + loadedCheerio('.post-title h1').text().trim() || + loadedCheerio('#manga-title h1').text(); + novel.cover = + loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || + loadedCheerio('.summary_image > a > img').attr('data-src') || + loadedCheerio('.summary_image > a > img').attr('src') || + defaultCover_1.defaultCover; + loadedCheerio('.post-content_item, .post-content').each(function () { + var detailName = loadedCheerio(this).find('h5').text().trim(); + var detail = loadedCheerio(this).find('.summary-content').text().trim(); + switch (detailName) { + case 'Genre(s)': + case 'التصنيفات': + novel.genres = detail.replace(/[\\t\\n]/g, ','); + break; + case 'Author(s)': + case 'المؤلف': + case 'المؤلف (ين)': + novel.author = detail; + break; + case 'Status': + case 'الحالة': + novel.status = + detail.includes('OnGoing') || detail.includes('مستمرة') + ? novelStatus_1.NovelStatus.Ongoing + : novelStatus_1.NovelStatus.Completed; + break; + } + }); + loadedCheerio('div.summary__content .code-block,script').remove(); + novel.summary = + loadedCheerio('div.summary__content').text().trim() || + loadedCheerio('#tab-manga-about').text().trim() || + loadedCheerio('.post-content_item h5:contains("Summary")').next().text().trim(); + if (!(((_a = this.options) === null || _a === void 0 ? void 0 : _a.useNewChapterEndpoint) !== true)) return [3 /*break*/, 3]; + novelId = loadedCheerio('.rating-post-id').attr('value') || + loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; + formData = new FormData(); + formData.append("action", "manga_get_chapters"); + formData.append("manga", novelId); + return [4 /*yield*/, (0, fetch_1.fetchApi)(this.site + 'wp-admin/admin-ajax.php', { + method: 'POST', + body: formData, + }) + .then(function (res) { return res.text(); })]; + case 2: + html = _b.sent(); + return [3 /*break*/, 5]; + case 3: return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl + 'ajax/chapters/', { method: 'POST' }) + .then(function (res) { return res.text(); })]; + case 4: + html = _b.sent(); + _b.label = 5; + case 5: + if (html !== '0') { + loadedCheerio = (0, cheerio_1.load)(html); + } + chapters = []; + loadedCheerio('.wp-manga-chapter').each(function () { + var chapterName = loadedCheerio(this).find('a').text().trim(); + var releaseDate = null; + releaseDate = loadedCheerio(this) + .find('span.chapter-release-date') + .text() + .trim(); + if (releaseDate) { + releaseDate = (0, parseMadaraDate_1.parseMadaraDate)(releaseDate); + } + else { + /** + * Insert current date + */ + releaseDate = (0, dayjs_1.default)().format('LL'); + } + var chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); + }); + novel.chapters = chapters.reverse(); + return [2 /*return*/, novel]; + } + }); + }); + }; + MadaraPlugin.prototype.parseChapter = function (chapterUrl) { + return __awaiter(this, void 0, void 0, function () { + var body, loadedCheerio, chapterText; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, (0, fetch_1.fetchApi)(chapterUrl).then(function (res) { return res.text(); })]; + case 1: + body = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + chapterText = loadedCheerio('.text-left').html() || + loadedCheerio('.text-right').html() || + loadedCheerio('.entry-content').html() || ""; + return [2 /*return*/, chapterText]; + } + }); + }); + }; + MadaraPlugin.prototype.searchNovels = function (searchTerm, pageNo) { + return __awaiter(this, void 0, void 0, function () { + var novels, url, body, loadedCheerio; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + novels = []; + url = this.site + "?s=" + searchTerm + "&post_type=wp-manga"; + return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })]; + case 1: + body = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.c-tabs-item__content').each(function () { + var novelName = loadedCheerio(this).find('.post-title').text().trim(); + var image = loadedCheerio(this).find('img'); + var novelCover = image.attr('data-src') || image.attr('src'); + var novelUrl = loadedCheerio(this) + .find('.post-title') + .find('a') + .attr('href') || ''; + var novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + novels.push(novel); + }); + return [2 /*return*/, novels]; + } + }); + }); + }; + MadaraPlugin.prototype.fetchImage = function (url) { + return __awaiter(this, void 0, void 0, function () { + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, (0, fetch_1.fetchFile)(url, {})]; + case 1: return [2 /*return*/, _a.sent()]; + } + }); + }); + }; + return MadaraPlugin; +}()); +var plugin = new MadaraPlugin({ "id": "novelmultiverse", "sourceSite": "https://www.novelmultiverse.com/", "sourceName": "NovelMultiverse", "filters": [{ "key": "sort", "label": "Order by", "values": [{ "label": "Rating", "value": "rating" }, { "label": "A-Z", "value": "alphabet" }, { "label": "Latest", "value": "latest" }, { "label": "Most Views", "value": "views" }, { "label": "New", "value": "new-manga" }, { "label": "Trending", "value": "trending" }], "inputType": "Picker" }, { "key": "genres", "label": "GENRES", "values": [{ "label": "Action", "value": "action" }, { "label": "Adult", "value": "adult" }, { "label": "Adventure", "value": "adventure" }, { "label": "Anime", "value": "anime" }, { "label": "Cartoon", "value": "cartoon" }, { "label": "Comedy", "value": "comedy" }, { "label": "Comic", "value": "comic" }, { "label": "Cooking", "value": "cooking" }, { "label": "Detective", "value": "detective" }, { "label": "Doujinshi", "value": "doujinshi" }, { "label": "Drama", "value": "drama" }, { "label": "Ecchi", "value": "ecchi" }, { "label": "Fantasy", "value": "fantasy" }, { "label": "Gender Bender", "value": "gender-bender" }, { "label": "Harem", "value": "harem" }, { "label": "Historical", "value": "historical" }, { "label": "Horror", "value": "horror" }, { "label": "Josei", "value": "josei" }, { "label": "Live action", "value": "live-action" }, { "label": "Manga", "value": "manga" }, { "label": "Manhua", "value": "manhua" }, { "label": "Manhwa", "value": "manhwa" }, { "label": "Martial Arts", "value": "martial-arts" }, { "label": "Mature", "value": "mature" }, { "label": "Mecha", "value": "mecha" }, { "label": "Mystery", "value": "mystery" }, { "label": "One shot", "value": "one-shot" }, { "label": "Original", "value": "original" }, { "label": "Psychological", "value": "psychological" }, { "label": "Romance", "value": "romance" }, { "label": "School Life", "value": "school-life" }, { "label": "Sci-fi", "value": "sci-fi" }, { "label": "Seinen", "value": "seinen" }, { "label": "Shoujo", "value": "shoujo" }, { "label": "Shoujo Ai", "value": "shoujo-ai" }, { "label": "Shounen", "value": "shounen" }, { "label": "Shounen Ai", "value": "shounen-ai" }, { "label": "Slice of Life", "value": "slice-of-life" }, { "label": "Smut", "value": "smut" }, { "label": "Soft Yaoi", "value": "soft-yaoi" }, { "label": "Soft Yuri", "value": "soft-yuri" }, { "label": "Sports", "value": "sports" }, { "label": "Supernatural", "value": "supernatural" }, { "label": "Tragedy", "value": "tragedy" }, { "label": "Translation", "value": "translation" }, { "label": "Webtoon", "value": "webtoon" }, { "label": "Wuxia", "value": "wuxia" }, { "label": "Xianxia", "value": "xianxia" }, { "label": "Xuanhuan", "value": "xuanhuan" }, { "label": "Yaoi", "value": "yaoi" }, { "label": "Yuri", "value": "yuri" }], "inputType": "Picker" }], "options": { "lang": "English" } }); +exports.default = plugin; diff --git a/.js/plugins/english/NovelR18[madara].js b/.js/plugins/english/NovelR18[madara].js new file mode 100644 index 0000000..b322c38 --- /dev/null +++ b/.js/plugins/english/NovelR18[madara].js @@ -0,0 +1,269 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __generator = (this && this.__generator) || function (thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (g && (g = 0, op[0] && (_ = 0)), _) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +}; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var fetch_1 = require("@libs/fetch"); +var cheerio_1 = require("cheerio"); +var defaultCover_1 = require("@libs/defaultCover"); +var novelStatus_1 = require("@libs/novelStatus"); +var parseMadaraDate_1 = require("@libs/parseMadaraDate"); +var dayjs_1 = __importDefault(require("dayjs")); +var MadaraDefaultPath = { + novels: 'novel', + novel: 'novel', + chapter: 'novel' +}; +var MadaraPlugin = /** @class */ (function () { + function MadaraPlugin(metadata) { + this.id = metadata.id; + this.name = metadata.sourceName + "[madara]"; + var iconFileName = metadata.sourceName.replace(/\s+/g, "").toLowerCase(); + this.icon = "multisrc/madara/icons/".concat(iconFileName, ".png"); + this.site = metadata.sourceSite; + this.version = "1.0.0"; + this.userAgent = ""; + this.cookieString = ""; + this.options = metadata.options; + this.filter = metadata.filters; + } + MadaraPlugin.prototype.popularNovels = function (pageNo, _a) { + var _b, _c, _d, _e, _f, _g; + var filters = _a.filters, showLatestNovels = _a.showLatestNovels; + return __awaiter(this, void 0, void 0, function () { + var novels, url, body, loadedCheerio; + return __generator(this, function (_h) { + switch (_h.label) { + case 0: + novels = []; + url = this.site; + if ((filters === null || filters === void 0 ? void 0 : filters.genres) && ((_c = (_b = this.options) === null || _b === void 0 ? void 0 : _b.path) === null || _c === void 0 ? void 0 : _c.genres)) { + url += ((_e = (_d = this.options) === null || _d === void 0 ? void 0 : _d.path) === null || _e === void 0 ? void 0 : _e.genres) + filters.genres + '/'; + } + else { + url += ((_g = (_f = this.options) === null || _f === void 0 ? void 0 : _f.path) === null || _g === void 0 ? void 0 : _g.novels) ? this.options.path.novels : MadaraDefaultPath.novels; + } + url += '/page/' + pageNo + '/' + + '?m_orderby=' + (showLatestNovels ? 'latest' : ((filters === null || filters === void 0 ? void 0 : filters.sort) || 'rating')); + return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })]; + case 1: + body = _h.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.manga-title-badges').remove(); + loadedCheerio('.page-item-detail').each(function () { + var novelName = loadedCheerio(this).find('.post-title').text().trim(); + var image = loadedCheerio(this).find('img'); + var novelCover = image.attr('data-src') || image.attr('src'); + var novelUrl = loadedCheerio(this).find('.post-title') + .find('a') + .attr('href') || ''; + var novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + novels.push(novel); + }); + return [2 /*return*/, novels]; + } + }); + }); + }; + MadaraPlugin.prototype.parseNovelAndChapters = function (novelUrl) { + var _a; + return __awaiter(this, void 0, void 0, function () { + var novel, body, loadedCheerio, html, novelId, formData, chapters; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + novel = { + url: novelUrl, + }; + return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl).then(function (res) { return res.text(); })]; + case 1: + body = _b.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.manga-title-badges, #manga-title span').remove(); + novel.name = + loadedCheerio('.post-title h1').text().trim() || + loadedCheerio('#manga-title h1').text(); + novel.cover = + loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || + loadedCheerio('.summary_image > a > img').attr('data-src') || + loadedCheerio('.summary_image > a > img').attr('src') || + defaultCover_1.defaultCover; + loadedCheerio('.post-content_item, .post-content').each(function () { + var detailName = loadedCheerio(this).find('h5').text().trim(); + var detail = loadedCheerio(this).find('.summary-content').text().trim(); + switch (detailName) { + case 'Genre(s)': + case 'التصنيفات': + novel.genres = detail.replace(/[\\t\\n]/g, ','); + break; + case 'Author(s)': + case 'المؤلف': + case 'المؤلف (ين)': + novel.author = detail; + break; + case 'Status': + case 'الحالة': + novel.status = + detail.includes('OnGoing') || detail.includes('مستمرة') + ? novelStatus_1.NovelStatus.Ongoing + : novelStatus_1.NovelStatus.Completed; + break; + } + }); + loadedCheerio('div.summary__content .code-block,script').remove(); + novel.summary = + loadedCheerio('div.summary__content').text().trim() || + loadedCheerio('#tab-manga-about').text().trim() || + loadedCheerio('.post-content_item h5:contains("Summary")').next().text().trim(); + if (!(((_a = this.options) === null || _a === void 0 ? void 0 : _a.useNewChapterEndpoint) !== true)) return [3 /*break*/, 3]; + novelId = loadedCheerio('.rating-post-id').attr('value') || + loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; + formData = new FormData(); + formData.append("action", "manga_get_chapters"); + formData.append("manga", novelId); + return [4 /*yield*/, (0, fetch_1.fetchApi)(this.site + 'wp-admin/admin-ajax.php', { + method: 'POST', + body: formData, + }) + .then(function (res) { return res.text(); })]; + case 2: + html = _b.sent(); + return [3 /*break*/, 5]; + case 3: return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl + 'ajax/chapters/', { method: 'POST' }) + .then(function (res) { return res.text(); })]; + case 4: + html = _b.sent(); + _b.label = 5; + case 5: + if (html !== '0') { + loadedCheerio = (0, cheerio_1.load)(html); + } + chapters = []; + loadedCheerio('.wp-manga-chapter').each(function () { + var chapterName = loadedCheerio(this).find('a').text().trim(); + var releaseDate = null; + releaseDate = loadedCheerio(this) + .find('span.chapter-release-date') + .text() + .trim(); + if (releaseDate) { + releaseDate = (0, parseMadaraDate_1.parseMadaraDate)(releaseDate); + } + else { + /** + * Insert current date + */ + releaseDate = (0, dayjs_1.default)().format('LL'); + } + var chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); + }); + novel.chapters = chapters.reverse(); + return [2 /*return*/, novel]; + } + }); + }); + }; + MadaraPlugin.prototype.parseChapter = function (chapterUrl) { + return __awaiter(this, void 0, void 0, function () { + var body, loadedCheerio, chapterText; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, (0, fetch_1.fetchApi)(chapterUrl).then(function (res) { return res.text(); })]; + case 1: + body = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + chapterText = loadedCheerio('.text-left').html() || + loadedCheerio('.text-right').html() || + loadedCheerio('.entry-content').html() || ""; + return [2 /*return*/, chapterText]; + } + }); + }); + }; + MadaraPlugin.prototype.searchNovels = function (searchTerm, pageNo) { + return __awaiter(this, void 0, void 0, function () { + var novels, url, body, loadedCheerio; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + novels = []; + url = this.site + "?s=" + searchTerm + "&post_type=wp-manga"; + return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })]; + case 1: + body = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.c-tabs-item__content').each(function () { + var novelName = loadedCheerio(this).find('.post-title').text().trim(); + var image = loadedCheerio(this).find('img'); + var novelCover = image.attr('data-src') || image.attr('src'); + var novelUrl = loadedCheerio(this) + .find('.post-title') + .find('a') + .attr('href') || ''; + var novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + novels.push(novel); + }); + return [2 /*return*/, novels]; + } + }); + }); + }; + MadaraPlugin.prototype.fetchImage = function (url) { + return __awaiter(this, void 0, void 0, function () { + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, (0, fetch_1.fetchFile)(url, {})]; + case 1: return [2 /*return*/, _a.sent()]; + } + }); + }); + }; + return MadaraPlugin; +}()); +var plugin = new MadaraPlugin({ "id": "novelr18", "sourceSite": "https://novelr18.com/", "sourceName": "NovelR18", "filters": [{ "key": "sort", "label": "Sort by :", "values": [{ "label": "Rating", "value": "rating" }, { "label": "A-Z", "value": "alphabet" }, { "label": "Latest Update", "value": "latest" }, { "label": "Most Views", "value": "views" }, { "label": "Newly Added Novels", "value": "new-manga" }, { "label": "Trending", "value": "trending" }], "inputType": "Picker" }], "options": { "path": { "novels": "novel", "novel": "manga", "chapter": "manga" }, "useNewChapterEndpoint": true, "lang": "English" } }); +exports.default = plugin; diff --git a/.js/plugins/english/NovelTranslate[madara].js b/.js/plugins/english/NovelTranslate[madara].js new file mode 100644 index 0000000..3abed76 --- /dev/null +++ b/.js/plugins/english/NovelTranslate[madara].js @@ -0,0 +1,269 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __generator = (this && this.__generator) || function (thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (g && (g = 0, op[0] && (_ = 0)), _) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +}; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var fetch_1 = require("@libs/fetch"); +var cheerio_1 = require("cheerio"); +var defaultCover_1 = require("@libs/defaultCover"); +var novelStatus_1 = require("@libs/novelStatus"); +var parseMadaraDate_1 = require("@libs/parseMadaraDate"); +var dayjs_1 = __importDefault(require("dayjs")); +var MadaraDefaultPath = { + novels: 'novel', + novel: 'novel', + chapter: 'novel' +}; +var MadaraPlugin = /** @class */ (function () { + function MadaraPlugin(metadata) { + this.id = metadata.id; + this.name = metadata.sourceName + "[madara]"; + var iconFileName = metadata.sourceName.replace(/\s+/g, "").toLowerCase(); + this.icon = "multisrc/madara/icons/".concat(iconFileName, ".png"); + this.site = metadata.sourceSite; + this.version = "1.0.0"; + this.userAgent = ""; + this.cookieString = ""; + this.options = metadata.options; + this.filter = metadata.filters; + } + MadaraPlugin.prototype.popularNovels = function (pageNo, _a) { + var _b, _c, _d, _e, _f, _g; + var filters = _a.filters, showLatestNovels = _a.showLatestNovels; + return __awaiter(this, void 0, void 0, function () { + var novels, url, body, loadedCheerio; + return __generator(this, function (_h) { + switch (_h.label) { + case 0: + novels = []; + url = this.site; + if ((filters === null || filters === void 0 ? void 0 : filters.genres) && ((_c = (_b = this.options) === null || _b === void 0 ? void 0 : _b.path) === null || _c === void 0 ? void 0 : _c.genres)) { + url += ((_e = (_d = this.options) === null || _d === void 0 ? void 0 : _d.path) === null || _e === void 0 ? void 0 : _e.genres) + filters.genres + '/'; + } + else { + url += ((_g = (_f = this.options) === null || _f === void 0 ? void 0 : _f.path) === null || _g === void 0 ? void 0 : _g.novels) ? this.options.path.novels : MadaraDefaultPath.novels; + } + url += '/page/' + pageNo + '/' + + '?m_orderby=' + (showLatestNovels ? 'latest' : ((filters === null || filters === void 0 ? void 0 : filters.sort) || 'rating')); + return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })]; + case 1: + body = _h.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.manga-title-badges').remove(); + loadedCheerio('.page-item-detail').each(function () { + var novelName = loadedCheerio(this).find('.post-title').text().trim(); + var image = loadedCheerio(this).find('img'); + var novelCover = image.attr('data-src') || image.attr('src'); + var novelUrl = loadedCheerio(this).find('.post-title') + .find('a') + .attr('href') || ''; + var novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + novels.push(novel); + }); + return [2 /*return*/, novels]; + } + }); + }); + }; + MadaraPlugin.prototype.parseNovelAndChapters = function (novelUrl) { + var _a; + return __awaiter(this, void 0, void 0, function () { + var novel, body, loadedCheerio, html, novelId, formData, chapters; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + novel = { + url: novelUrl, + }; + return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl).then(function (res) { return res.text(); })]; + case 1: + body = _b.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.manga-title-badges, #manga-title span').remove(); + novel.name = + loadedCheerio('.post-title h1').text().trim() || + loadedCheerio('#manga-title h1').text(); + novel.cover = + loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || + loadedCheerio('.summary_image > a > img').attr('data-src') || + loadedCheerio('.summary_image > a > img').attr('src') || + defaultCover_1.defaultCover; + loadedCheerio('.post-content_item, .post-content').each(function () { + var detailName = loadedCheerio(this).find('h5').text().trim(); + var detail = loadedCheerio(this).find('.summary-content').text().trim(); + switch (detailName) { + case 'Genre(s)': + case 'التصنيفات': + novel.genres = detail.replace(/[\\t\\n]/g, ','); + break; + case 'Author(s)': + case 'المؤلف': + case 'المؤلف (ين)': + novel.author = detail; + break; + case 'Status': + case 'الحالة': + novel.status = + detail.includes('OnGoing') || detail.includes('مستمرة') + ? novelStatus_1.NovelStatus.Ongoing + : novelStatus_1.NovelStatus.Completed; + break; + } + }); + loadedCheerio('div.summary__content .code-block,script').remove(); + novel.summary = + loadedCheerio('div.summary__content').text().trim() || + loadedCheerio('#tab-manga-about').text().trim() || + loadedCheerio('.post-content_item h5:contains("Summary")').next().text().trim(); + if (!(((_a = this.options) === null || _a === void 0 ? void 0 : _a.useNewChapterEndpoint) !== true)) return [3 /*break*/, 3]; + novelId = loadedCheerio('.rating-post-id').attr('value') || + loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; + formData = new FormData(); + formData.append("action", "manga_get_chapters"); + formData.append("manga", novelId); + return [4 /*yield*/, (0, fetch_1.fetchApi)(this.site + 'wp-admin/admin-ajax.php', { + method: 'POST', + body: formData, + }) + .then(function (res) { return res.text(); })]; + case 2: + html = _b.sent(); + return [3 /*break*/, 5]; + case 3: return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl + 'ajax/chapters/', { method: 'POST' }) + .then(function (res) { return res.text(); })]; + case 4: + html = _b.sent(); + _b.label = 5; + case 5: + if (html !== '0') { + loadedCheerio = (0, cheerio_1.load)(html); + } + chapters = []; + loadedCheerio('.wp-manga-chapter').each(function () { + var chapterName = loadedCheerio(this).find('a').text().trim(); + var releaseDate = null; + releaseDate = loadedCheerio(this) + .find('span.chapter-release-date') + .text() + .trim(); + if (releaseDate) { + releaseDate = (0, parseMadaraDate_1.parseMadaraDate)(releaseDate); + } + else { + /** + * Insert current date + */ + releaseDate = (0, dayjs_1.default)().format('LL'); + } + var chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); + }); + novel.chapters = chapters.reverse(); + return [2 /*return*/, novel]; + } + }); + }); + }; + MadaraPlugin.prototype.parseChapter = function (chapterUrl) { + return __awaiter(this, void 0, void 0, function () { + var body, loadedCheerio, chapterText; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, (0, fetch_1.fetchApi)(chapterUrl).then(function (res) { return res.text(); })]; + case 1: + body = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + chapterText = loadedCheerio('.text-left').html() || + loadedCheerio('.text-right').html() || + loadedCheerio('.entry-content').html() || ""; + return [2 /*return*/, chapterText]; + } + }); + }); + }; + MadaraPlugin.prototype.searchNovels = function (searchTerm, pageNo) { + return __awaiter(this, void 0, void 0, function () { + var novels, url, body, loadedCheerio; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + novels = []; + url = this.site + "?s=" + searchTerm + "&post_type=wp-manga"; + return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })]; + case 1: + body = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.c-tabs-item__content').each(function () { + var novelName = loadedCheerio(this).find('.post-title').text().trim(); + var image = loadedCheerio(this).find('img'); + var novelCover = image.attr('data-src') || image.attr('src'); + var novelUrl = loadedCheerio(this) + .find('.post-title') + .find('a') + .attr('href') || ''; + var novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + novels.push(novel); + }); + return [2 /*return*/, novels]; + } + }); + }); + }; + MadaraPlugin.prototype.fetchImage = function (url) { + return __awaiter(this, void 0, void 0, function () { + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, (0, fetch_1.fetchFile)(url, {})]; + case 1: return [2 /*return*/, _a.sent()]; + } + }); + }); + }; + return MadaraPlugin; +}()); +var plugin = new MadaraPlugin({ "id": "novelTL", "sourceSite": "https://noveltranslate.com/", "sourceName": "NovelTranslate", "filters": [{ "key": "sort", "label": "Order by", "values": [{ "label": "Rating", "value": "rating" }, { "label": "A-Z", "value": "alphabet" }, { "label": "Latest", "value": "latest" }, { "label": "Most Views", "value": "views" }, { "label": "New", "value": "new-manga" }, { "label": "Trending", "value": "trending" }], "inputType": "Picker" }, { "key": "genres", "label": "GENRES", "values": [{ "label": "Action", "value": "action" }, { "label": "Adult", "value": "adult" }, { "label": "Adventure", "value": "adventure" }, { "label": "Bleach", "value": "bleach" }, { "label": "Chinese", "value": "chinese" }, { "label": "Comedy", "value": "comedy" }, { "label": "Conan", "value": "conan" }, { "label": "cooking", "value": "cooking" }, { "label": "Dragon Ball", "value": "dragon-ball" }, { "label": "Drama", "value": "drama" }, { "label": "Ecchi", "value": "ecchi" }, { "label": "Erciyuan", "value": "erciyuan" }, { "label": "Fairy Tail", "value": "fairy-tail" }, { "label": "Faloo", "value": "faloo" }, { "label": "Fan-Fiction", "value": "fan-fiction" }, { "label": "Fantasy", "value": "fantasy" }, { "label": "FoodWars!", "value": "foodwars" }, { "label": "Game", "value": "game" }, { "label": "Gender Bender", "value": "gender-bender" }, { "label": "Harem", "value": "harem" }, { "label": "Historical", "value": "historical" }, { "label": "Horror", "value": "horror" }, { "label": "Hunter x Hunter", "value": "hunter-x-hunter" }, { "label": "Isekai", "value": "isekai" }, { "label": "Japanese", "value": "japanese" }, { "label": "Jojo", "value": "jojo" }, { "label": "Josei", "value": "josei" }, { "label": "Korean", "value": "korean" }, { "label": "Martial Arts", "value": "martial-arts" }, { "label": "Marvel", "value": "marvel" }, { "label": "Mature", "value": "mature" }, { "label": "Mecha", "value": "mecha" }, { "label": "Military", "value": "military" }, { "label": "Mystery", "value": "mystery" }, { "label": "Naruto", "value": "naruto" }, { "label": "One piece", "value": "one-piece" }, { "label": "Pokemon", "value": "pokemon" }, { "label": "Political", "value": "political" }, { "label": "Psychological", "value": "psychological" }, { "label": "Romance", "value": "romance" }, { "label": "School Life", "value": "school-life" }, { "label": "Sci-fi", "value": "sci-fi" }, { "label": "Seinen", "value": "seinen" }, { "label": "Shoujo", "value": "shoujo" }, { "label": "Shoujo Ai", "value": "shoujo-ai" }, { "label": "Shounen", "value": "shounen" }, { "label": "Shounen Ai", "value": "shounen-ai" }, { "label": "Slice of Life", "value": "slice-of-life" }, { "label": "Smut", "value": "smut" }, { "label": "Sport", "value": "sport" }, { "label": "Sports", "value": "sports" }, { "label": "Supernatural", "value": "supernatural" }, { "label": "System", "value": "system" }, { "label": "Toriko", "value": "toriko" }, { "label": "Tragedy", "value": "tragedy" }, { "label": "Urban", "value": "urban" }, { "label": "Urban Life", "value": "urban-life" }, { "label": "Wuxia", "value": "wuxia" }, { "label": "Xianxia", "value": "xianxia" }, { "label": "Xuanhuan", "value": "xuanhuan" }, { "label": "Yaoi", "value": "yaoi" }, { "label": "Yuri", "value": "yuri" }], "inputType": "Picker" }], "options": { "path": { "novels": "all-novels", "novel": "manga", "chapter": "manga", "genres": "manga-genre" }, "lang": "English" } }); +exports.default = plugin; diff --git a/.js/plugins/english/Novelroomnet[madara].js b/.js/plugins/english/Novelroomnet[madara].js new file mode 100644 index 0000000..8b5455e --- /dev/null +++ b/.js/plugins/english/Novelroomnet[madara].js @@ -0,0 +1,269 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __generator = (this && this.__generator) || function (thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (g && (g = 0, op[0] && (_ = 0)), _) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +}; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var fetch_1 = require("@libs/fetch"); +var cheerio_1 = require("cheerio"); +var defaultCover_1 = require("@libs/defaultCover"); +var novelStatus_1 = require("@libs/novelStatus"); +var parseMadaraDate_1 = require("@libs/parseMadaraDate"); +var dayjs_1 = __importDefault(require("dayjs")); +var MadaraDefaultPath = { + novels: 'novel', + novel: 'novel', + chapter: 'novel' +}; +var MadaraPlugin = /** @class */ (function () { + function MadaraPlugin(metadata) { + this.id = metadata.id; + this.name = metadata.sourceName + "[madara]"; + var iconFileName = metadata.sourceName.replace(/\s+/g, "").toLowerCase(); + this.icon = "multisrc/madara/icons/".concat(iconFileName, ".png"); + this.site = metadata.sourceSite; + this.version = "1.0.0"; + this.userAgent = ""; + this.cookieString = ""; + this.options = metadata.options; + this.filter = metadata.filters; + } + MadaraPlugin.prototype.popularNovels = function (pageNo, _a) { + var _b, _c, _d, _e, _f, _g; + var filters = _a.filters, showLatestNovels = _a.showLatestNovels; + return __awaiter(this, void 0, void 0, function () { + var novels, url, body, loadedCheerio; + return __generator(this, function (_h) { + switch (_h.label) { + case 0: + novels = []; + url = this.site; + if ((filters === null || filters === void 0 ? void 0 : filters.genres) && ((_c = (_b = this.options) === null || _b === void 0 ? void 0 : _b.path) === null || _c === void 0 ? void 0 : _c.genres)) { + url += ((_e = (_d = this.options) === null || _d === void 0 ? void 0 : _d.path) === null || _e === void 0 ? void 0 : _e.genres) + filters.genres + '/'; + } + else { + url += ((_g = (_f = this.options) === null || _f === void 0 ? void 0 : _f.path) === null || _g === void 0 ? void 0 : _g.novels) ? this.options.path.novels : MadaraDefaultPath.novels; + } + url += '/page/' + pageNo + '/' + + '?m_orderby=' + (showLatestNovels ? 'latest' : ((filters === null || filters === void 0 ? void 0 : filters.sort) || 'rating')); + return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })]; + case 1: + body = _h.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.manga-title-badges').remove(); + loadedCheerio('.page-item-detail').each(function () { + var novelName = loadedCheerio(this).find('.post-title').text().trim(); + var image = loadedCheerio(this).find('img'); + var novelCover = image.attr('data-src') || image.attr('src'); + var novelUrl = loadedCheerio(this).find('.post-title') + .find('a') + .attr('href') || ''; + var novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + novels.push(novel); + }); + return [2 /*return*/, novels]; + } + }); + }); + }; + MadaraPlugin.prototype.parseNovelAndChapters = function (novelUrl) { + var _a; + return __awaiter(this, void 0, void 0, function () { + var novel, body, loadedCheerio, html, novelId, formData, chapters; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + novel = { + url: novelUrl, + }; + return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl).then(function (res) { return res.text(); })]; + case 1: + body = _b.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.manga-title-badges, #manga-title span').remove(); + novel.name = + loadedCheerio('.post-title h1').text().trim() || + loadedCheerio('#manga-title h1').text(); + novel.cover = + loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || + loadedCheerio('.summary_image > a > img').attr('data-src') || + loadedCheerio('.summary_image > a > img').attr('src') || + defaultCover_1.defaultCover; + loadedCheerio('.post-content_item, .post-content').each(function () { + var detailName = loadedCheerio(this).find('h5').text().trim(); + var detail = loadedCheerio(this).find('.summary-content').text().trim(); + switch (detailName) { + case 'Genre(s)': + case 'التصنيفات': + novel.genres = detail.replace(/[\\t\\n]/g, ','); + break; + case 'Author(s)': + case 'المؤلف': + case 'المؤلف (ين)': + novel.author = detail; + break; + case 'Status': + case 'الحالة': + novel.status = + detail.includes('OnGoing') || detail.includes('مستمرة') + ? novelStatus_1.NovelStatus.Ongoing + : novelStatus_1.NovelStatus.Completed; + break; + } + }); + loadedCheerio('div.summary__content .code-block,script').remove(); + novel.summary = + loadedCheerio('div.summary__content').text().trim() || + loadedCheerio('#tab-manga-about').text().trim() || + loadedCheerio('.post-content_item h5:contains("Summary")').next().text().trim(); + if (!(((_a = this.options) === null || _a === void 0 ? void 0 : _a.useNewChapterEndpoint) !== true)) return [3 /*break*/, 3]; + novelId = loadedCheerio('.rating-post-id').attr('value') || + loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; + formData = new FormData(); + formData.append("action", "manga_get_chapters"); + formData.append("manga", novelId); + return [4 /*yield*/, (0, fetch_1.fetchApi)(this.site + 'wp-admin/admin-ajax.php', { + method: 'POST', + body: formData, + }) + .then(function (res) { return res.text(); })]; + case 2: + html = _b.sent(); + return [3 /*break*/, 5]; + case 3: return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl + 'ajax/chapters/', { method: 'POST' }) + .then(function (res) { return res.text(); })]; + case 4: + html = _b.sent(); + _b.label = 5; + case 5: + if (html !== '0') { + loadedCheerio = (0, cheerio_1.load)(html); + } + chapters = []; + loadedCheerio('.wp-manga-chapter').each(function () { + var chapterName = loadedCheerio(this).find('a').text().trim(); + var releaseDate = null; + releaseDate = loadedCheerio(this) + .find('span.chapter-release-date') + .text() + .trim(); + if (releaseDate) { + releaseDate = (0, parseMadaraDate_1.parseMadaraDate)(releaseDate); + } + else { + /** + * Insert current date + */ + releaseDate = (0, dayjs_1.default)().format('LL'); + } + var chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); + }); + novel.chapters = chapters.reverse(); + return [2 /*return*/, novel]; + } + }); + }); + }; + MadaraPlugin.prototype.parseChapter = function (chapterUrl) { + return __awaiter(this, void 0, void 0, function () { + var body, loadedCheerio, chapterText; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, (0, fetch_1.fetchApi)(chapterUrl).then(function (res) { return res.text(); })]; + case 1: + body = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + chapterText = loadedCheerio('.text-left').html() || + loadedCheerio('.text-right').html() || + loadedCheerio('.entry-content').html() || ""; + return [2 /*return*/, chapterText]; + } + }); + }); + }; + MadaraPlugin.prototype.searchNovels = function (searchTerm, pageNo) { + return __awaiter(this, void 0, void 0, function () { + var novels, url, body, loadedCheerio; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + novels = []; + url = this.site + "?s=" + searchTerm + "&post_type=wp-manga"; + return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })]; + case 1: + body = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.c-tabs-item__content').each(function () { + var novelName = loadedCheerio(this).find('.post-title').text().trim(); + var image = loadedCheerio(this).find('img'); + var novelCover = image.attr('data-src') || image.attr('src'); + var novelUrl = loadedCheerio(this) + .find('.post-title') + .find('a') + .attr('href') || ''; + var novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + novels.push(novel); + }); + return [2 /*return*/, novels]; + } + }); + }); + }; + MadaraPlugin.prototype.fetchImage = function (url) { + return __awaiter(this, void 0, void 0, function () { + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, (0, fetch_1.fetchFile)(url, {})]; + case 1: return [2 /*return*/, _a.sent()]; + } + }); + }); + }; + return MadaraPlugin; +}()); +var plugin = new MadaraPlugin({ "id": "novelroom", "sourceSite": "https://novelroom.net/", "sourceName": "Novelroom.net", "filters": [], "options": { "path": { "novels": "manga", "novel": "manga", "chapter": "manga" }, "lang": "English" } }); +exports.default = plugin; diff --git a/.js/plugins/english/Novelstic[madara].js b/.js/plugins/english/Novelstic[madara].js new file mode 100644 index 0000000..2e9f9a5 --- /dev/null +++ b/.js/plugins/english/Novelstic[madara].js @@ -0,0 +1,269 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __generator = (this && this.__generator) || function (thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (g && (g = 0, op[0] && (_ = 0)), _) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +}; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var fetch_1 = require("@libs/fetch"); +var cheerio_1 = require("cheerio"); +var defaultCover_1 = require("@libs/defaultCover"); +var novelStatus_1 = require("@libs/novelStatus"); +var parseMadaraDate_1 = require("@libs/parseMadaraDate"); +var dayjs_1 = __importDefault(require("dayjs")); +var MadaraDefaultPath = { + novels: 'novel', + novel: 'novel', + chapter: 'novel' +}; +var MadaraPlugin = /** @class */ (function () { + function MadaraPlugin(metadata) { + this.id = metadata.id; + this.name = metadata.sourceName + "[madara]"; + var iconFileName = metadata.sourceName.replace(/\s+/g, "").toLowerCase(); + this.icon = "multisrc/madara/icons/".concat(iconFileName, ".png"); + this.site = metadata.sourceSite; + this.version = "1.0.0"; + this.userAgent = ""; + this.cookieString = ""; + this.options = metadata.options; + this.filter = metadata.filters; + } + MadaraPlugin.prototype.popularNovels = function (pageNo, _a) { + var _b, _c, _d, _e, _f, _g; + var filters = _a.filters, showLatestNovels = _a.showLatestNovels; + return __awaiter(this, void 0, void 0, function () { + var novels, url, body, loadedCheerio; + return __generator(this, function (_h) { + switch (_h.label) { + case 0: + novels = []; + url = this.site; + if ((filters === null || filters === void 0 ? void 0 : filters.genres) && ((_c = (_b = this.options) === null || _b === void 0 ? void 0 : _b.path) === null || _c === void 0 ? void 0 : _c.genres)) { + url += ((_e = (_d = this.options) === null || _d === void 0 ? void 0 : _d.path) === null || _e === void 0 ? void 0 : _e.genres) + filters.genres + '/'; + } + else { + url += ((_g = (_f = this.options) === null || _f === void 0 ? void 0 : _f.path) === null || _g === void 0 ? void 0 : _g.novels) ? this.options.path.novels : MadaraDefaultPath.novels; + } + url += '/page/' + pageNo + '/' + + '?m_orderby=' + (showLatestNovels ? 'latest' : ((filters === null || filters === void 0 ? void 0 : filters.sort) || 'rating')); + return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })]; + case 1: + body = _h.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.manga-title-badges').remove(); + loadedCheerio('.page-item-detail').each(function () { + var novelName = loadedCheerio(this).find('.post-title').text().trim(); + var image = loadedCheerio(this).find('img'); + var novelCover = image.attr('data-src') || image.attr('src'); + var novelUrl = loadedCheerio(this).find('.post-title') + .find('a') + .attr('href') || ''; + var novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + novels.push(novel); + }); + return [2 /*return*/, novels]; + } + }); + }); + }; + MadaraPlugin.prototype.parseNovelAndChapters = function (novelUrl) { + var _a; + return __awaiter(this, void 0, void 0, function () { + var novel, body, loadedCheerio, html, novelId, formData, chapters; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + novel = { + url: novelUrl, + }; + return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl).then(function (res) { return res.text(); })]; + case 1: + body = _b.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.manga-title-badges, #manga-title span').remove(); + novel.name = + loadedCheerio('.post-title h1').text().trim() || + loadedCheerio('#manga-title h1').text(); + novel.cover = + loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || + loadedCheerio('.summary_image > a > img').attr('data-src') || + loadedCheerio('.summary_image > a > img').attr('src') || + defaultCover_1.defaultCover; + loadedCheerio('.post-content_item, .post-content').each(function () { + var detailName = loadedCheerio(this).find('h5').text().trim(); + var detail = loadedCheerio(this).find('.summary-content').text().trim(); + switch (detailName) { + case 'Genre(s)': + case 'التصنيفات': + novel.genres = detail.replace(/[\\t\\n]/g, ','); + break; + case 'Author(s)': + case 'المؤلف': + case 'المؤلف (ين)': + novel.author = detail; + break; + case 'Status': + case 'الحالة': + novel.status = + detail.includes('OnGoing') || detail.includes('مستمرة') + ? novelStatus_1.NovelStatus.Ongoing + : novelStatus_1.NovelStatus.Completed; + break; + } + }); + loadedCheerio('div.summary__content .code-block,script').remove(); + novel.summary = + loadedCheerio('div.summary__content').text().trim() || + loadedCheerio('#tab-manga-about').text().trim() || + loadedCheerio('.post-content_item h5:contains("Summary")').next().text().trim(); + if (!(((_a = this.options) === null || _a === void 0 ? void 0 : _a.useNewChapterEndpoint) !== true)) return [3 /*break*/, 3]; + novelId = loadedCheerio('.rating-post-id').attr('value') || + loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; + formData = new FormData(); + formData.append("action", "manga_get_chapters"); + formData.append("manga", novelId); + return [4 /*yield*/, (0, fetch_1.fetchApi)(this.site + 'wp-admin/admin-ajax.php', { + method: 'POST', + body: formData, + }) + .then(function (res) { return res.text(); })]; + case 2: + html = _b.sent(); + return [3 /*break*/, 5]; + case 3: return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl + 'ajax/chapters/', { method: 'POST' }) + .then(function (res) { return res.text(); })]; + case 4: + html = _b.sent(); + _b.label = 5; + case 5: + if (html !== '0') { + loadedCheerio = (0, cheerio_1.load)(html); + } + chapters = []; + loadedCheerio('.wp-manga-chapter').each(function () { + var chapterName = loadedCheerio(this).find('a').text().trim(); + var releaseDate = null; + releaseDate = loadedCheerio(this) + .find('span.chapter-release-date') + .text() + .trim(); + if (releaseDate) { + releaseDate = (0, parseMadaraDate_1.parseMadaraDate)(releaseDate); + } + else { + /** + * Insert current date + */ + releaseDate = (0, dayjs_1.default)().format('LL'); + } + var chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); + }); + novel.chapters = chapters.reverse(); + return [2 /*return*/, novel]; + } + }); + }); + }; + MadaraPlugin.prototype.parseChapter = function (chapterUrl) { + return __awaiter(this, void 0, void 0, function () { + var body, loadedCheerio, chapterText; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, (0, fetch_1.fetchApi)(chapterUrl).then(function (res) { return res.text(); })]; + case 1: + body = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + chapterText = loadedCheerio('.text-left').html() || + loadedCheerio('.text-right').html() || + loadedCheerio('.entry-content').html() || ""; + return [2 /*return*/, chapterText]; + } + }); + }); + }; + MadaraPlugin.prototype.searchNovels = function (searchTerm, pageNo) { + return __awaiter(this, void 0, void 0, function () { + var novels, url, body, loadedCheerio; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + novels = []; + url = this.site + "?s=" + searchTerm + "&post_type=wp-manga"; + return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })]; + case 1: + body = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.c-tabs-item__content').each(function () { + var novelName = loadedCheerio(this).find('.post-title').text().trim(); + var image = loadedCheerio(this).find('img'); + var novelCover = image.attr('data-src') || image.attr('src'); + var novelUrl = loadedCheerio(this) + .find('.post-title') + .find('a') + .attr('href') || ''; + var novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + novels.push(novel); + }); + return [2 /*return*/, novels]; + } + }); + }); + }; + MadaraPlugin.prototype.fetchImage = function (url) { + return __awaiter(this, void 0, void 0, function () { + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, (0, fetch_1.fetchFile)(url, {})]; + case 1: return [2 /*return*/, _a.sent()]; + } + }); + }); + }; + return MadaraPlugin; +}()); +var plugin = new MadaraPlugin({ "id": "novelstic", "sourceSite": "https://novelstic.com/", "sourceName": "Novelstic", "filters": [{ "key": "sort", "label": "Order by", "values": [{ "label": "Rating", "value": "rating" }, { "label": "A-Z", "value": "alphabet" }, { "label": "Latest", "value": "latest" }, { "label": "Most Views", "value": "views" }, { "label": "New", "value": "new-manga" }, { "label": "Trending", "value": "trending" }], "inputType": "Picker" }], "options": { "useNewChapterEndpoint": true, "lang": "English" } }); +exports.default = plugin; diff --git a/.js/plugins/english/OnlyMTL[madara].js b/.js/plugins/english/OnlyMTL[madara].js new file mode 100644 index 0000000..eb7513f --- /dev/null +++ b/.js/plugins/english/OnlyMTL[madara].js @@ -0,0 +1,269 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __generator = (this && this.__generator) || function (thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (g && (g = 0, op[0] && (_ = 0)), _) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +}; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var fetch_1 = require("@libs/fetch"); +var cheerio_1 = require("cheerio"); +var defaultCover_1 = require("@libs/defaultCover"); +var novelStatus_1 = require("@libs/novelStatus"); +var parseMadaraDate_1 = require("@libs/parseMadaraDate"); +var dayjs_1 = __importDefault(require("dayjs")); +var MadaraDefaultPath = { + novels: 'novel', + novel: 'novel', + chapter: 'novel' +}; +var MadaraPlugin = /** @class */ (function () { + function MadaraPlugin(metadata) { + this.id = metadata.id; + this.name = metadata.sourceName + "[madara]"; + var iconFileName = metadata.sourceName.replace(/\s+/g, "").toLowerCase(); + this.icon = "multisrc/madara/icons/".concat(iconFileName, ".png"); + this.site = metadata.sourceSite; + this.version = "1.0.0"; + this.userAgent = ""; + this.cookieString = ""; + this.options = metadata.options; + this.filter = metadata.filters; + } + MadaraPlugin.prototype.popularNovels = function (pageNo, _a) { + var _b, _c, _d, _e, _f, _g; + var filters = _a.filters, showLatestNovels = _a.showLatestNovels; + return __awaiter(this, void 0, void 0, function () { + var novels, url, body, loadedCheerio; + return __generator(this, function (_h) { + switch (_h.label) { + case 0: + novels = []; + url = this.site; + if ((filters === null || filters === void 0 ? void 0 : filters.genres) && ((_c = (_b = this.options) === null || _b === void 0 ? void 0 : _b.path) === null || _c === void 0 ? void 0 : _c.genres)) { + url += ((_e = (_d = this.options) === null || _d === void 0 ? void 0 : _d.path) === null || _e === void 0 ? void 0 : _e.genres) + filters.genres + '/'; + } + else { + url += ((_g = (_f = this.options) === null || _f === void 0 ? void 0 : _f.path) === null || _g === void 0 ? void 0 : _g.novels) ? this.options.path.novels : MadaraDefaultPath.novels; + } + url += '/page/' + pageNo + '/' + + '?m_orderby=' + (showLatestNovels ? 'latest' : ((filters === null || filters === void 0 ? void 0 : filters.sort) || 'rating')); + return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })]; + case 1: + body = _h.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.manga-title-badges').remove(); + loadedCheerio('.page-item-detail').each(function () { + var novelName = loadedCheerio(this).find('.post-title').text().trim(); + var image = loadedCheerio(this).find('img'); + var novelCover = image.attr('data-src') || image.attr('src'); + var novelUrl = loadedCheerio(this).find('.post-title') + .find('a') + .attr('href') || ''; + var novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + novels.push(novel); + }); + return [2 /*return*/, novels]; + } + }); + }); + }; + MadaraPlugin.prototype.parseNovelAndChapters = function (novelUrl) { + var _a; + return __awaiter(this, void 0, void 0, function () { + var novel, body, loadedCheerio, html, novelId, formData, chapters; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + novel = { + url: novelUrl, + }; + return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl).then(function (res) { return res.text(); })]; + case 1: + body = _b.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.manga-title-badges, #manga-title span').remove(); + novel.name = + loadedCheerio('.post-title h1').text().trim() || + loadedCheerio('#manga-title h1').text(); + novel.cover = + loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || + loadedCheerio('.summary_image > a > img').attr('data-src') || + loadedCheerio('.summary_image > a > img').attr('src') || + defaultCover_1.defaultCover; + loadedCheerio('.post-content_item, .post-content').each(function () { + var detailName = loadedCheerio(this).find('h5').text().trim(); + var detail = loadedCheerio(this).find('.summary-content').text().trim(); + switch (detailName) { + case 'Genre(s)': + case 'التصنيفات': + novel.genres = detail.replace(/[\\t\\n]/g, ','); + break; + case 'Author(s)': + case 'المؤلف': + case 'المؤلف (ين)': + novel.author = detail; + break; + case 'Status': + case 'الحالة': + novel.status = + detail.includes('OnGoing') || detail.includes('مستمرة') + ? novelStatus_1.NovelStatus.Ongoing + : novelStatus_1.NovelStatus.Completed; + break; + } + }); + loadedCheerio('div.summary__content .code-block,script').remove(); + novel.summary = + loadedCheerio('div.summary__content').text().trim() || + loadedCheerio('#tab-manga-about').text().trim() || + loadedCheerio('.post-content_item h5:contains("Summary")').next().text().trim(); + if (!(((_a = this.options) === null || _a === void 0 ? void 0 : _a.useNewChapterEndpoint) !== true)) return [3 /*break*/, 3]; + novelId = loadedCheerio('.rating-post-id').attr('value') || + loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; + formData = new FormData(); + formData.append("action", "manga_get_chapters"); + formData.append("manga", novelId); + return [4 /*yield*/, (0, fetch_1.fetchApi)(this.site + 'wp-admin/admin-ajax.php', { + method: 'POST', + body: formData, + }) + .then(function (res) { return res.text(); })]; + case 2: + html = _b.sent(); + return [3 /*break*/, 5]; + case 3: return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl + 'ajax/chapters/', { method: 'POST' }) + .then(function (res) { return res.text(); })]; + case 4: + html = _b.sent(); + _b.label = 5; + case 5: + if (html !== '0') { + loadedCheerio = (0, cheerio_1.load)(html); + } + chapters = []; + loadedCheerio('.wp-manga-chapter').each(function () { + var chapterName = loadedCheerio(this).find('a').text().trim(); + var releaseDate = null; + releaseDate = loadedCheerio(this) + .find('span.chapter-release-date') + .text() + .trim(); + if (releaseDate) { + releaseDate = (0, parseMadaraDate_1.parseMadaraDate)(releaseDate); + } + else { + /** + * Insert current date + */ + releaseDate = (0, dayjs_1.default)().format('LL'); + } + var chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); + }); + novel.chapters = chapters.reverse(); + return [2 /*return*/, novel]; + } + }); + }); + }; + MadaraPlugin.prototype.parseChapter = function (chapterUrl) { + return __awaiter(this, void 0, void 0, function () { + var body, loadedCheerio, chapterText; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, (0, fetch_1.fetchApi)(chapterUrl).then(function (res) { return res.text(); })]; + case 1: + body = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + chapterText = loadedCheerio('.text-left').html() || + loadedCheerio('.text-right').html() || + loadedCheerio('.entry-content').html() || ""; + return [2 /*return*/, chapterText]; + } + }); + }); + }; + MadaraPlugin.prototype.searchNovels = function (searchTerm, pageNo) { + return __awaiter(this, void 0, void 0, function () { + var novels, url, body, loadedCheerio; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + novels = []; + url = this.site + "?s=" + searchTerm + "&post_type=wp-manga"; + return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })]; + case 1: + body = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.c-tabs-item__content').each(function () { + var novelName = loadedCheerio(this).find('.post-title').text().trim(); + var image = loadedCheerio(this).find('img'); + var novelCover = image.attr('data-src') || image.attr('src'); + var novelUrl = loadedCheerio(this) + .find('.post-title') + .find('a') + .attr('href') || ''; + var novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + novels.push(novel); + }); + return [2 /*return*/, novels]; + } + }); + }); + }; + MadaraPlugin.prototype.fetchImage = function (url) { + return __awaiter(this, void 0, void 0, function () { + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, (0, fetch_1.fetchFile)(url, {})]; + case 1: return [2 /*return*/, _a.sent()]; + } + }); + }); + }; + return MadaraPlugin; +}()); +var plugin = new MadaraPlugin({ "id": "onlymtl", "sourceSite": "https://www.onlymtl.com/", "sourceName": "OnlyMTL", "filters": [], "options": { "useNewChapterEndpoint": true, "lang": "English" } }); +exports.default = plugin; diff --git a/.js/plugins/english/ReadWebNovels[madara].js b/.js/plugins/english/ReadWebNovels[madara].js new file mode 100644 index 0000000..f93ae3f --- /dev/null +++ b/.js/plugins/english/ReadWebNovels[madara].js @@ -0,0 +1,269 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __generator = (this && this.__generator) || function (thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (g && (g = 0, op[0] && (_ = 0)), _) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +}; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var fetch_1 = require("@libs/fetch"); +var cheerio_1 = require("cheerio"); +var defaultCover_1 = require("@libs/defaultCover"); +var novelStatus_1 = require("@libs/novelStatus"); +var parseMadaraDate_1 = require("@libs/parseMadaraDate"); +var dayjs_1 = __importDefault(require("dayjs")); +var MadaraDefaultPath = { + novels: 'novel', + novel: 'novel', + chapter: 'novel' +}; +var MadaraPlugin = /** @class */ (function () { + function MadaraPlugin(metadata) { + this.id = metadata.id; + this.name = metadata.sourceName + "[madara]"; + var iconFileName = metadata.sourceName.replace(/\s+/g, "").toLowerCase(); + this.icon = "multisrc/madara/icons/".concat(iconFileName, ".png"); + this.site = metadata.sourceSite; + this.version = "1.0.0"; + this.userAgent = ""; + this.cookieString = ""; + this.options = metadata.options; + this.filter = metadata.filters; + } + MadaraPlugin.prototype.popularNovels = function (pageNo, _a) { + var _b, _c, _d, _e, _f, _g; + var filters = _a.filters, showLatestNovels = _a.showLatestNovels; + return __awaiter(this, void 0, void 0, function () { + var novels, url, body, loadedCheerio; + return __generator(this, function (_h) { + switch (_h.label) { + case 0: + novels = []; + url = this.site; + if ((filters === null || filters === void 0 ? void 0 : filters.genres) && ((_c = (_b = this.options) === null || _b === void 0 ? void 0 : _b.path) === null || _c === void 0 ? void 0 : _c.genres)) { + url += ((_e = (_d = this.options) === null || _d === void 0 ? void 0 : _d.path) === null || _e === void 0 ? void 0 : _e.genres) + filters.genres + '/'; + } + else { + url += ((_g = (_f = this.options) === null || _f === void 0 ? void 0 : _f.path) === null || _g === void 0 ? void 0 : _g.novels) ? this.options.path.novels : MadaraDefaultPath.novels; + } + url += '/page/' + pageNo + '/' + + '?m_orderby=' + (showLatestNovels ? 'latest' : ((filters === null || filters === void 0 ? void 0 : filters.sort) || 'rating')); + return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })]; + case 1: + body = _h.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.manga-title-badges').remove(); + loadedCheerio('.page-item-detail').each(function () { + var novelName = loadedCheerio(this).find('.post-title').text().trim(); + var image = loadedCheerio(this).find('img'); + var novelCover = image.attr('data-src') || image.attr('src'); + var novelUrl = loadedCheerio(this).find('.post-title') + .find('a') + .attr('href') || ''; + var novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + novels.push(novel); + }); + return [2 /*return*/, novels]; + } + }); + }); + }; + MadaraPlugin.prototype.parseNovelAndChapters = function (novelUrl) { + var _a; + return __awaiter(this, void 0, void 0, function () { + var novel, body, loadedCheerio, html, novelId, formData, chapters; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + novel = { + url: novelUrl, + }; + return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl).then(function (res) { return res.text(); })]; + case 1: + body = _b.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.manga-title-badges, #manga-title span').remove(); + novel.name = + loadedCheerio('.post-title h1').text().trim() || + loadedCheerio('#manga-title h1').text(); + novel.cover = + loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || + loadedCheerio('.summary_image > a > img').attr('data-src') || + loadedCheerio('.summary_image > a > img').attr('src') || + defaultCover_1.defaultCover; + loadedCheerio('.post-content_item, .post-content').each(function () { + var detailName = loadedCheerio(this).find('h5').text().trim(); + var detail = loadedCheerio(this).find('.summary-content').text().trim(); + switch (detailName) { + case 'Genre(s)': + case 'التصنيفات': + novel.genres = detail.replace(/[\\t\\n]/g, ','); + break; + case 'Author(s)': + case 'المؤلف': + case 'المؤلف (ين)': + novel.author = detail; + break; + case 'Status': + case 'الحالة': + novel.status = + detail.includes('OnGoing') || detail.includes('مستمرة') + ? novelStatus_1.NovelStatus.Ongoing + : novelStatus_1.NovelStatus.Completed; + break; + } + }); + loadedCheerio('div.summary__content .code-block,script').remove(); + novel.summary = + loadedCheerio('div.summary__content').text().trim() || + loadedCheerio('#tab-manga-about').text().trim() || + loadedCheerio('.post-content_item h5:contains("Summary")').next().text().trim(); + if (!(((_a = this.options) === null || _a === void 0 ? void 0 : _a.useNewChapterEndpoint) !== true)) return [3 /*break*/, 3]; + novelId = loadedCheerio('.rating-post-id').attr('value') || + loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; + formData = new FormData(); + formData.append("action", "manga_get_chapters"); + formData.append("manga", novelId); + return [4 /*yield*/, (0, fetch_1.fetchApi)(this.site + 'wp-admin/admin-ajax.php', { + method: 'POST', + body: formData, + }) + .then(function (res) { return res.text(); })]; + case 2: + html = _b.sent(); + return [3 /*break*/, 5]; + case 3: return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl + 'ajax/chapters/', { method: 'POST' }) + .then(function (res) { return res.text(); })]; + case 4: + html = _b.sent(); + _b.label = 5; + case 5: + if (html !== '0') { + loadedCheerio = (0, cheerio_1.load)(html); + } + chapters = []; + loadedCheerio('.wp-manga-chapter').each(function () { + var chapterName = loadedCheerio(this).find('a').text().trim(); + var releaseDate = null; + releaseDate = loadedCheerio(this) + .find('span.chapter-release-date') + .text() + .trim(); + if (releaseDate) { + releaseDate = (0, parseMadaraDate_1.parseMadaraDate)(releaseDate); + } + else { + /** + * Insert current date + */ + releaseDate = (0, dayjs_1.default)().format('LL'); + } + var chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); + }); + novel.chapters = chapters.reverse(); + return [2 /*return*/, novel]; + } + }); + }); + }; + MadaraPlugin.prototype.parseChapter = function (chapterUrl) { + return __awaiter(this, void 0, void 0, function () { + var body, loadedCheerio, chapterText; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, (0, fetch_1.fetchApi)(chapterUrl).then(function (res) { return res.text(); })]; + case 1: + body = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + chapterText = loadedCheerio('.text-left').html() || + loadedCheerio('.text-right').html() || + loadedCheerio('.entry-content').html() || ""; + return [2 /*return*/, chapterText]; + } + }); + }); + }; + MadaraPlugin.prototype.searchNovels = function (searchTerm, pageNo) { + return __awaiter(this, void 0, void 0, function () { + var novels, url, body, loadedCheerio; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + novels = []; + url = this.site + "?s=" + searchTerm + "&post_type=wp-manga"; + return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })]; + case 1: + body = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.c-tabs-item__content').each(function () { + var novelName = loadedCheerio(this).find('.post-title').text().trim(); + var image = loadedCheerio(this).find('img'); + var novelCover = image.attr('data-src') || image.attr('src'); + var novelUrl = loadedCheerio(this) + .find('.post-title') + .find('a') + .attr('href') || ''; + var novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + novels.push(novel); + }); + return [2 /*return*/, novels]; + } + }); + }); + }; + MadaraPlugin.prototype.fetchImage = function (url) { + return __awaiter(this, void 0, void 0, function () { + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, (0, fetch_1.fetchFile)(url, {})]; + case 1: return [2 /*return*/, _a.sent()]; + } + }); + }); + }; + return MadaraPlugin; +}()); +var plugin = new MadaraPlugin({ "id": "readwebnovels", "sourceSite": "https://readwebnovels.net/", "sourceName": "ReadWebNovels", "filters": [{ "key": "sort", "label": "Order by", "values": [{ "label": "Rating", "value": "rating" }, { "label": "A-Z", "value": "alphabet" }, { "label": "Latest", "value": "latest" }, { "label": "Most Views", "value": "views" }, { "label": "New", "value": "new-manga" }, { "label": "Trending", "value": "trending" }], "inputType": "Picker" }], "options": { "lang": "English" } }); +exports.default = plugin; diff --git a/.js/plugins/english/SleepyTranslations[madara].js b/.js/plugins/english/SleepyTranslations[madara].js new file mode 100644 index 0000000..0f60e4e --- /dev/null +++ b/.js/plugins/english/SleepyTranslations[madara].js @@ -0,0 +1,269 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __generator = (this && this.__generator) || function (thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (g && (g = 0, op[0] && (_ = 0)), _) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +}; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var fetch_1 = require("@libs/fetch"); +var cheerio_1 = require("cheerio"); +var defaultCover_1 = require("@libs/defaultCover"); +var novelStatus_1 = require("@libs/novelStatus"); +var parseMadaraDate_1 = require("@libs/parseMadaraDate"); +var dayjs_1 = __importDefault(require("dayjs")); +var MadaraDefaultPath = { + novels: 'novel', + novel: 'novel', + chapter: 'novel' +}; +var MadaraPlugin = /** @class */ (function () { + function MadaraPlugin(metadata) { + this.id = metadata.id; + this.name = metadata.sourceName + "[madara]"; + var iconFileName = metadata.sourceName.replace(/\s+/g, "").toLowerCase(); + this.icon = "multisrc/madara/icons/".concat(iconFileName, ".png"); + this.site = metadata.sourceSite; + this.version = "1.0.0"; + this.userAgent = ""; + this.cookieString = ""; + this.options = metadata.options; + this.filter = metadata.filters; + } + MadaraPlugin.prototype.popularNovels = function (pageNo, _a) { + var _b, _c, _d, _e, _f, _g; + var filters = _a.filters, showLatestNovels = _a.showLatestNovels; + return __awaiter(this, void 0, void 0, function () { + var novels, url, body, loadedCheerio; + return __generator(this, function (_h) { + switch (_h.label) { + case 0: + novels = []; + url = this.site; + if ((filters === null || filters === void 0 ? void 0 : filters.genres) && ((_c = (_b = this.options) === null || _b === void 0 ? void 0 : _b.path) === null || _c === void 0 ? void 0 : _c.genres)) { + url += ((_e = (_d = this.options) === null || _d === void 0 ? void 0 : _d.path) === null || _e === void 0 ? void 0 : _e.genres) + filters.genres + '/'; + } + else { + url += ((_g = (_f = this.options) === null || _f === void 0 ? void 0 : _f.path) === null || _g === void 0 ? void 0 : _g.novels) ? this.options.path.novels : MadaraDefaultPath.novels; + } + url += '/page/' + pageNo + '/' + + '?m_orderby=' + (showLatestNovels ? 'latest' : ((filters === null || filters === void 0 ? void 0 : filters.sort) || 'rating')); + return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })]; + case 1: + body = _h.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.manga-title-badges').remove(); + loadedCheerio('.page-item-detail').each(function () { + var novelName = loadedCheerio(this).find('.post-title').text().trim(); + var image = loadedCheerio(this).find('img'); + var novelCover = image.attr('data-src') || image.attr('src'); + var novelUrl = loadedCheerio(this).find('.post-title') + .find('a') + .attr('href') || ''; + var novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + novels.push(novel); + }); + return [2 /*return*/, novels]; + } + }); + }); + }; + MadaraPlugin.prototype.parseNovelAndChapters = function (novelUrl) { + var _a; + return __awaiter(this, void 0, void 0, function () { + var novel, body, loadedCheerio, html, novelId, formData, chapters; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + novel = { + url: novelUrl, + }; + return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl).then(function (res) { return res.text(); })]; + case 1: + body = _b.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.manga-title-badges, #manga-title span').remove(); + novel.name = + loadedCheerio('.post-title h1').text().trim() || + loadedCheerio('#manga-title h1').text(); + novel.cover = + loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || + loadedCheerio('.summary_image > a > img').attr('data-src') || + loadedCheerio('.summary_image > a > img').attr('src') || + defaultCover_1.defaultCover; + loadedCheerio('.post-content_item, .post-content').each(function () { + var detailName = loadedCheerio(this).find('h5').text().trim(); + var detail = loadedCheerio(this).find('.summary-content').text().trim(); + switch (detailName) { + case 'Genre(s)': + case 'التصنيفات': + novel.genres = detail.replace(/[\\t\\n]/g, ','); + break; + case 'Author(s)': + case 'المؤلف': + case 'المؤلف (ين)': + novel.author = detail; + break; + case 'Status': + case 'الحالة': + novel.status = + detail.includes('OnGoing') || detail.includes('مستمرة') + ? novelStatus_1.NovelStatus.Ongoing + : novelStatus_1.NovelStatus.Completed; + break; + } + }); + loadedCheerio('div.summary__content .code-block,script').remove(); + novel.summary = + loadedCheerio('div.summary__content').text().trim() || + loadedCheerio('#tab-manga-about').text().trim() || + loadedCheerio('.post-content_item h5:contains("Summary")').next().text().trim(); + if (!(((_a = this.options) === null || _a === void 0 ? void 0 : _a.useNewChapterEndpoint) !== true)) return [3 /*break*/, 3]; + novelId = loadedCheerio('.rating-post-id').attr('value') || + loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; + formData = new FormData(); + formData.append("action", "manga_get_chapters"); + formData.append("manga", novelId); + return [4 /*yield*/, (0, fetch_1.fetchApi)(this.site + 'wp-admin/admin-ajax.php', { + method: 'POST', + body: formData, + }) + .then(function (res) { return res.text(); })]; + case 2: + html = _b.sent(); + return [3 /*break*/, 5]; + case 3: return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl + 'ajax/chapters/', { method: 'POST' }) + .then(function (res) { return res.text(); })]; + case 4: + html = _b.sent(); + _b.label = 5; + case 5: + if (html !== '0') { + loadedCheerio = (0, cheerio_1.load)(html); + } + chapters = []; + loadedCheerio('.wp-manga-chapter').each(function () { + var chapterName = loadedCheerio(this).find('a').text().trim(); + var releaseDate = null; + releaseDate = loadedCheerio(this) + .find('span.chapter-release-date') + .text() + .trim(); + if (releaseDate) { + releaseDate = (0, parseMadaraDate_1.parseMadaraDate)(releaseDate); + } + else { + /** + * Insert current date + */ + releaseDate = (0, dayjs_1.default)().format('LL'); + } + var chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); + }); + novel.chapters = chapters.reverse(); + return [2 /*return*/, novel]; + } + }); + }); + }; + MadaraPlugin.prototype.parseChapter = function (chapterUrl) { + return __awaiter(this, void 0, void 0, function () { + var body, loadedCheerio, chapterText; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, (0, fetch_1.fetchApi)(chapterUrl).then(function (res) { return res.text(); })]; + case 1: + body = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + chapterText = loadedCheerio('.text-left').html() || + loadedCheerio('.text-right').html() || + loadedCheerio('.entry-content').html() || ""; + return [2 /*return*/, chapterText]; + } + }); + }); + }; + MadaraPlugin.prototype.searchNovels = function (searchTerm, pageNo) { + return __awaiter(this, void 0, void 0, function () { + var novels, url, body, loadedCheerio; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + novels = []; + url = this.site + "?s=" + searchTerm + "&post_type=wp-manga"; + return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })]; + case 1: + body = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.c-tabs-item__content').each(function () { + var novelName = loadedCheerio(this).find('.post-title').text().trim(); + var image = loadedCheerio(this).find('img'); + var novelCover = image.attr('data-src') || image.attr('src'); + var novelUrl = loadedCheerio(this) + .find('.post-title') + .find('a') + .attr('href') || ''; + var novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + novels.push(novel); + }); + return [2 /*return*/, novels]; + } + }); + }); + }; + MadaraPlugin.prototype.fetchImage = function (url) { + return __awaiter(this, void 0, void 0, function () { + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, (0, fetch_1.fetchFile)(url, {})]; + case 1: return [2 /*return*/, _a.sent()]; + } + }); + }); + }; + return MadaraPlugin; +}()); +var plugin = new MadaraPlugin({ "id": "sleeptTLS", "sourceSite": "https://sleepytranslations.com/", "sourceName": "SleepyTranslations", "filters": [{ "key": "sort", "label": "Order by", "values": [{ "label": "Rating", "value": "rating" }, { "label": "A-Z", "value": "alphabet" }, { "label": "Latest", "value": "latest" }, { "label": "Most Views", "value": "views" }, { "label": "New", "value": "new-manga" }, { "label": "Trending", "value": "trending" }], "inputType": "Picker" }], "options": { "path": { "novels": "series", "novel": "series", "chapter": "series" }, "useNewChapterEndpoint": true, "lang": "English" } }); +exports.default = plugin; diff --git a/.js/plugins/english/SonicMTL[madara].js b/.js/plugins/english/SonicMTL[madara].js new file mode 100644 index 0000000..b975609 --- /dev/null +++ b/.js/plugins/english/SonicMTL[madara].js @@ -0,0 +1,269 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __generator = (this && this.__generator) || function (thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (g && (g = 0, op[0] && (_ = 0)), _) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +}; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var fetch_1 = require("@libs/fetch"); +var cheerio_1 = require("cheerio"); +var defaultCover_1 = require("@libs/defaultCover"); +var novelStatus_1 = require("@libs/novelStatus"); +var parseMadaraDate_1 = require("@libs/parseMadaraDate"); +var dayjs_1 = __importDefault(require("dayjs")); +var MadaraDefaultPath = { + novels: 'novel', + novel: 'novel', + chapter: 'novel' +}; +var MadaraPlugin = /** @class */ (function () { + function MadaraPlugin(metadata) { + this.id = metadata.id; + this.name = metadata.sourceName + "[madara]"; + var iconFileName = metadata.sourceName.replace(/\s+/g, "").toLowerCase(); + this.icon = "multisrc/madara/icons/".concat(iconFileName, ".png"); + this.site = metadata.sourceSite; + this.version = "1.0.0"; + this.userAgent = ""; + this.cookieString = ""; + this.options = metadata.options; + this.filter = metadata.filters; + } + MadaraPlugin.prototype.popularNovels = function (pageNo, _a) { + var _b, _c, _d, _e, _f, _g; + var filters = _a.filters, showLatestNovels = _a.showLatestNovels; + return __awaiter(this, void 0, void 0, function () { + var novels, url, body, loadedCheerio; + return __generator(this, function (_h) { + switch (_h.label) { + case 0: + novels = []; + url = this.site; + if ((filters === null || filters === void 0 ? void 0 : filters.genres) && ((_c = (_b = this.options) === null || _b === void 0 ? void 0 : _b.path) === null || _c === void 0 ? void 0 : _c.genres)) { + url += ((_e = (_d = this.options) === null || _d === void 0 ? void 0 : _d.path) === null || _e === void 0 ? void 0 : _e.genres) + filters.genres + '/'; + } + else { + url += ((_g = (_f = this.options) === null || _f === void 0 ? void 0 : _f.path) === null || _g === void 0 ? void 0 : _g.novels) ? this.options.path.novels : MadaraDefaultPath.novels; + } + url += '/page/' + pageNo + '/' + + '?m_orderby=' + (showLatestNovels ? 'latest' : ((filters === null || filters === void 0 ? void 0 : filters.sort) || 'rating')); + return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })]; + case 1: + body = _h.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.manga-title-badges').remove(); + loadedCheerio('.page-item-detail').each(function () { + var novelName = loadedCheerio(this).find('.post-title').text().trim(); + var image = loadedCheerio(this).find('img'); + var novelCover = image.attr('data-src') || image.attr('src'); + var novelUrl = loadedCheerio(this).find('.post-title') + .find('a') + .attr('href') || ''; + var novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + novels.push(novel); + }); + return [2 /*return*/, novels]; + } + }); + }); + }; + MadaraPlugin.prototype.parseNovelAndChapters = function (novelUrl) { + var _a; + return __awaiter(this, void 0, void 0, function () { + var novel, body, loadedCheerio, html, novelId, formData, chapters; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + novel = { + url: novelUrl, + }; + return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl).then(function (res) { return res.text(); })]; + case 1: + body = _b.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.manga-title-badges, #manga-title span').remove(); + novel.name = + loadedCheerio('.post-title h1').text().trim() || + loadedCheerio('#manga-title h1').text(); + novel.cover = + loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || + loadedCheerio('.summary_image > a > img').attr('data-src') || + loadedCheerio('.summary_image > a > img').attr('src') || + defaultCover_1.defaultCover; + loadedCheerio('.post-content_item, .post-content').each(function () { + var detailName = loadedCheerio(this).find('h5').text().trim(); + var detail = loadedCheerio(this).find('.summary-content').text().trim(); + switch (detailName) { + case 'Genre(s)': + case 'التصنيفات': + novel.genres = detail.replace(/[\\t\\n]/g, ','); + break; + case 'Author(s)': + case 'المؤلف': + case 'المؤلف (ين)': + novel.author = detail; + break; + case 'Status': + case 'الحالة': + novel.status = + detail.includes('OnGoing') || detail.includes('مستمرة') + ? novelStatus_1.NovelStatus.Ongoing + : novelStatus_1.NovelStatus.Completed; + break; + } + }); + loadedCheerio('div.summary__content .code-block,script').remove(); + novel.summary = + loadedCheerio('div.summary__content').text().trim() || + loadedCheerio('#tab-manga-about').text().trim() || + loadedCheerio('.post-content_item h5:contains("Summary")').next().text().trim(); + if (!(((_a = this.options) === null || _a === void 0 ? void 0 : _a.useNewChapterEndpoint) !== true)) return [3 /*break*/, 3]; + novelId = loadedCheerio('.rating-post-id').attr('value') || + loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; + formData = new FormData(); + formData.append("action", "manga_get_chapters"); + formData.append("manga", novelId); + return [4 /*yield*/, (0, fetch_1.fetchApi)(this.site + 'wp-admin/admin-ajax.php', { + method: 'POST', + body: formData, + }) + .then(function (res) { return res.text(); })]; + case 2: + html = _b.sent(); + return [3 /*break*/, 5]; + case 3: return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl + 'ajax/chapters/', { method: 'POST' }) + .then(function (res) { return res.text(); })]; + case 4: + html = _b.sent(); + _b.label = 5; + case 5: + if (html !== '0') { + loadedCheerio = (0, cheerio_1.load)(html); + } + chapters = []; + loadedCheerio('.wp-manga-chapter').each(function () { + var chapterName = loadedCheerio(this).find('a').text().trim(); + var releaseDate = null; + releaseDate = loadedCheerio(this) + .find('span.chapter-release-date') + .text() + .trim(); + if (releaseDate) { + releaseDate = (0, parseMadaraDate_1.parseMadaraDate)(releaseDate); + } + else { + /** + * Insert current date + */ + releaseDate = (0, dayjs_1.default)().format('LL'); + } + var chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); + }); + novel.chapters = chapters.reverse(); + return [2 /*return*/, novel]; + } + }); + }); + }; + MadaraPlugin.prototype.parseChapter = function (chapterUrl) { + return __awaiter(this, void 0, void 0, function () { + var body, loadedCheerio, chapterText; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, (0, fetch_1.fetchApi)(chapterUrl).then(function (res) { return res.text(); })]; + case 1: + body = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + chapterText = loadedCheerio('.text-left').html() || + loadedCheerio('.text-right').html() || + loadedCheerio('.entry-content').html() || ""; + return [2 /*return*/, chapterText]; + } + }); + }); + }; + MadaraPlugin.prototype.searchNovels = function (searchTerm, pageNo) { + return __awaiter(this, void 0, void 0, function () { + var novels, url, body, loadedCheerio; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + novels = []; + url = this.site + "?s=" + searchTerm + "&post_type=wp-manga"; + return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })]; + case 1: + body = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.c-tabs-item__content').each(function () { + var novelName = loadedCheerio(this).find('.post-title').text().trim(); + var image = loadedCheerio(this).find('img'); + var novelCover = image.attr('data-src') || image.attr('src'); + var novelUrl = loadedCheerio(this) + .find('.post-title') + .find('a') + .attr('href') || ''; + var novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + novels.push(novel); + }); + return [2 /*return*/, novels]; + } + }); + }); + }; + MadaraPlugin.prototype.fetchImage = function (url) { + return __awaiter(this, void 0, void 0, function () { + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, (0, fetch_1.fetchFile)(url, {})]; + case 1: return [2 /*return*/, _a.sent()]; + } + }); + }); + }; + return MadaraPlugin; +}()); +var plugin = new MadaraPlugin({ "id": "sonicmtl", "sourceSite": "https://www.sonicmtl.com/", "sourceName": "SonicMTL", "filters": [{ "key": "sort", "label": "Order by", "values": [{ "label": "Rating", "value": "rating" }, { "label": "A-Z", "value": "alphabet" }, { "label": "Latest", "value": "latest" }, { "label": "Most Views", "value": "views" }, { "label": "New", "value": "new-manga" }, { "label": "Trending", "value": "trending" }], "inputType": "Picker" }, { "key": "genres", "label": "GENRES", "values": [{ "label": "Action", "value": "action" }, { "label": "Adult", "value": "adult" }, { "label": "Adventure", "value": "adventure" }, { "label": "Comedy", "value": "comedy" }, { "label": "Cooking", "value": "cooking" }, { "label": "Detective", "value": "detective" }, { "label": "Doujinshi", "value": "doujinshi" }, { "label": "Drama", "value": "drama" }, { "label": "Ecchi", "value": "ecchi" }, { "label": "Fan-Fiction", "value": "fan-fiction" }, { "label": "Fantasy", "value": "fantasy" }, { "label": "Gender Bender", "value": "gender-bender" }, { "label": "Harem", "value": "harem" }, { "label": "Historical", "value": "historical" }, { "label": "Horror", "value": "horror" }, { "label": "Josei", "value": "josei" }, { "label": "Live action", "value": "live-action" }, { "label": "Manga", "value": "manga" }, { "label": "Manhua", "value": "manhua" }, { "label": "Manhwa", "value": "manhwa" }, { "label": "Martial Arts", "value": "martial-arts" }, { "label": "Mature", "value": "mature" }, { "label": "Mecha", "value": "mecha" }, { "label": "Mystery", "value": "mystery" }, { "label": "One shot", "value": "one-shot" }, { "label": "Psychological", "value": "psychological" }, { "label": "Romance", "value": "romance" }, { "label": "School Life", "value": "school-life" }, { "label": "Sci-fi", "value": "sci-fi" }, { "label": "Seinen", "value": "seinen" }, { "label": "Shoujo", "value": "shoujo" }, { "label": "Shoujo Ai", "value": "shoujo-ai" }, { "label": "Shounen", "value": "shounen" }, { "label": "Shounen Ai", "value": "shounen-ai" }, { "label": "Slice of Life", "value": "slice-of-life" }, { "label": "Smut", "value": "smut" }, { "label": "Soft Yaoi", "value": "soft-yaoi" }, { "label": "Soft Yuri", "value": "soft-yuri" }, { "label": "Sports", "value": "sports" }, { "label": "Supernatural", "value": "supernatural" }, { "label": "Tragedy", "value": "tragedy" }, { "label": "Urban Life", "value": "urban-life" }, { "label": "Wuxia", "value": "wuxia" }, { "label": "Xianxia", "value": "xianxia" }, { "label": "Xuanhuan", "value": "xuanhuan" }, { "label": "Yaoi", "value": "yaoi" }, { "label": "Yuri", "value": "yuri" }], "inputType": "Picker" }], "options": { "useNewChapterEndpoint": true, "lang": "English" } }); +exports.default = plugin; diff --git a/.js/plugins/english/SugarBabies[madara].js b/.js/plugins/english/SugarBabies[madara].js new file mode 100644 index 0000000..fa1a338 --- /dev/null +++ b/.js/plugins/english/SugarBabies[madara].js @@ -0,0 +1,269 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __generator = (this && this.__generator) || function (thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (g && (g = 0, op[0] && (_ = 0)), _) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +}; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var fetch_1 = require("@libs/fetch"); +var cheerio_1 = require("cheerio"); +var defaultCover_1 = require("@libs/defaultCover"); +var novelStatus_1 = require("@libs/novelStatus"); +var parseMadaraDate_1 = require("@libs/parseMadaraDate"); +var dayjs_1 = __importDefault(require("dayjs")); +var MadaraDefaultPath = { + novels: 'novel', + novel: 'novel', + chapter: 'novel' +}; +var MadaraPlugin = /** @class */ (function () { + function MadaraPlugin(metadata) { + this.id = metadata.id; + this.name = metadata.sourceName + "[madara]"; + var iconFileName = metadata.sourceName.replace(/\s+/g, "").toLowerCase(); + this.icon = "multisrc/madara/icons/".concat(iconFileName, ".png"); + this.site = metadata.sourceSite; + this.version = "1.0.0"; + this.userAgent = ""; + this.cookieString = ""; + this.options = metadata.options; + this.filter = metadata.filters; + } + MadaraPlugin.prototype.popularNovels = function (pageNo, _a) { + var _b, _c, _d, _e, _f, _g; + var filters = _a.filters, showLatestNovels = _a.showLatestNovels; + return __awaiter(this, void 0, void 0, function () { + var novels, url, body, loadedCheerio; + return __generator(this, function (_h) { + switch (_h.label) { + case 0: + novels = []; + url = this.site; + if ((filters === null || filters === void 0 ? void 0 : filters.genres) && ((_c = (_b = this.options) === null || _b === void 0 ? void 0 : _b.path) === null || _c === void 0 ? void 0 : _c.genres)) { + url += ((_e = (_d = this.options) === null || _d === void 0 ? void 0 : _d.path) === null || _e === void 0 ? void 0 : _e.genres) + filters.genres + '/'; + } + else { + url += ((_g = (_f = this.options) === null || _f === void 0 ? void 0 : _f.path) === null || _g === void 0 ? void 0 : _g.novels) ? this.options.path.novels : MadaraDefaultPath.novels; + } + url += '/page/' + pageNo + '/' + + '?m_orderby=' + (showLatestNovels ? 'latest' : ((filters === null || filters === void 0 ? void 0 : filters.sort) || 'rating')); + return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })]; + case 1: + body = _h.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.manga-title-badges').remove(); + loadedCheerio('.page-item-detail').each(function () { + var novelName = loadedCheerio(this).find('.post-title').text().trim(); + var image = loadedCheerio(this).find('img'); + var novelCover = image.attr('data-src') || image.attr('src'); + var novelUrl = loadedCheerio(this).find('.post-title') + .find('a') + .attr('href') || ''; + var novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + novels.push(novel); + }); + return [2 /*return*/, novels]; + } + }); + }); + }; + MadaraPlugin.prototype.parseNovelAndChapters = function (novelUrl) { + var _a; + return __awaiter(this, void 0, void 0, function () { + var novel, body, loadedCheerio, html, novelId, formData, chapters; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + novel = { + url: novelUrl, + }; + return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl).then(function (res) { return res.text(); })]; + case 1: + body = _b.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.manga-title-badges, #manga-title span').remove(); + novel.name = + loadedCheerio('.post-title h1').text().trim() || + loadedCheerio('#manga-title h1').text(); + novel.cover = + loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || + loadedCheerio('.summary_image > a > img').attr('data-src') || + loadedCheerio('.summary_image > a > img').attr('src') || + defaultCover_1.defaultCover; + loadedCheerio('.post-content_item, .post-content').each(function () { + var detailName = loadedCheerio(this).find('h5').text().trim(); + var detail = loadedCheerio(this).find('.summary-content').text().trim(); + switch (detailName) { + case 'Genre(s)': + case 'التصنيفات': + novel.genres = detail.replace(/[\\t\\n]/g, ','); + break; + case 'Author(s)': + case 'المؤلف': + case 'المؤلف (ين)': + novel.author = detail; + break; + case 'Status': + case 'الحالة': + novel.status = + detail.includes('OnGoing') || detail.includes('مستمرة') + ? novelStatus_1.NovelStatus.Ongoing + : novelStatus_1.NovelStatus.Completed; + break; + } + }); + loadedCheerio('div.summary__content .code-block,script').remove(); + novel.summary = + loadedCheerio('div.summary__content').text().trim() || + loadedCheerio('#tab-manga-about').text().trim() || + loadedCheerio('.post-content_item h5:contains("Summary")').next().text().trim(); + if (!(((_a = this.options) === null || _a === void 0 ? void 0 : _a.useNewChapterEndpoint) !== true)) return [3 /*break*/, 3]; + novelId = loadedCheerio('.rating-post-id').attr('value') || + loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; + formData = new FormData(); + formData.append("action", "manga_get_chapters"); + formData.append("manga", novelId); + return [4 /*yield*/, (0, fetch_1.fetchApi)(this.site + 'wp-admin/admin-ajax.php', { + method: 'POST', + body: formData, + }) + .then(function (res) { return res.text(); })]; + case 2: + html = _b.sent(); + return [3 /*break*/, 5]; + case 3: return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl + 'ajax/chapters/', { method: 'POST' }) + .then(function (res) { return res.text(); })]; + case 4: + html = _b.sent(); + _b.label = 5; + case 5: + if (html !== '0') { + loadedCheerio = (0, cheerio_1.load)(html); + } + chapters = []; + loadedCheerio('.wp-manga-chapter').each(function () { + var chapterName = loadedCheerio(this).find('a').text().trim(); + var releaseDate = null; + releaseDate = loadedCheerio(this) + .find('span.chapter-release-date') + .text() + .trim(); + if (releaseDate) { + releaseDate = (0, parseMadaraDate_1.parseMadaraDate)(releaseDate); + } + else { + /** + * Insert current date + */ + releaseDate = (0, dayjs_1.default)().format('LL'); + } + var chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); + }); + novel.chapters = chapters.reverse(); + return [2 /*return*/, novel]; + } + }); + }); + }; + MadaraPlugin.prototype.parseChapter = function (chapterUrl) { + return __awaiter(this, void 0, void 0, function () { + var body, loadedCheerio, chapterText; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, (0, fetch_1.fetchApi)(chapterUrl).then(function (res) { return res.text(); })]; + case 1: + body = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + chapterText = loadedCheerio('.text-left').html() || + loadedCheerio('.text-right').html() || + loadedCheerio('.entry-content').html() || ""; + return [2 /*return*/, chapterText]; + } + }); + }); + }; + MadaraPlugin.prototype.searchNovels = function (searchTerm, pageNo) { + return __awaiter(this, void 0, void 0, function () { + var novels, url, body, loadedCheerio; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + novels = []; + url = this.site + "?s=" + searchTerm + "&post_type=wp-manga"; + return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })]; + case 1: + body = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.c-tabs-item__content').each(function () { + var novelName = loadedCheerio(this).find('.post-title').text().trim(); + var image = loadedCheerio(this).find('img'); + var novelCover = image.attr('data-src') || image.attr('src'); + var novelUrl = loadedCheerio(this) + .find('.post-title') + .find('a') + .attr('href') || ''; + var novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + novels.push(novel); + }); + return [2 /*return*/, novels]; + } + }); + }); + }; + MadaraPlugin.prototype.fetchImage = function (url) { + return __awaiter(this, void 0, void 0, function () { + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, (0, fetch_1.fetchFile)(url, {})]; + case 1: return [2 /*return*/, _a.sent()]; + } + }); + }); + }; + return MadaraPlugin; +}()); +var plugin = new MadaraPlugin({ "id": "sugarbbscan", "sourceSite": "https://sugarbbscan.com/", "sourceName": "Sugar Babies", "filters": [], "options": { "path": { "novels": "series", "novel": "series", "chapter": "series" }, "lang": "English" } }); +exports.default = plugin; diff --git a/.js/plugins/english/SweetEscapeTranslations[madara].js b/.js/plugins/english/SweetEscapeTranslations[madara].js new file mode 100644 index 0000000..917ffd3 --- /dev/null +++ b/.js/plugins/english/SweetEscapeTranslations[madara].js @@ -0,0 +1,269 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __generator = (this && this.__generator) || function (thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (g && (g = 0, op[0] && (_ = 0)), _) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +}; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var fetch_1 = require("@libs/fetch"); +var cheerio_1 = require("cheerio"); +var defaultCover_1 = require("@libs/defaultCover"); +var novelStatus_1 = require("@libs/novelStatus"); +var parseMadaraDate_1 = require("@libs/parseMadaraDate"); +var dayjs_1 = __importDefault(require("dayjs")); +var MadaraDefaultPath = { + novels: 'novel', + novel: 'novel', + chapter: 'novel' +}; +var MadaraPlugin = /** @class */ (function () { + function MadaraPlugin(metadata) { + this.id = metadata.id; + this.name = metadata.sourceName + "[madara]"; + var iconFileName = metadata.sourceName.replace(/\s+/g, "").toLowerCase(); + this.icon = "multisrc/madara/icons/".concat(iconFileName, ".png"); + this.site = metadata.sourceSite; + this.version = "1.0.0"; + this.userAgent = ""; + this.cookieString = ""; + this.options = metadata.options; + this.filter = metadata.filters; + } + MadaraPlugin.prototype.popularNovels = function (pageNo, _a) { + var _b, _c, _d, _e, _f, _g; + var filters = _a.filters, showLatestNovels = _a.showLatestNovels; + return __awaiter(this, void 0, void 0, function () { + var novels, url, body, loadedCheerio; + return __generator(this, function (_h) { + switch (_h.label) { + case 0: + novels = []; + url = this.site; + if ((filters === null || filters === void 0 ? void 0 : filters.genres) && ((_c = (_b = this.options) === null || _b === void 0 ? void 0 : _b.path) === null || _c === void 0 ? void 0 : _c.genres)) { + url += ((_e = (_d = this.options) === null || _d === void 0 ? void 0 : _d.path) === null || _e === void 0 ? void 0 : _e.genres) + filters.genres + '/'; + } + else { + url += ((_g = (_f = this.options) === null || _f === void 0 ? void 0 : _f.path) === null || _g === void 0 ? void 0 : _g.novels) ? this.options.path.novels : MadaraDefaultPath.novels; + } + url += '/page/' + pageNo + '/' + + '?m_orderby=' + (showLatestNovels ? 'latest' : ((filters === null || filters === void 0 ? void 0 : filters.sort) || 'rating')); + return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })]; + case 1: + body = _h.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.manga-title-badges').remove(); + loadedCheerio('.page-item-detail').each(function () { + var novelName = loadedCheerio(this).find('.post-title').text().trim(); + var image = loadedCheerio(this).find('img'); + var novelCover = image.attr('data-src') || image.attr('src'); + var novelUrl = loadedCheerio(this).find('.post-title') + .find('a') + .attr('href') || ''; + var novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + novels.push(novel); + }); + return [2 /*return*/, novels]; + } + }); + }); + }; + MadaraPlugin.prototype.parseNovelAndChapters = function (novelUrl) { + var _a; + return __awaiter(this, void 0, void 0, function () { + var novel, body, loadedCheerio, html, novelId, formData, chapters; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + novel = { + url: novelUrl, + }; + return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl).then(function (res) { return res.text(); })]; + case 1: + body = _b.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.manga-title-badges, #manga-title span').remove(); + novel.name = + loadedCheerio('.post-title h1').text().trim() || + loadedCheerio('#manga-title h1').text(); + novel.cover = + loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || + loadedCheerio('.summary_image > a > img').attr('data-src') || + loadedCheerio('.summary_image > a > img').attr('src') || + defaultCover_1.defaultCover; + loadedCheerio('.post-content_item, .post-content').each(function () { + var detailName = loadedCheerio(this).find('h5').text().trim(); + var detail = loadedCheerio(this).find('.summary-content').text().trim(); + switch (detailName) { + case 'Genre(s)': + case 'التصنيفات': + novel.genres = detail.replace(/[\\t\\n]/g, ','); + break; + case 'Author(s)': + case 'المؤلف': + case 'المؤلف (ين)': + novel.author = detail; + break; + case 'Status': + case 'الحالة': + novel.status = + detail.includes('OnGoing') || detail.includes('مستمرة') + ? novelStatus_1.NovelStatus.Ongoing + : novelStatus_1.NovelStatus.Completed; + break; + } + }); + loadedCheerio('div.summary__content .code-block,script').remove(); + novel.summary = + loadedCheerio('div.summary__content').text().trim() || + loadedCheerio('#tab-manga-about').text().trim() || + loadedCheerio('.post-content_item h5:contains("Summary")').next().text().trim(); + if (!(((_a = this.options) === null || _a === void 0 ? void 0 : _a.useNewChapterEndpoint) !== true)) return [3 /*break*/, 3]; + novelId = loadedCheerio('.rating-post-id').attr('value') || + loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; + formData = new FormData(); + formData.append("action", "manga_get_chapters"); + formData.append("manga", novelId); + return [4 /*yield*/, (0, fetch_1.fetchApi)(this.site + 'wp-admin/admin-ajax.php', { + method: 'POST', + body: formData, + }) + .then(function (res) { return res.text(); })]; + case 2: + html = _b.sent(); + return [3 /*break*/, 5]; + case 3: return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl + 'ajax/chapters/', { method: 'POST' }) + .then(function (res) { return res.text(); })]; + case 4: + html = _b.sent(); + _b.label = 5; + case 5: + if (html !== '0') { + loadedCheerio = (0, cheerio_1.load)(html); + } + chapters = []; + loadedCheerio('.wp-manga-chapter').each(function () { + var chapterName = loadedCheerio(this).find('a').text().trim(); + var releaseDate = null; + releaseDate = loadedCheerio(this) + .find('span.chapter-release-date') + .text() + .trim(); + if (releaseDate) { + releaseDate = (0, parseMadaraDate_1.parseMadaraDate)(releaseDate); + } + else { + /** + * Insert current date + */ + releaseDate = (0, dayjs_1.default)().format('LL'); + } + var chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); + }); + novel.chapters = chapters.reverse(); + return [2 /*return*/, novel]; + } + }); + }); + }; + MadaraPlugin.prototype.parseChapter = function (chapterUrl) { + return __awaiter(this, void 0, void 0, function () { + var body, loadedCheerio, chapterText; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, (0, fetch_1.fetchApi)(chapterUrl).then(function (res) { return res.text(); })]; + case 1: + body = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + chapterText = loadedCheerio('.text-left').html() || + loadedCheerio('.text-right').html() || + loadedCheerio('.entry-content').html() || ""; + return [2 /*return*/, chapterText]; + } + }); + }); + }; + MadaraPlugin.prototype.searchNovels = function (searchTerm, pageNo) { + return __awaiter(this, void 0, void 0, function () { + var novels, url, body, loadedCheerio; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + novels = []; + url = this.site + "?s=" + searchTerm + "&post_type=wp-manga"; + return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })]; + case 1: + body = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.c-tabs-item__content').each(function () { + var novelName = loadedCheerio(this).find('.post-title').text().trim(); + var image = loadedCheerio(this).find('img'); + var novelCover = image.attr('data-src') || image.attr('src'); + var novelUrl = loadedCheerio(this) + .find('.post-title') + .find('a') + .attr('href') || ''; + var novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + novels.push(novel); + }); + return [2 /*return*/, novels]; + } + }); + }); + }; + MadaraPlugin.prototype.fetchImage = function (url) { + return __awaiter(this, void 0, void 0, function () { + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, (0, fetch_1.fetchFile)(url, {})]; + case 1: return [2 /*return*/, _a.sent()]; + } + }); + }); + }; + return MadaraPlugin; +}()); +var plugin = new MadaraPlugin({ "id": "sweetEscapeTL", "sourceSite": "https://sweetescapetranslations.com/", "sourceName": "Sweet Escape Translations", "filters": [{ "key": "sort", "label": "Order by", "values": [{ "label": "Rating", "value": "rating" }, { "label": "A-Z", "value": "alphabet" }, { "label": "Latest", "value": "latest" }, { "label": "Most Views", "value": "views" }, { "label": "New", "value": "new-manga" }, { "label": "Trending", "value": "trending" }], "inputType": "Picker" }, { "key": "genres", "label": "GENRES", "values": [{ "label": "Action", "value": "action" }, { "label": "Adult", "value": "adult" }, { "label": "Comedy", "value": "comedy" }, { "label": "Drama", "value": "drama" }, { "label": "Fantasy", "value": "fantasy" }, { "label": "Gender Bender", "value": "gender-bender" }, { "label": "Mature", "value": "mature" }, { "label": "Modern", "value": "modern" }, { "label": "Mystery", "value": "mystery" }, { "label": "R-15", "value": "r-15" }, { "label": "Romance", "value": "romance" }, { "label": "Slice of Life", "value": "slice-of-life" }], "inputType": "Picker" }], "options": { "path": { "novels": "manga", "novel": "manga", "chapter": "manga", "genres": "manga-genre" }, "useNewChapterEndpoint": false, "lang": "English" } }); +exports.default = plugin; diff --git a/.js/plugins/english/WebNovelLover[madara].js b/.js/plugins/english/WebNovelLover[madara].js new file mode 100644 index 0000000..44fffb0 --- /dev/null +++ b/.js/plugins/english/WebNovelLover[madara].js @@ -0,0 +1,269 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __generator = (this && this.__generator) || function (thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (g && (g = 0, op[0] && (_ = 0)), _) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +}; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var fetch_1 = require("@libs/fetch"); +var cheerio_1 = require("cheerio"); +var defaultCover_1 = require("@libs/defaultCover"); +var novelStatus_1 = require("@libs/novelStatus"); +var parseMadaraDate_1 = require("@libs/parseMadaraDate"); +var dayjs_1 = __importDefault(require("dayjs")); +var MadaraDefaultPath = { + novels: 'novel', + novel: 'novel', + chapter: 'novel' +}; +var MadaraPlugin = /** @class */ (function () { + function MadaraPlugin(metadata) { + this.id = metadata.id; + this.name = metadata.sourceName + "[madara]"; + var iconFileName = metadata.sourceName.replace(/\s+/g, "").toLowerCase(); + this.icon = "multisrc/madara/icons/".concat(iconFileName, ".png"); + this.site = metadata.sourceSite; + this.version = "1.0.0"; + this.userAgent = ""; + this.cookieString = ""; + this.options = metadata.options; + this.filter = metadata.filters; + } + MadaraPlugin.prototype.popularNovels = function (pageNo, _a) { + var _b, _c, _d, _e, _f, _g; + var filters = _a.filters, showLatestNovels = _a.showLatestNovels; + return __awaiter(this, void 0, void 0, function () { + var novels, url, body, loadedCheerio; + return __generator(this, function (_h) { + switch (_h.label) { + case 0: + novels = []; + url = this.site; + if ((filters === null || filters === void 0 ? void 0 : filters.genres) && ((_c = (_b = this.options) === null || _b === void 0 ? void 0 : _b.path) === null || _c === void 0 ? void 0 : _c.genres)) { + url += ((_e = (_d = this.options) === null || _d === void 0 ? void 0 : _d.path) === null || _e === void 0 ? void 0 : _e.genres) + filters.genres + '/'; + } + else { + url += ((_g = (_f = this.options) === null || _f === void 0 ? void 0 : _f.path) === null || _g === void 0 ? void 0 : _g.novels) ? this.options.path.novels : MadaraDefaultPath.novels; + } + url += '/page/' + pageNo + '/' + + '?m_orderby=' + (showLatestNovels ? 'latest' : ((filters === null || filters === void 0 ? void 0 : filters.sort) || 'rating')); + return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })]; + case 1: + body = _h.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.manga-title-badges').remove(); + loadedCheerio('.page-item-detail').each(function () { + var novelName = loadedCheerio(this).find('.post-title').text().trim(); + var image = loadedCheerio(this).find('img'); + var novelCover = image.attr('data-src') || image.attr('src'); + var novelUrl = loadedCheerio(this).find('.post-title') + .find('a') + .attr('href') || ''; + var novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + novels.push(novel); + }); + return [2 /*return*/, novels]; + } + }); + }); + }; + MadaraPlugin.prototype.parseNovelAndChapters = function (novelUrl) { + var _a; + return __awaiter(this, void 0, void 0, function () { + var novel, body, loadedCheerio, html, novelId, formData, chapters; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + novel = { + url: novelUrl, + }; + return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl).then(function (res) { return res.text(); })]; + case 1: + body = _b.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.manga-title-badges, #manga-title span').remove(); + novel.name = + loadedCheerio('.post-title h1').text().trim() || + loadedCheerio('#manga-title h1').text(); + novel.cover = + loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || + loadedCheerio('.summary_image > a > img').attr('data-src') || + loadedCheerio('.summary_image > a > img').attr('src') || + defaultCover_1.defaultCover; + loadedCheerio('.post-content_item, .post-content').each(function () { + var detailName = loadedCheerio(this).find('h5').text().trim(); + var detail = loadedCheerio(this).find('.summary-content').text().trim(); + switch (detailName) { + case 'Genre(s)': + case 'التصنيفات': + novel.genres = detail.replace(/[\\t\\n]/g, ','); + break; + case 'Author(s)': + case 'المؤلف': + case 'المؤلف (ين)': + novel.author = detail; + break; + case 'Status': + case 'الحالة': + novel.status = + detail.includes('OnGoing') || detail.includes('مستمرة') + ? novelStatus_1.NovelStatus.Ongoing + : novelStatus_1.NovelStatus.Completed; + break; + } + }); + loadedCheerio('div.summary__content .code-block,script').remove(); + novel.summary = + loadedCheerio('div.summary__content').text().trim() || + loadedCheerio('#tab-manga-about').text().trim() || + loadedCheerio('.post-content_item h5:contains("Summary")').next().text().trim(); + if (!(((_a = this.options) === null || _a === void 0 ? void 0 : _a.useNewChapterEndpoint) !== true)) return [3 /*break*/, 3]; + novelId = loadedCheerio('.rating-post-id').attr('value') || + loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; + formData = new FormData(); + formData.append("action", "manga_get_chapters"); + formData.append("manga", novelId); + return [4 /*yield*/, (0, fetch_1.fetchApi)(this.site + 'wp-admin/admin-ajax.php', { + method: 'POST', + body: formData, + }) + .then(function (res) { return res.text(); })]; + case 2: + html = _b.sent(); + return [3 /*break*/, 5]; + case 3: return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl + 'ajax/chapters/', { method: 'POST' }) + .then(function (res) { return res.text(); })]; + case 4: + html = _b.sent(); + _b.label = 5; + case 5: + if (html !== '0') { + loadedCheerio = (0, cheerio_1.load)(html); + } + chapters = []; + loadedCheerio('.wp-manga-chapter').each(function () { + var chapterName = loadedCheerio(this).find('a').text().trim(); + var releaseDate = null; + releaseDate = loadedCheerio(this) + .find('span.chapter-release-date') + .text() + .trim(); + if (releaseDate) { + releaseDate = (0, parseMadaraDate_1.parseMadaraDate)(releaseDate); + } + else { + /** + * Insert current date + */ + releaseDate = (0, dayjs_1.default)().format('LL'); + } + var chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); + }); + novel.chapters = chapters.reverse(); + return [2 /*return*/, novel]; + } + }); + }); + }; + MadaraPlugin.prototype.parseChapter = function (chapterUrl) { + return __awaiter(this, void 0, void 0, function () { + var body, loadedCheerio, chapterText; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, (0, fetch_1.fetchApi)(chapterUrl).then(function (res) { return res.text(); })]; + case 1: + body = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + chapterText = loadedCheerio('.text-left').html() || + loadedCheerio('.text-right').html() || + loadedCheerio('.entry-content').html() || ""; + return [2 /*return*/, chapterText]; + } + }); + }); + }; + MadaraPlugin.prototype.searchNovels = function (searchTerm, pageNo) { + return __awaiter(this, void 0, void 0, function () { + var novels, url, body, loadedCheerio; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + novels = []; + url = this.site + "?s=" + searchTerm + "&post_type=wp-manga"; + return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })]; + case 1: + body = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.c-tabs-item__content').each(function () { + var novelName = loadedCheerio(this).find('.post-title').text().trim(); + var image = loadedCheerio(this).find('img'); + var novelCover = image.attr('data-src') || image.attr('src'); + var novelUrl = loadedCheerio(this) + .find('.post-title') + .find('a') + .attr('href') || ''; + var novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + novels.push(novel); + }); + return [2 /*return*/, novels]; + } + }); + }); + }; + MadaraPlugin.prototype.fetchImage = function (url) { + return __awaiter(this, void 0, void 0, function () { + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, (0, fetch_1.fetchFile)(url, {})]; + case 1: return [2 /*return*/, _a.sent()]; + } + }); + }); + }; + return MadaraPlugin; +}()); +var plugin = new MadaraPlugin({ "id": "webnovelover", "sourceSite": "https://www.webnovelover.com/", "sourceName": "WebNovelLover", "filters": [{ "key": "sort", "label": "Order by", "values": [{ "label": "Rating", "value": "rating" }, { "label": "A-Z", "value": "alphabet" }, { "label": "Latest", "value": "latest" }, { "label": "Most Views", "value": "views" }, { "label": "New", "value": "new-manga" }, { "label": "Trending", "value": "trending" }], "inputType": "Picker" }, { "key": "genres", "label": "GENRES", "values": [{ "label": "Action", "value": "action" }, { "label": "Adapted into drama", "value": "adapted-into-drama" }, { "label": "Adventure", "value": "adventure" }, { "label": "Comedy", "value": "comedy" }, { "label": "Completed", "value": "completed" }, { "label": "Drama", "value": "drama" }, { "label": "English Novel", "value": "english-novel" }, { "label": "Fantasy", "value": "fantasy" }, { "label": "Gender Bender", "value": "gender-bender" }, { "label": "Harem", "value": "harem" }, { "label": "Historical", "value": "historical" }, { "label": "Horror", "value": "horror" }, { "label": "Indo Novel", "value": "indo-novel" }, { "label": "Josei", "value": "josei" }, { "label": "Martial Arts", "value": "martial-arts" }, { "label": "Mature", "value": "mature" }, { "label": "Mystery", "value": "mystery" }, { "label": "Rebirth", "value": "rebirth" }, { "label": "Reincarnation", "value": "reincarnation" }, { "label": "Romance", "value": "romance" }, { "label": "Sci-fi", "value": "sci-fi" }, { "label": "Shoujo", "value": "shoujo" }, { "label": "Shounen", "value": "shounen" }, { "label": "Slice of Life", "value": "slice-of-life" }, { "label": "Spiritual", "value": "spiritual" }, { "label": "Supernatural", "value": "supernatural" }, { "label": "Tragedy", "value": "tragedy" }, { "label": "Transmigration", "value": "transmigration" }, { "label": "University", "value": "university" }, { "label": "Wuxia", "value": "wuxia" }, { "label": "Xianxia", "value": "xianxia" }, { "label": "Xuanhuan", "value": "xuanhuan" }, { "label": "Youth", "value": "youth" }], "inputType": "Picker" }], "options": { "lang": "English" } }); +exports.default = plugin; diff --git a/.js/plugins/english/WuxiaWorldSite[madara].js b/.js/plugins/english/WuxiaWorldSite[madara].js new file mode 100644 index 0000000..db9b9bd --- /dev/null +++ b/.js/plugins/english/WuxiaWorldSite[madara].js @@ -0,0 +1,269 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __generator = (this && this.__generator) || function (thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (g && (g = 0, op[0] && (_ = 0)), _) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +}; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var fetch_1 = require("@libs/fetch"); +var cheerio_1 = require("cheerio"); +var defaultCover_1 = require("@libs/defaultCover"); +var novelStatus_1 = require("@libs/novelStatus"); +var parseMadaraDate_1 = require("@libs/parseMadaraDate"); +var dayjs_1 = __importDefault(require("dayjs")); +var MadaraDefaultPath = { + novels: 'novel', + novel: 'novel', + chapter: 'novel' +}; +var MadaraPlugin = /** @class */ (function () { + function MadaraPlugin(metadata) { + this.id = metadata.id; + this.name = metadata.sourceName + "[madara]"; + var iconFileName = metadata.sourceName.replace(/\s+/g, "").toLowerCase(); + this.icon = "multisrc/madara/icons/".concat(iconFileName, ".png"); + this.site = metadata.sourceSite; + this.version = "1.0.0"; + this.userAgent = ""; + this.cookieString = ""; + this.options = metadata.options; + this.filter = metadata.filters; + } + MadaraPlugin.prototype.popularNovels = function (pageNo, _a) { + var _b, _c, _d, _e, _f, _g; + var filters = _a.filters, showLatestNovels = _a.showLatestNovels; + return __awaiter(this, void 0, void 0, function () { + var novels, url, body, loadedCheerio; + return __generator(this, function (_h) { + switch (_h.label) { + case 0: + novels = []; + url = this.site; + if ((filters === null || filters === void 0 ? void 0 : filters.genres) && ((_c = (_b = this.options) === null || _b === void 0 ? void 0 : _b.path) === null || _c === void 0 ? void 0 : _c.genres)) { + url += ((_e = (_d = this.options) === null || _d === void 0 ? void 0 : _d.path) === null || _e === void 0 ? void 0 : _e.genres) + filters.genres + '/'; + } + else { + url += ((_g = (_f = this.options) === null || _f === void 0 ? void 0 : _f.path) === null || _g === void 0 ? void 0 : _g.novels) ? this.options.path.novels : MadaraDefaultPath.novels; + } + url += '/page/' + pageNo + '/' + + '?m_orderby=' + (showLatestNovels ? 'latest' : ((filters === null || filters === void 0 ? void 0 : filters.sort) || 'rating')); + return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })]; + case 1: + body = _h.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.manga-title-badges').remove(); + loadedCheerio('.page-item-detail').each(function () { + var novelName = loadedCheerio(this).find('.post-title').text().trim(); + var image = loadedCheerio(this).find('img'); + var novelCover = image.attr('data-src') || image.attr('src'); + var novelUrl = loadedCheerio(this).find('.post-title') + .find('a') + .attr('href') || ''; + var novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + novels.push(novel); + }); + return [2 /*return*/, novels]; + } + }); + }); + }; + MadaraPlugin.prototype.parseNovelAndChapters = function (novelUrl) { + var _a; + return __awaiter(this, void 0, void 0, function () { + var novel, body, loadedCheerio, html, novelId, formData, chapters; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + novel = { + url: novelUrl, + }; + return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl).then(function (res) { return res.text(); })]; + case 1: + body = _b.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.manga-title-badges, #manga-title span').remove(); + novel.name = + loadedCheerio('.post-title h1').text().trim() || + loadedCheerio('#manga-title h1').text(); + novel.cover = + loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || + loadedCheerio('.summary_image > a > img').attr('data-src') || + loadedCheerio('.summary_image > a > img').attr('src') || + defaultCover_1.defaultCover; + loadedCheerio('.post-content_item, .post-content').each(function () { + var detailName = loadedCheerio(this).find('h5').text().trim(); + var detail = loadedCheerio(this).find('.summary-content').text().trim(); + switch (detailName) { + case 'Genre(s)': + case 'التصنيفات': + novel.genres = detail.replace(/[\\t\\n]/g, ','); + break; + case 'Author(s)': + case 'المؤلف': + case 'المؤلف (ين)': + novel.author = detail; + break; + case 'Status': + case 'الحالة': + novel.status = + detail.includes('OnGoing') || detail.includes('مستمرة') + ? novelStatus_1.NovelStatus.Ongoing + : novelStatus_1.NovelStatus.Completed; + break; + } + }); + loadedCheerio('div.summary__content .code-block,script').remove(); + novel.summary = + loadedCheerio('div.summary__content').text().trim() || + loadedCheerio('#tab-manga-about').text().trim() || + loadedCheerio('.post-content_item h5:contains("Summary")').next().text().trim(); + if (!(((_a = this.options) === null || _a === void 0 ? void 0 : _a.useNewChapterEndpoint) !== true)) return [3 /*break*/, 3]; + novelId = loadedCheerio('.rating-post-id').attr('value') || + loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; + formData = new FormData(); + formData.append("action", "manga_get_chapters"); + formData.append("manga", novelId); + return [4 /*yield*/, (0, fetch_1.fetchApi)(this.site + 'wp-admin/admin-ajax.php', { + method: 'POST', + body: formData, + }) + .then(function (res) { return res.text(); })]; + case 2: + html = _b.sent(); + return [3 /*break*/, 5]; + case 3: return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl + 'ajax/chapters/', { method: 'POST' }) + .then(function (res) { return res.text(); })]; + case 4: + html = _b.sent(); + _b.label = 5; + case 5: + if (html !== '0') { + loadedCheerio = (0, cheerio_1.load)(html); + } + chapters = []; + loadedCheerio('.wp-manga-chapter').each(function () { + var chapterName = loadedCheerio(this).find('a').text().trim(); + var releaseDate = null; + releaseDate = loadedCheerio(this) + .find('span.chapter-release-date') + .text() + .trim(); + if (releaseDate) { + releaseDate = (0, parseMadaraDate_1.parseMadaraDate)(releaseDate); + } + else { + /** + * Insert current date + */ + releaseDate = (0, dayjs_1.default)().format('LL'); + } + var chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); + }); + novel.chapters = chapters.reverse(); + return [2 /*return*/, novel]; + } + }); + }); + }; + MadaraPlugin.prototype.parseChapter = function (chapterUrl) { + return __awaiter(this, void 0, void 0, function () { + var body, loadedCheerio, chapterText; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, (0, fetch_1.fetchApi)(chapterUrl).then(function (res) { return res.text(); })]; + case 1: + body = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + chapterText = loadedCheerio('.text-left').html() || + loadedCheerio('.text-right').html() || + loadedCheerio('.entry-content').html() || ""; + return [2 /*return*/, chapterText]; + } + }); + }); + }; + MadaraPlugin.prototype.searchNovels = function (searchTerm, pageNo) { + return __awaiter(this, void 0, void 0, function () { + var novels, url, body, loadedCheerio; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + novels = []; + url = this.site + "?s=" + searchTerm + "&post_type=wp-manga"; + return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })]; + case 1: + body = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.c-tabs-item__content').each(function () { + var novelName = loadedCheerio(this).find('.post-title').text().trim(); + var image = loadedCheerio(this).find('img'); + var novelCover = image.attr('data-src') || image.attr('src'); + var novelUrl = loadedCheerio(this) + .find('.post-title') + .find('a') + .attr('href') || ''; + var novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + novels.push(novel); + }); + return [2 /*return*/, novels]; + } + }); + }); + }; + MadaraPlugin.prototype.fetchImage = function (url) { + return __awaiter(this, void 0, void 0, function () { + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, (0, fetch_1.fetchFile)(url, {})]; + case 1: return [2 /*return*/, _a.sent()]; + } + }); + }); + }; + return MadaraPlugin; +}()); +var plugin = new MadaraPlugin({ "id": "wuxiaworld.site", "sourceSite": "https://wuxiaworld.site/", "sourceName": "WuxiaWorld.Site", "filters": [{ "key": "sort", "label": "Order by", "values": [{ "label": "Rating", "value": "rating" }, { "label": "A-Z", "value": "alphabet" }, { "label": "Latest", "value": "latest" }, { "label": "Most Views", "value": "views" }, { "label": "New", "value": "new-manga" }, { "label": "Trending", "value": "trending" }], "inputType": "Picker" }], "options": { "useNewChapterEndpoint": true, "lang": "English" } }); +exports.default = plugin; diff --git a/.js/plugins/english/ZetroTranslation[madara].js b/.js/plugins/english/ZetroTranslation[madara].js new file mode 100644 index 0000000..aa2b9cf --- /dev/null +++ b/.js/plugins/english/ZetroTranslation[madara].js @@ -0,0 +1,269 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __generator = (this && this.__generator) || function (thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (g && (g = 0, op[0] && (_ = 0)), _) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +}; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var fetch_1 = require("@libs/fetch"); +var cheerio_1 = require("cheerio"); +var defaultCover_1 = require("@libs/defaultCover"); +var novelStatus_1 = require("@libs/novelStatus"); +var parseMadaraDate_1 = require("@libs/parseMadaraDate"); +var dayjs_1 = __importDefault(require("dayjs")); +var MadaraDefaultPath = { + novels: 'novel', + novel: 'novel', + chapter: 'novel' +}; +var MadaraPlugin = /** @class */ (function () { + function MadaraPlugin(metadata) { + this.id = metadata.id; + this.name = metadata.sourceName + "[madara]"; + var iconFileName = metadata.sourceName.replace(/\s+/g, "").toLowerCase(); + this.icon = "multisrc/madara/icons/".concat(iconFileName, ".png"); + this.site = metadata.sourceSite; + this.version = "1.0.0"; + this.userAgent = ""; + this.cookieString = ""; + this.options = metadata.options; + this.filter = metadata.filters; + } + MadaraPlugin.prototype.popularNovels = function (pageNo, _a) { + var _b, _c, _d, _e, _f, _g; + var filters = _a.filters, showLatestNovels = _a.showLatestNovels; + return __awaiter(this, void 0, void 0, function () { + var novels, url, body, loadedCheerio; + return __generator(this, function (_h) { + switch (_h.label) { + case 0: + novels = []; + url = this.site; + if ((filters === null || filters === void 0 ? void 0 : filters.genres) && ((_c = (_b = this.options) === null || _b === void 0 ? void 0 : _b.path) === null || _c === void 0 ? void 0 : _c.genres)) { + url += ((_e = (_d = this.options) === null || _d === void 0 ? void 0 : _d.path) === null || _e === void 0 ? void 0 : _e.genres) + filters.genres + '/'; + } + else { + url += ((_g = (_f = this.options) === null || _f === void 0 ? void 0 : _f.path) === null || _g === void 0 ? void 0 : _g.novels) ? this.options.path.novels : MadaraDefaultPath.novels; + } + url += '/page/' + pageNo + '/' + + '?m_orderby=' + (showLatestNovels ? 'latest' : ((filters === null || filters === void 0 ? void 0 : filters.sort) || 'rating')); + return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })]; + case 1: + body = _h.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.manga-title-badges').remove(); + loadedCheerio('.page-item-detail').each(function () { + var novelName = loadedCheerio(this).find('.post-title').text().trim(); + var image = loadedCheerio(this).find('img'); + var novelCover = image.attr('data-src') || image.attr('src'); + var novelUrl = loadedCheerio(this).find('.post-title') + .find('a') + .attr('href') || ''; + var novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + novels.push(novel); + }); + return [2 /*return*/, novels]; + } + }); + }); + }; + MadaraPlugin.prototype.parseNovelAndChapters = function (novelUrl) { + var _a; + return __awaiter(this, void 0, void 0, function () { + var novel, body, loadedCheerio, html, novelId, formData, chapters; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + novel = { + url: novelUrl, + }; + return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl).then(function (res) { return res.text(); })]; + case 1: + body = _b.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.manga-title-badges, #manga-title span').remove(); + novel.name = + loadedCheerio('.post-title h1').text().trim() || + loadedCheerio('#manga-title h1').text(); + novel.cover = + loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || + loadedCheerio('.summary_image > a > img').attr('data-src') || + loadedCheerio('.summary_image > a > img').attr('src') || + defaultCover_1.defaultCover; + loadedCheerio('.post-content_item, .post-content').each(function () { + var detailName = loadedCheerio(this).find('h5').text().trim(); + var detail = loadedCheerio(this).find('.summary-content').text().trim(); + switch (detailName) { + case 'Genre(s)': + case 'التصنيفات': + novel.genres = detail.replace(/[\\t\\n]/g, ','); + break; + case 'Author(s)': + case 'المؤلف': + case 'المؤلف (ين)': + novel.author = detail; + break; + case 'Status': + case 'الحالة': + novel.status = + detail.includes('OnGoing') || detail.includes('مستمرة') + ? novelStatus_1.NovelStatus.Ongoing + : novelStatus_1.NovelStatus.Completed; + break; + } + }); + loadedCheerio('div.summary__content .code-block,script').remove(); + novel.summary = + loadedCheerio('div.summary__content').text().trim() || + loadedCheerio('#tab-manga-about').text().trim() || + loadedCheerio('.post-content_item h5:contains("Summary")').next().text().trim(); + if (!(((_a = this.options) === null || _a === void 0 ? void 0 : _a.useNewChapterEndpoint) !== true)) return [3 /*break*/, 3]; + novelId = loadedCheerio('.rating-post-id').attr('value') || + loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; + formData = new FormData(); + formData.append("action", "manga_get_chapters"); + formData.append("manga", novelId); + return [4 /*yield*/, (0, fetch_1.fetchApi)(this.site + 'wp-admin/admin-ajax.php', { + method: 'POST', + body: formData, + }) + .then(function (res) { return res.text(); })]; + case 2: + html = _b.sent(); + return [3 /*break*/, 5]; + case 3: return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl + 'ajax/chapters/', { method: 'POST' }) + .then(function (res) { return res.text(); })]; + case 4: + html = _b.sent(); + _b.label = 5; + case 5: + if (html !== '0') { + loadedCheerio = (0, cheerio_1.load)(html); + } + chapters = []; + loadedCheerio('.wp-manga-chapter').each(function () { + var chapterName = loadedCheerio(this).find('a').text().trim(); + var releaseDate = null; + releaseDate = loadedCheerio(this) + .find('span.chapter-release-date') + .text() + .trim(); + if (releaseDate) { + releaseDate = (0, parseMadaraDate_1.parseMadaraDate)(releaseDate); + } + else { + /** + * Insert current date + */ + releaseDate = (0, dayjs_1.default)().format('LL'); + } + var chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); + }); + novel.chapters = chapters.reverse(); + return [2 /*return*/, novel]; + } + }); + }); + }; + MadaraPlugin.prototype.parseChapter = function (chapterUrl) { + return __awaiter(this, void 0, void 0, function () { + var body, loadedCheerio, chapterText; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, (0, fetch_1.fetchApi)(chapterUrl).then(function (res) { return res.text(); })]; + case 1: + body = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + chapterText = loadedCheerio('.text-left').html() || + loadedCheerio('.text-right').html() || + loadedCheerio('.entry-content').html() || ""; + return [2 /*return*/, chapterText]; + } + }); + }); + }; + MadaraPlugin.prototype.searchNovels = function (searchTerm, pageNo) { + return __awaiter(this, void 0, void 0, function () { + var novels, url, body, loadedCheerio; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + novels = []; + url = this.site + "?s=" + searchTerm + "&post_type=wp-manga"; + return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })]; + case 1: + body = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.c-tabs-item__content').each(function () { + var novelName = loadedCheerio(this).find('.post-title').text().trim(); + var image = loadedCheerio(this).find('img'); + var novelCover = image.attr('data-src') || image.attr('src'); + var novelUrl = loadedCheerio(this) + .find('.post-title') + .find('a') + .attr('href') || ''; + var novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + novels.push(novel); + }); + return [2 /*return*/, novels]; + } + }); + }); + }; + MadaraPlugin.prototype.fetchImage = function (url) { + return __awaiter(this, void 0, void 0, function () { + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, (0, fetch_1.fetchFile)(url, {})]; + case 1: return [2 /*return*/, _a.sent()]; + } + }); + }); + }; + return MadaraPlugin; +}()); +var plugin = new MadaraPlugin({ "id": "zetroTL", "sourceSite": "https://zetrotranslation.com/", "sourceName": "Zetro Translation", "filters": [{ "key": "sort", "label": "Order by", "values": [{ "label": "Rating", "value": "rating" }, { "label": "A-Z", "value": "alphabet" }, { "label": "Latest", "value": "latest" }, { "label": "Most Views", "value": "views" }, { "label": "New", "value": "new-manga" }, { "label": "Trending", "value": "trending" }], "inputType": "Picker" }, { "key": "genres", "label": "GENRES", "values": [{ "label": "Action", "value": "action" }, { "label": "Adventure", "value": "adventure" }, { "label": "Comedy", "value": "comedy" }, { "label": "Dark Elf", "value": "dark-elf" }, { "label": "Drama", "value": "drama" }, { "label": "Ecchi", "value": "ecchi" }, { "label": "Fantasy", "value": "fantasy" }, { "label": "Harem", "value": "harem" }, { "label": "Horror", "value": "horror" }, { "label": "Isekai", "value": "isekai" }, { "label": "Mecha", "value": "mecha" }, { "label": "Mystery", "value": "mystery" }, { "label": "NTR", "value": "ntr" }, { "label": "Original Works", "value": "original-works" }, { "label": "Rom-Com", "value": "rom-com" }, { "label": "Romance", "value": "romance" }, { "label": "School", "value": "school" }, { "label": "Shoujo", "value": "shoujo" }, { "label": "Slice of Life", "value": "slice-of-life" }, { "label": "Villain", "value": "villain" }, { "label": "Yuri", "value": "yuri" }], "inputType": "Picker" }], "options": { "path": { "genres": "genre" }, "lang": "English" } }); +exports.default = plugin; diff --git a/.js/plugins/english/ZinnNovel[madara].js b/.js/plugins/english/ZinnNovel[madara].js new file mode 100644 index 0000000..9e42f1e --- /dev/null +++ b/.js/plugins/english/ZinnNovel[madara].js @@ -0,0 +1,269 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __generator = (this && this.__generator) || function (thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (g && (g = 0, op[0] && (_ = 0)), _) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +}; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var fetch_1 = require("@libs/fetch"); +var cheerio_1 = require("cheerio"); +var defaultCover_1 = require("@libs/defaultCover"); +var novelStatus_1 = require("@libs/novelStatus"); +var parseMadaraDate_1 = require("@libs/parseMadaraDate"); +var dayjs_1 = __importDefault(require("dayjs")); +var MadaraDefaultPath = { + novels: 'novel', + novel: 'novel', + chapter: 'novel' +}; +var MadaraPlugin = /** @class */ (function () { + function MadaraPlugin(metadata) { + this.id = metadata.id; + this.name = metadata.sourceName + "[madara]"; + var iconFileName = metadata.sourceName.replace(/\s+/g, "").toLowerCase(); + this.icon = "multisrc/madara/icons/".concat(iconFileName, ".png"); + this.site = metadata.sourceSite; + this.version = "1.0.0"; + this.userAgent = ""; + this.cookieString = ""; + this.options = metadata.options; + this.filter = metadata.filters; + } + MadaraPlugin.prototype.popularNovels = function (pageNo, _a) { + var _b, _c, _d, _e, _f, _g; + var filters = _a.filters, showLatestNovels = _a.showLatestNovels; + return __awaiter(this, void 0, void 0, function () { + var novels, url, body, loadedCheerio; + return __generator(this, function (_h) { + switch (_h.label) { + case 0: + novels = []; + url = this.site; + if ((filters === null || filters === void 0 ? void 0 : filters.genres) && ((_c = (_b = this.options) === null || _b === void 0 ? void 0 : _b.path) === null || _c === void 0 ? void 0 : _c.genres)) { + url += ((_e = (_d = this.options) === null || _d === void 0 ? void 0 : _d.path) === null || _e === void 0 ? void 0 : _e.genres) + filters.genres + '/'; + } + else { + url += ((_g = (_f = this.options) === null || _f === void 0 ? void 0 : _f.path) === null || _g === void 0 ? void 0 : _g.novels) ? this.options.path.novels : MadaraDefaultPath.novels; + } + url += '/page/' + pageNo + '/' + + '?m_orderby=' + (showLatestNovels ? 'latest' : ((filters === null || filters === void 0 ? void 0 : filters.sort) || 'rating')); + return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })]; + case 1: + body = _h.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.manga-title-badges').remove(); + loadedCheerio('.page-item-detail').each(function () { + var novelName = loadedCheerio(this).find('.post-title').text().trim(); + var image = loadedCheerio(this).find('img'); + var novelCover = image.attr('data-src') || image.attr('src'); + var novelUrl = loadedCheerio(this).find('.post-title') + .find('a') + .attr('href') || ''; + var novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + novels.push(novel); + }); + return [2 /*return*/, novels]; + } + }); + }); + }; + MadaraPlugin.prototype.parseNovelAndChapters = function (novelUrl) { + var _a; + return __awaiter(this, void 0, void 0, function () { + var novel, body, loadedCheerio, html, novelId, formData, chapters; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + novel = { + url: novelUrl, + }; + return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl).then(function (res) { return res.text(); })]; + case 1: + body = _b.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.manga-title-badges, #manga-title span').remove(); + novel.name = + loadedCheerio('.post-title h1').text().trim() || + loadedCheerio('#manga-title h1').text(); + novel.cover = + loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || + loadedCheerio('.summary_image > a > img').attr('data-src') || + loadedCheerio('.summary_image > a > img').attr('src') || + defaultCover_1.defaultCover; + loadedCheerio('.post-content_item, .post-content').each(function () { + var detailName = loadedCheerio(this).find('h5').text().trim(); + var detail = loadedCheerio(this).find('.summary-content').text().trim(); + switch (detailName) { + case 'Genre(s)': + case 'التصنيفات': + novel.genres = detail.replace(/[\\t\\n]/g, ','); + break; + case 'Author(s)': + case 'المؤلف': + case 'المؤلف (ين)': + novel.author = detail; + break; + case 'Status': + case 'الحالة': + novel.status = + detail.includes('OnGoing') || detail.includes('مستمرة') + ? novelStatus_1.NovelStatus.Ongoing + : novelStatus_1.NovelStatus.Completed; + break; + } + }); + loadedCheerio('div.summary__content .code-block,script').remove(); + novel.summary = + loadedCheerio('div.summary__content').text().trim() || + loadedCheerio('#tab-manga-about').text().trim() || + loadedCheerio('.post-content_item h5:contains("Summary")').next().text().trim(); + if (!(((_a = this.options) === null || _a === void 0 ? void 0 : _a.useNewChapterEndpoint) !== true)) return [3 /*break*/, 3]; + novelId = loadedCheerio('.rating-post-id').attr('value') || + loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; + formData = new FormData(); + formData.append("action", "manga_get_chapters"); + formData.append("manga", novelId); + return [4 /*yield*/, (0, fetch_1.fetchApi)(this.site + 'wp-admin/admin-ajax.php', { + method: 'POST', + body: formData, + }) + .then(function (res) { return res.text(); })]; + case 2: + html = _b.sent(); + return [3 /*break*/, 5]; + case 3: return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl + 'ajax/chapters/', { method: 'POST' }) + .then(function (res) { return res.text(); })]; + case 4: + html = _b.sent(); + _b.label = 5; + case 5: + if (html !== '0') { + loadedCheerio = (0, cheerio_1.load)(html); + } + chapters = []; + loadedCheerio('.wp-manga-chapter').each(function () { + var chapterName = loadedCheerio(this).find('a').text().trim(); + var releaseDate = null; + releaseDate = loadedCheerio(this) + .find('span.chapter-release-date') + .text() + .trim(); + if (releaseDate) { + releaseDate = (0, parseMadaraDate_1.parseMadaraDate)(releaseDate); + } + else { + /** + * Insert current date + */ + releaseDate = (0, dayjs_1.default)().format('LL'); + } + var chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); + }); + novel.chapters = chapters.reverse(); + return [2 /*return*/, novel]; + } + }); + }); + }; + MadaraPlugin.prototype.parseChapter = function (chapterUrl) { + return __awaiter(this, void 0, void 0, function () { + var body, loadedCheerio, chapterText; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, (0, fetch_1.fetchApi)(chapterUrl).then(function (res) { return res.text(); })]; + case 1: + body = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + chapterText = loadedCheerio('.text-left').html() || + loadedCheerio('.text-right').html() || + loadedCheerio('.entry-content').html() || ""; + return [2 /*return*/, chapterText]; + } + }); + }); + }; + MadaraPlugin.prototype.searchNovels = function (searchTerm, pageNo) { + return __awaiter(this, void 0, void 0, function () { + var novels, url, body, loadedCheerio; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + novels = []; + url = this.site + "?s=" + searchTerm + "&post_type=wp-manga"; + return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })]; + case 1: + body = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.c-tabs-item__content').each(function () { + var novelName = loadedCheerio(this).find('.post-title').text().trim(); + var image = loadedCheerio(this).find('img'); + var novelCover = image.attr('data-src') || image.attr('src'); + var novelUrl = loadedCheerio(this) + .find('.post-title') + .find('a') + .attr('href') || ''; + var novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + novels.push(novel); + }); + return [2 /*return*/, novels]; + } + }); + }); + }; + MadaraPlugin.prototype.fetchImage = function (url) { + return __awaiter(this, void 0, void 0, function () { + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, (0, fetch_1.fetchFile)(url, {})]; + case 1: return [2 /*return*/, _a.sent()]; + } + }); + }); + }; + return MadaraPlugin; +}()); +var plugin = new MadaraPlugin({ "id": "zinnovel", "sourceSite": "https://zinnovel.com/", "sourceName": "ZinnNovel", "filters": [{ "key": "sort", "label": "Order by", "values": [{ "label": "Rating", "value": "rating" }, { "label": "A-Z", "value": "alphabet" }, { "label": "Latest", "value": "latest" }, { "label": "Most Views", "value": "views" }, { "label": "New", "value": "new-manga" }, { "label": "Trending", "value": "trending" }], "inputType": "Picker" }, { "key": "genres", "label": "GENRES", "values": [{ "label": "Action", "value": "action" }, { "label": "Adult", "value": "adult" }, { "label": "Adventure", "value": "adventure" }, { "label": "Anime", "value": "anime" }, { "label": "Cartoon", "value": "cartoon" }, { "label": "Comedy", "value": "comedy" }, { "label": "Comic", "value": "comic" }, { "label": "Cooking", "value": "cooking" }, { "label": "Detective", "value": "detective" }, { "label": "Doujinshi", "value": "doujinshi" }, { "label": "Drama", "value": "drama" }, { "label": "Ecchi", "value": "ecchi" }, { "label": "Fantasy", "value": "fantasy" }, { "label": "Game", "value": "game" }, { "label": "Gender Bender", "value": "gender-bender" }, { "label": "Harem", "value": "harem" }, { "label": "Historical", "value": "historical" }, { "label": "Horror", "value": "horror" }, { "label": "Isekai", "value": "isekai" }, { "label": "Josei", "value": "josei" }, { "label": "Live action", "value": "live-action" }, { "label": "Lolicon", "value": "lolicon" }, { "label": "Magical Realism", "value": "magical-realism" }, { "label": "Manga", "value": "manga" }, { "label": "Manhua", "value": "manhua" }, { "label": "Manhwa", "value": "manhwa" }, { "label": "Martial Arts", "value": "martial-arts" }, { "label": "Mature", "value": "mature" }, { "label": "Mecha", "value": "mecha" }, { "label": "Mystery", "value": "mystery" }, { "label": "One shot", "value": "one-shot" }, { "label": "Psychological", "value": "psychological" }, { "label": "Reincarnation", "value": "reincarnation" }, { "label": "Romance", "value": "romance" }, { "label": "School Life", "value": "school-life" }, { "label": "Sci-fi", "value": "sci-fi" }, { "label": "Seinen", "value": "seinen" }, { "label": "Shoujo", "value": "shoujo" }, { "label": "Shoujo Ai", "value": "shoujo-ai" }, { "label": "Shounen", "value": "shounen" }, { "label": "Shounen Ai", "value": "shounen-ai" }, { "label": "Slice of Life", "value": "slice-of-life" }, { "label": "Smut", "value": "smut" }, { "label": "Soft Yaoi", "value": "soft-yaoi" }, { "label": "Soft Yuri", "value": "soft-yuri" }, { "label": "Sports", "value": "sports" }, { "label": "Supernatural", "value": "supernatural" }, { "label": "Tragedy", "value": "tragedy" }, { "label": "Video Games", "value": "video-games" }, { "label": "Webtoon", "value": "webtoon" }, { "label": "Wuxia", "value": "wuxia" }, { "label": "Xianxia", "value": "xianxia" }, { "label": "Xuanhuan", "value": "xuanhuan" }, { "label": "Yaoi", "value": "yaoi" }, { "label": "Yuri", "value": "yuri" }], "inputType": "Picker" }], "options": { "path": { "novels": "manga", "novel": "manga", "chapter": "manga", "genres": "manga-genre" }, "lang": "English" } }); +exports.default = plugin; diff --git a/.js/plugins/english/bestlightnovel.js b/.js/plugins/english/bestlightnovel.js new file mode 100644 index 0000000..25af43d --- /dev/null +++ b/.js/plugins/english/bestlightnovel.js @@ -0,0 +1,231 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __generator = (this && this.__generator) || function (thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (g && (g = 0, op[0] && (_ = 0)), _) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var cheerio_1 = require("cheerio"); +var defaultCover_1 = require("@libs/defaultCover"); +var fetch_1 = require("@libs/fetch"); +var novelStatus_1 = require("@libs/novelStatus"); +var BLN = /** @class */ (function () { + function BLN() { + this.id = "BLN.com"; + this.name = "BestLightNovel"; + this.icon = "src/en/bestlightnovel/icon.png"; + this.site = "https://bestlightnovel.com/"; + this.version = "1.0.0"; + this.userAgent = ""; + this.cookieString = ""; + } + BLN.prototype.popularNovels = function (pageNo, options) { + return __awaiter(this, void 0, void 0, function () { + var url, result, _a, _b, body, loadedCheerio, novels; + return __generator(this, function (_c) { + switch (_c.label) { + case 0: + url = this.site + "novel_list?type=topview&category=all&state=all&page=1" + pageNo; + return [4 /*yield*/, fetch(url)]; + case 1: + result = _c.sent(); + if (!!result.ok) return [3 /*break*/, 3]; + _b = (_a = console).error; + return [4 /*yield*/, result.text()]; + case 2: + _b.apply(_a, [_c.sent()]); + // TODO: Cloudflare protection or other error + return [2 /*return*/, []]; + case 3: return [4 /*yield*/, result.text()]; + case 4: + body = _c.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + novels = []; + loadedCheerio(".update_item.list_category").each(function () { + var novelName = loadedCheerio(this).find("h3 > a").text(); + var novelCover = loadedCheerio(this).find("img").attr("src"); + var novelUrl = loadedCheerio(this).find("h3 > a").attr("href"); + if (!novelUrl) { + // TODO: Handle error + console.error("No novel url!"); + return; + } + var novel = { + name: novelName, + url: novelUrl, + cover: novelCover, + }; + novels.push(novel); + }); + return [2 /*return*/, novels]; + } + }); + }); + }; + BLN.prototype.parseNovelAndChapters = function (novelUrl) { + var _a, _b, _c; + return __awaiter(this, void 0, void 0, function () { + var url, result, _d, _e, body, loadedCheerio, novel, status, novelChapters; + return __generator(this, function (_f) { + switch (_f.label) { + case 0: + url = novelUrl; + return [4 /*yield*/, fetch(url)]; + case 1: + result = _f.sent(); + if (!!result.ok) return [3 /*break*/, 3]; + _e = (_d = console).error; + return [4 /*yield*/, result.text()]; + case 2: + _e.apply(_d, [_f.sent()]); + // TODO: Cloudflare protection + return [2 /*return*/, { url: url, chapters: [] }]; + case 3: return [4 /*yield*/, result.text()]; + case 4: + body = _f.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + novel = { + url: url, + name: "", + cover: "", + author: "", + status: novelStatus_1.NovelStatus.Unknown, + genres: "", + summary: "", + chapters: [], + }; + novel.name = loadedCheerio(".truyen_info_right h1").text().trim(); + novel.cover = + loadedCheerio(".info_image img").attr("src") || defaultCover_1.defaultCover; + novel.summary = (_a = loadedCheerio("#noidungm").text()) === null || _a === void 0 ? void 0 : _a.trim(); + novel.author = (_b = loadedCheerio("#main_body > div.cotgiua > div.truyen_info_wrapper > div.truyen_info > div.entry-header > div.truyen_if_wrap > ul > li:nth-child(2) > a") + .text()) === null || _b === void 0 ? void 0 : _b.trim(); + status = (_c = loadedCheerio("#main_body > div.cotgiua > div.truyen_info_wrapper > div.truyen_info > div.entry-header > div.truyen_if_wrap > ul > li:nth-child(4) > a") + .text()) === null || _c === void 0 ? void 0 : _c.trim(); + novel.status = + status === "ONGOING" + ? novelStatus_1.NovelStatus.Ongoing + : status === "COMPLETED" + ? novelStatus_1.NovelStatus.Completed + : novelStatus_1.NovelStatus.Unknown; + novelChapters = []; + loadedCheerio(".chapter-list div.row").each(function () { + var chapterName = loadedCheerio(this).find("a").text().trim(); + var releaseDate = loadedCheerio(this) + .find("span:nth-child(2)") + .text() + .trim(); + var chapterUrl = loadedCheerio(this).find("a").attr("href"); + if (!chapterUrl) { + // TODO: Handle error + console.error("No chapter url!"); + return; + } + novelChapters.push({ + name: chapterName, + releaseTime: releaseDate, + url: chapterUrl, + }); + }); + novel.chapters = novelChapters.reverse(); + return [2 /*return*/, novel]; + } + }); + }); + }; + BLN.prototype.parseChapter = function (chapterUrl) { + return __awaiter(this, void 0, void 0, function () { + var url, result, body, loadedCheerio, chapterText; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + url = chapterUrl; + return [4 /*yield*/, fetch(url)]; + case 1: + result = _a.sent(); + return [4 /*yield*/, result.text()]; + case 2: + body = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + chapterText = loadedCheerio("#vung_doc").html() || ""; + return [2 /*return*/, chapterText]; + } + }); + }); + }; + BLN.prototype.searchNovels = function (searchTerm, pageNo) { + return __awaiter(this, void 0, void 0, function () { + var url, result, body, loadedCheerio, novels; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + url = "".concat(this.site, "search_novels/").concat(searchTerm); + return [4 /*yield*/, fetch(url)]; + case 1: + result = _a.sent(); + return [4 /*yield*/, result.text()]; + case 2: + body = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + novels = []; + loadedCheerio(".update_item.list_category").each(function () { + var novelName = loadedCheerio(this).find("h3 > a").text(); + var novelCover = loadedCheerio(this).find("img").attr("src"); + var novelUrl = loadedCheerio(this).find("h3 > a").attr("href"); + if (!novelUrl) { + // TODO: Handle error + console.error("No novel url!"); + return; + } + var novel = { name: novelName, cover: novelCover, url: novelUrl }; + novels.push(novel); + }); + return [2 /*return*/, novels]; + } + }); + }); + }; + BLN.prototype.fetchImage = function (url) { + return __awaiter(this, void 0, void 0, function () { + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, (0, fetch_1.fetchFile)(url)]; + case 1: return [2 /*return*/, _a.sent()]; + } + }); + }); + }; + return BLN; +}()); +exports.default = new BLN(); diff --git a/.js/plugins/english/nobleMTL.js b/.js/plugins/english/nobleMTL.js new file mode 100644 index 0000000..db22d5b --- /dev/null +++ b/.js/plugins/english/nobleMTL.js @@ -0,0 +1,377 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __generator = (this && this.__generator) || function (thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (g && (g = 0, op[0] && (_ = 0)), _) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var cheerio_1 = require("cheerio"); +var fetch_1 = require("@libs/fetch"); +var filterInputs_1 = require("@libs/filterInputs"); +var NobleMTL = /** @class */ (function () { + function NobleMTL() { + this.id = "noblemtl"; + this.name = "NobleMTL"; + this.icon = "src/en/noblemtl/icon.png"; + this.site = "https://noblemtl.com/"; + this.version = "1.0.0"; + this.userAgent = ""; + this.cookieString = ""; + this.filters = [ + { + key: "order", + label: "Sort By", + values: [ + { label: "Default", value: "" }, + { label: "A-Z", value: "title" }, + { label: "Z-A", value: "titlereverse" }, + { label: "Latest Update", value: "update" }, + { label: "Latest Added", value: "latest" }, + { label: "Popular", value: "popular" }, + ], + inputType: filterInputs_1.FilterInputs.Picker, + }, + { + key: "status", + label: "Status", + values: [ + { label: "All", value: "" }, + { label: "Ongoing", value: "ongoing" }, + { label: "Hiatus", value: "hiatus" }, + { label: "Completed", value: "completed" }, + ], + inputType: filterInputs_1.FilterInputs.Picker, + }, + { + key: "type", + label: "Type", + values: [ + { label: "Chinese novel", value: "chinese-novel" }, + { label: "habyeol", value: "habyeol" }, + { label: "korean novel", value: "korean-novel" }, + { label: "Web Novel", value: "web-novel" }, + { label: "삼심", value: "%ec%82%bc%ec%8b%ac" }, + { label: "호곡", value: "%ed%98%b8%ea%b3%a1" }, + ], + inputType: filterInputs_1.FilterInputs.Checkbox, + }, + { + key: "genres", + label: "Genres", + values: [ + { label: "A.I", value: "a.i" }, + { label: "Academy", value: "academy" }, + { label: "Action", value: "action" }, + { label: "Adult", value: "adult" }, + { label: "Adventure", value: "adventure" }, + { label: "Alternative History", value: "alternative-history" }, + { label: "Another World", value: "another-world" }, + { label: "Apocalypse", value: "apocalypse" }, + { label: "Bromance", value: "bromance" }, + { label: "Comedy", value: "comedy" }, + { label: "Dark fantasy", value: "dark-fantasy" }, + { label: "Demons", value: "demons" }, + { label: "Drama", value: "drama" }, + { label: "Dystopia", value: "dystopia" }, + { label: "Ecchi", value: "ecchi" }, + { label: "Entertainment", value: "entertainment" }, + { label: "Exhaustion", value: "exhaustion" }, + { label: "Fanfiction", value: "fanfiction" }, + { label: "fantasy", value: "fantasy" }, + { label: "finance", value: "finance" }, + { label: "Full color", value: "full-color" }, + { label: "Game", value: "game" }, + { label: "Gender Bender", value: "gender-bender" }, + { label: "Genius", value: "genius" }, + { label: "Harem", value: "harem" }, + { label: "Hero", value: "hero" }, + { label: "Historical", value: "historical" }, + { label: "Hunter", value: "hunter" }, + { label: "korean novel", value: "korean-novel" }, + { label: "Light Novel", value: "light-novel" }, + { + label: "List Adventure Manga Genres", + value: "list-adventure-manga-genres", + }, + { label: "Long Strip", value: "long-strip" }, + { label: "Love comedy", value: "love-comedy" }, + { label: "magic", value: "magic" }, + { label: "Manhua", value: "manhua" }, + { label: "Martial Arts", value: "martial-arts" }, + { label: "Mature", value: "mature" }, + { label: "Medieval", value: "medieval" }, + { label: "Misunderstanding", value: "misunderstanding" }, + { label: "Modern", value: "modern" }, + { label: "modern fantasy", value: "modern-fantasy" }, + { label: "music", value: "music" }, + { label: "Mystery", value: "mystery" }, + { label: "Necromancy", value: "necromancy" }, + { label: "No Romance", value: "no-romance" }, + { label: "NTL", value: "ntl" }, + { label: "o", value: "o" }, + { label: "Obsession", value: "obsession" }, + { label: "Politics", value: "politics" }, + { label: "Possession", value: "possession" }, + { label: "Programming", value: "programming" }, + { label: "Psychological", value: "psychological" }, + { label: "Pure Love", value: "pure-love" }, + { label: "Redemption", value: "redemption" }, + { label: "Regression", value: "regression" }, + { label: "Regret", value: "regret" }, + { label: "Reincarnation", value: "reincarnation" }, + { label: "Revenge", value: "revenge" }, + { label: "Romance", value: "romance" }, + { label: "Romance Fanrasy", value: "romance-fanrasy" }, + { label: "Salvation", value: "salvation" }, + { label: "School Life", value: "school-life" }, + { label: "Sci-fi", value: "sci-fi" }, + { label: "Science fiction", value: "science-fiction" }, + { label: "Seinen", value: "seinen" }, + { label: "Shounen", value: "shounen" }, + { label: "Slice of Life", value: "slice-of-life" }, + { label: "Soft yandere", value: "soft-yandere" }, + { label: "Sports", value: "sports" }, + { label: "Supernatural", value: "supernatural" }, + { label: "Survival", value: "survival" }, + { label: "system", value: "system" }, + { label: "Time limit", value: "time-limit" }, + { label: "Tragedy", value: "tragedy" }, + { label: "Transmigration", value: "transmigration" }, + { label: "TS", value: "ts" }, + { label: "Tsundere", value: "tsundere" }, + { label: "Unique", value: "unique" }, + { label: "Wholesome", value: "wholesome" }, + { label: "Wuxia", value: "wuxia" }, + { label: "Xuanhuan", value: "xuanhuan" }, + { label: "Yandere", value: "yandere" }, + { label: "Yuri", value: "yuri" }, + ], + inputType: filterInputs_1.FilterInputs.Checkbox, + }, + ]; + } + NobleMTL.prototype.popularNovels = function (pageNo, _a) { + var filters = _a.filters; + return __awaiter(this, void 0, void 0, function () { + var link, headers, body, loadedCheerio, novels; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + link = "".concat(this.site, "series/?page=").concat(pageNo); + if (filters) { + if (Array.isArray(filters.genres) && filters.genres.length) { + link += filters.genres.map(function (i) { return "&genre[]=".concat(i); }).join(""); + } + if (Array.isArray(filters.type) && filters.type.length) + link += filters.type.map(function (i) { return "&lang[]=".concat(i); }).join(""); + } + link += "&status=" + ((filters === null || filters === void 0 ? void 0 : filters.status) ? filters.status : ""); + link += "&order=" + ((filters === null || filters === void 0 ? void 0 : filters.order) ? filters.order : "popular"); + headers = new Headers(); + if (this.cookieString) { + headers.append("cookie", this.cookieString); + } + return [4 /*yield*/, (0, fetch_1.fetchApi)(link, { headers: headers }).then(function (result) { + return result.text(); + })]; + case 1: + body = _b.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + novels = []; + loadedCheerio("article.bs").each(function () { + var novelName = loadedCheerio(this).find(".ntitle").text().trim(); + var image = loadedCheerio(this).find("img"); + var novelCover = image.attr("data-src") || image.attr("src"); + var novelUrl = loadedCheerio(this).find("a").attr("href"); + if (!novelUrl) + return; + var novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + novels.push(novel); + }); + return [2 /*return*/, novels]; + } + }); + }); + }; + ; + NobleMTL.prototype.parseNovelAndChapters = function (novelUrl) { + return __awaiter(this, void 0, void 0, function () { + var url, headers, result, body, loadedCheerio, novel, chapter; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + url = novelUrl; + headers = new Headers(); + if (this.cookieString) { + headers.append("cookie", this.cookieString); + } + return [4 /*yield*/, (0, fetch_1.fetchApi)(url, { headers: headers })]; + case 1: + result = _a.sent(); + return [4 /*yield*/, result.text()]; + case 2: + body = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + novel = { + url: url, + chapters: [], + }; + novel.name = loadedCheerio(".entry-title").text(); + novel.cover = + loadedCheerio("img.wp-post-image").attr("data-src") || + loadedCheerio("img.wp-post-image").attr("src"); + loadedCheerio("div.spe > span").each(function () { + var detailName = loadedCheerio(this).find("b").text().trim(); + var detail = loadedCheerio(this).find('b').remove().end().text().trim(); + switch (detailName) { + case "Author:": + novel.author = detail; + break; + case "Status:": + novel.status = detail; + break; + } + }); + novel.genres = loadedCheerio(".genxed") + .text() + .trim() + .replace(/\s/g, ","); + loadedCheerio('div[itemprop="description"] h3,p.a,strong').remove(); + novel.summary = loadedCheerio('div[itemprop="description"]') + .find("br") + .replaceWith("\n") + .end() + .text(); + chapter = []; + loadedCheerio(".eplister") + .find("li") + .each(function () { + var chapterName = loadedCheerio(this).find(".epl-num").text() + + " - " + + loadedCheerio(this).find(".epl-title").text(); + var releaseDate = loadedCheerio(this) + .find(".epl-date") + .text() + .trim(); + var chapterUrl = loadedCheerio(this).find("a").attr("href"); + if (!chapterUrl) + return; + chapter.push({ + name: chapterName, + releaseTime: releaseDate, + url: chapterUrl, + }); + }); + novel.chapters = chapter.reverse(); + return [2 /*return*/, novel]; + } + }); + }); + }; + NobleMTL.prototype.parseChapter = function (chapterUrl) { + return __awaiter(this, void 0, void 0, function () { + var headers, result, body, loadedCheerio, chapterText; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + headers = new Headers(); + if (this.cookieString) { + headers.append("cookie", this.cookieString); + } + return [4 /*yield*/, (0, fetch_1.fetchApi)(chapterUrl, { headers: headers })]; + case 1: + result = _a.sent(); + return [4 /*yield*/, result.text()]; + case 2: + body = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + chapterText = loadedCheerio(".epcontent").html() || ""; + return [2 /*return*/, chapterText]; + } + }); + }); + }; + NobleMTL.prototype.searchNovels = function (searchTerm, pageNo) { + return __awaiter(this, void 0, void 0, function () { + var url, headers, result, body, loadedCheerio, novels; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + url = "".concat(this.site, "?s=").concat(searchTerm); + headers = new Headers(); + if (this.cookieString) { + headers.append("cookie", this.cookieString); + } + return [4 /*yield*/, (0, fetch_1.fetchApi)(url, { headers: headers })]; + case 1: + result = _a.sent(); + return [4 /*yield*/, result.text()]; + case 2: + body = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + novels = []; + loadedCheerio("article.bs").each(function () { + var novelName = loadedCheerio(this).find(".ntitle").text().trim(); + var novelCover = loadedCheerio(this).find("img").attr("src"); + var novelUrl = loadedCheerio(this).find("a").attr("href"); + if (!novelUrl) + return; + novels.push({ + name: novelName, + url: novelUrl, + cover: novelCover, + }); + }); + return [2 /*return*/, novels]; + } + }); + }); + }; + NobleMTL.prototype.fetchImage = function (url) { + return __awaiter(this, void 0, void 0, function () { + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, (0, fetch_1.fetchFile)(url)]; + case 1: return [2 /*return*/, _a.sent()]; + } + }); + }); + }; + return NobleMTL; +}()); +exports.default = new NobleMTL(); diff --git a/.js/plugins/english/pandaMTL.js b/.js/plugins/english/pandaMTL.js new file mode 100644 index 0000000..50d8b18 --- /dev/null +++ b/.js/plugins/english/pandaMTL.js @@ -0,0 +1,304 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __generator = (this && this.__generator) || function (thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (g && (g = 0, op[0] && (_ = 0)), _) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var cheerio_1 = require("cheerio"); +var fetch_1 = require("@libs/fetch"); +var filterInputs_1 = require("@libs/filterInputs"); +var PandaMTL = /** @class */ (function () { + function PandaMTL() { + this.id = "pandamtl"; + this.name = "PandaMTL"; + this.icon = "src/en/wordpress/icon.png"; + this.site = "https://pandamtl.com/"; + this.version = "1.0.0"; + this.userAgent = ""; + this.cookieString = ""; + this.filters = [ + { + key: "order", + label: "Sort By", + values: [ + { label: "Default", value: "" }, + { label: "A-Z", value: "title" }, + { label: "Z-A", value: "titlereverse" }, + { label: "Latest Update", value: "update" }, + { label: "Latest Added", value: "latest" }, + { label: "Popular", value: "popular" }, + ], + inputType: filterInputs_1.FilterInputs.Picker, + }, + { + key: "status", + label: "Status", + values: [ + { label: "All", value: "" }, + { label: "Ongoing", value: "ongoing" }, + { label: "Hiatus", value: "hiatus" }, + { label: "Completed", value: "completed" }, + ], + inputType: filterInputs_1.FilterInputs.Picker, + }, + { + key: "type", + label: "Type", + values: [ + { label: "Light Novel (KR)", value: "light-novel-kr" }, + { label: "Web Novel", value: "web-novel" }, + ], + inputType: filterInputs_1.FilterInputs.Checkbox, + }, + { + key: "genres", + label: "Genres", + values: [ + { label: "Action", value: "action" }, + { label: "Adult", value: "adult" }, + { label: "Adventure", value: "adventure" }, + { label: "Comedy", value: "comedy" }, + { label: "Ecchi", value: "ecchi" }, + { label: "Fantasy", value: "fantasy" }, + { label: "Harem", value: "harem" }, + { label: "Josei", value: "josei" }, + { label: "Martial Arts", value: "martial-arts" }, + { label: "Mature", value: "mature" }, + { label: "Romance", value: "romance" }, + { label: "School Life", value: "school-life" }, + { label: "Sci-fi", value: "sci-fi" }, + { label: "Seinen", value: "seinen" }, + { label: "Slice of Life", value: "slice-of-life" }, + { label: "Smut", value: "smut" }, + { label: "Sports", value: "sports" }, + { label: "Supernatural", value: "supernatural" }, + { label: "Tragedy", value: "tragedy" }, + ], + inputType: filterInputs_1.FilterInputs.Checkbox, + }, + ]; + } + PandaMTL.prototype.popularNovels = function (pageNo, _a) { + var filters = _a.filters; + return __awaiter(this, void 0, void 0, function () { + var link, headers, body, loadedCheerio, novels; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + link = "".concat(this.site, "series/?page=").concat(pageNo); + if (filters) { + if (Array.isArray(filters.genres) && filters.genres.length) { + link += filters.genres.map(function (i) { return "&genre[]=".concat(i); }).join(""); + } + if (Array.isArray(filters.type) && filters.type.length) + link += filters.type.map(function (i) { return "&lang[]=".concat(i); }).join(""); + } + link += "&status=" + ((filters === null || filters === void 0 ? void 0 : filters.status) ? filters.status : ""); + link += "&order=" + ((filters === null || filters === void 0 ? void 0 : filters.order) ? filters.order : "popular"); + headers = new Headers(); + if (this.cookieString) { + headers.append("cookie", this.cookieString); + } + return [4 /*yield*/, (0, fetch_1.fetchApi)(link, { headers: headers }).then(function (result) { + return result.text(); + })]; + case 1: + body = _b.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + novels = []; + loadedCheerio("article.maindet").each(function () { + var novelName = loadedCheerio(this).find("h2").text(); + var image = loadedCheerio(this).find("img"); + var novelCover = image.attr("data-src") || image.attr("src"); + var novelUrl = loadedCheerio(this).find("h2 a").attr("href"); + if (!novelUrl) + return; + var novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + novels.push(novel); + }); + return [2 /*return*/, novels]; + } + }); + }); + }; + PandaMTL.prototype.parseNovelAndChapters = function (novelUrl) { + return __awaiter(this, void 0, void 0, function () { + var url, headers, result, body, loadedCheerio, novel, chapter; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + url = novelUrl; + headers = new Headers(); + if (this.cookieString) { + headers.append("cookie", this.cookieString); + } + return [4 /*yield*/, (0, fetch_1.fetchApi)(url, { headers: headers })]; + case 1: + result = _a.sent(); + return [4 /*yield*/, result.text()]; + case 2: + body = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + novel = { + url: url, + chapters: [], + }; + novel.name = loadedCheerio("h1.entry-title").text(); + novel.cover = + loadedCheerio("img.wp-post-image").attr("data-src") || + loadedCheerio("img.wp-post-image").attr("src"); + loadedCheerio(".serl:nth-child(3) > span").each(function () { + var detailName = loadedCheerio(this).text().trim(); + var detail = loadedCheerio(this).next().text().trim(); + switch (detailName) { + case "Author": + novel.author = detail; + break; + } + }); + novel.status = loadedCheerio(".sertostat > span").attr("class"); + novel.genres = loadedCheerio(".sertogenre") + .children("a") + .map(function (i, el) { return loadedCheerio(el).text(); }) + .toArray() + .join(","); + novel.summary = loadedCheerio(".sersys") + .find("br") + .replaceWith("\n") + .end() + .text(); + chapter = []; + loadedCheerio(".eplister") + .find("li") + .each(function () { + var chapterName = loadedCheerio(this).find(".epl-num").text() + + " - " + + loadedCheerio(this).find(".epl-title").text(); + var releaseDate = loadedCheerio(this) + .find(".epl-date") + .text() + .trim(); + var chapterUrl = loadedCheerio(this).find("a").attr("href"); + if (!chapterUrl) + return; + chapter.push({ + name: chapterName, + releaseTime: releaseDate, + url: chapterUrl, + }); + }); + novel.chapters = chapter.reverse(); + return [2 /*return*/, novel]; + } + }); + }); + }; + PandaMTL.prototype.parseChapter = function (chapterUrl) { + return __awaiter(this, void 0, void 0, function () { + var headers, result, body, loadedCheerio, chapterText; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + headers = new Headers(); + if (this.cookieString) { + headers.append("cookie", this.cookieString); + } + return [4 /*yield*/, (0, fetch_1.fetchApi)(chapterUrl, { headers: headers })]; + case 1: + result = _a.sent(); + return [4 /*yield*/, result.text()]; + case 2: + body = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + chapterText = loadedCheerio(".epcontent").html() || ""; + return [2 /*return*/, chapterText]; + } + }); + }); + }; + PandaMTL.prototype.searchNovels = function (searchTerm, pageNo) { + return __awaiter(this, void 0, void 0, function () { + var url, headers, result, body, loadedCheerio, novels; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + url = "".concat(this.site, "?s=").concat(searchTerm); + headers = new Headers(); + if (this.cookieString) { + headers.append("cookie", this.cookieString); + } + return [4 /*yield*/, (0, fetch_1.fetchApi)(url, { headers: headers })]; + case 1: + result = _a.sent(); + return [4 /*yield*/, result.text()]; + case 2: + body = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + novels = []; + loadedCheerio("article.maindet").each(function () { + var novelName = loadedCheerio(this).find("h2").text(); + var image = loadedCheerio(this).find("img"); + var novelCover = image.attr("data-src") || image.attr("src"); + var novelUrl = loadedCheerio(this).find("h2 a").attr("href"); + if (!novelUrl) + return; + novels.push({ + name: novelName, + url: novelUrl, + cover: novelCover, + }); + }); + return [2 /*return*/, novels]; + } + }); + }); + }; + PandaMTL.prototype.fetchImage = function (url) { + return __awaiter(this, void 0, void 0, function () { + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, (0, fetch_1.fetchFile)(url)]; + case 1: return [2 /*return*/, _a.sent()]; + } + }); + }); + }; + return PandaMTL; +}()); +exports.default = new PandaMTL(); diff --git a/.js/plugins/indonesian/MeioNovel[madara].js b/.js/plugins/indonesian/MeioNovel[madara].js new file mode 100644 index 0000000..00bb961 --- /dev/null +++ b/.js/plugins/indonesian/MeioNovel[madara].js @@ -0,0 +1,269 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __generator = (this && this.__generator) || function (thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (g && (g = 0, op[0] && (_ = 0)), _) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +}; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var fetch_1 = require("@libs/fetch"); +var cheerio_1 = require("cheerio"); +var defaultCover_1 = require("@libs/defaultCover"); +var novelStatus_1 = require("@libs/novelStatus"); +var parseMadaraDate_1 = require("@libs/parseMadaraDate"); +var dayjs_1 = __importDefault(require("dayjs")); +var MadaraDefaultPath = { + novels: 'novel', + novel: 'novel', + chapter: 'novel' +}; +var MadaraPlugin = /** @class */ (function () { + function MadaraPlugin(metadata) { + this.id = metadata.id; + this.name = metadata.sourceName + "[madara]"; + var iconFileName = metadata.sourceName.replace(/\s+/g, "").toLowerCase(); + this.icon = "multisrc/madara/icons/".concat(iconFileName, ".png"); + this.site = metadata.sourceSite; + this.version = "1.0.0"; + this.userAgent = ""; + this.cookieString = ""; + this.options = metadata.options; + this.filter = metadata.filters; + } + MadaraPlugin.prototype.popularNovels = function (pageNo, _a) { + var _b, _c, _d, _e, _f, _g; + var filters = _a.filters, showLatestNovels = _a.showLatestNovels; + return __awaiter(this, void 0, void 0, function () { + var novels, url, body, loadedCheerio; + return __generator(this, function (_h) { + switch (_h.label) { + case 0: + novels = []; + url = this.site; + if ((filters === null || filters === void 0 ? void 0 : filters.genres) && ((_c = (_b = this.options) === null || _b === void 0 ? void 0 : _b.path) === null || _c === void 0 ? void 0 : _c.genres)) { + url += ((_e = (_d = this.options) === null || _d === void 0 ? void 0 : _d.path) === null || _e === void 0 ? void 0 : _e.genres) + filters.genres + '/'; + } + else { + url += ((_g = (_f = this.options) === null || _f === void 0 ? void 0 : _f.path) === null || _g === void 0 ? void 0 : _g.novels) ? this.options.path.novels : MadaraDefaultPath.novels; + } + url += '/page/' + pageNo + '/' + + '?m_orderby=' + (showLatestNovels ? 'latest' : ((filters === null || filters === void 0 ? void 0 : filters.sort) || 'rating')); + return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })]; + case 1: + body = _h.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.manga-title-badges').remove(); + loadedCheerio('.page-item-detail').each(function () { + var novelName = loadedCheerio(this).find('.post-title').text().trim(); + var image = loadedCheerio(this).find('img'); + var novelCover = image.attr('data-src') || image.attr('src'); + var novelUrl = loadedCheerio(this).find('.post-title') + .find('a') + .attr('href') || ''; + var novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + novels.push(novel); + }); + return [2 /*return*/, novels]; + } + }); + }); + }; + MadaraPlugin.prototype.parseNovelAndChapters = function (novelUrl) { + var _a; + return __awaiter(this, void 0, void 0, function () { + var novel, body, loadedCheerio, html, novelId, formData, chapters; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + novel = { + url: novelUrl, + }; + return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl).then(function (res) { return res.text(); })]; + case 1: + body = _b.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.manga-title-badges, #manga-title span').remove(); + novel.name = + loadedCheerio('.post-title h1').text().trim() || + loadedCheerio('#manga-title h1').text(); + novel.cover = + loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || + loadedCheerio('.summary_image > a > img').attr('data-src') || + loadedCheerio('.summary_image > a > img').attr('src') || + defaultCover_1.defaultCover; + loadedCheerio('.post-content_item, .post-content').each(function () { + var detailName = loadedCheerio(this).find('h5').text().trim(); + var detail = loadedCheerio(this).find('.summary-content').text().trim(); + switch (detailName) { + case 'Genre(s)': + case 'التصنيفات': + novel.genres = detail.replace(/[\\t\\n]/g, ','); + break; + case 'Author(s)': + case 'المؤلف': + case 'المؤلف (ين)': + novel.author = detail; + break; + case 'Status': + case 'الحالة': + novel.status = + detail.includes('OnGoing') || detail.includes('مستمرة') + ? novelStatus_1.NovelStatus.Ongoing + : novelStatus_1.NovelStatus.Completed; + break; + } + }); + loadedCheerio('div.summary__content .code-block,script').remove(); + novel.summary = + loadedCheerio('div.summary__content').text().trim() || + loadedCheerio('#tab-manga-about').text().trim() || + loadedCheerio('.post-content_item h5:contains("Summary")').next().text().trim(); + if (!(((_a = this.options) === null || _a === void 0 ? void 0 : _a.useNewChapterEndpoint) !== true)) return [3 /*break*/, 3]; + novelId = loadedCheerio('.rating-post-id').attr('value') || + loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; + formData = new FormData(); + formData.append("action", "manga_get_chapters"); + formData.append("manga", novelId); + return [4 /*yield*/, (0, fetch_1.fetchApi)(this.site + 'wp-admin/admin-ajax.php', { + method: 'POST', + body: formData, + }) + .then(function (res) { return res.text(); })]; + case 2: + html = _b.sent(); + return [3 /*break*/, 5]; + case 3: return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl + 'ajax/chapters/', { method: 'POST' }) + .then(function (res) { return res.text(); })]; + case 4: + html = _b.sent(); + _b.label = 5; + case 5: + if (html !== '0') { + loadedCheerio = (0, cheerio_1.load)(html); + } + chapters = []; + loadedCheerio('.wp-manga-chapter').each(function () { + var chapterName = loadedCheerio(this).find('a').text().trim(); + var releaseDate = null; + releaseDate = loadedCheerio(this) + .find('span.chapter-release-date') + .text() + .trim(); + if (releaseDate) { + releaseDate = (0, parseMadaraDate_1.parseMadaraDate)(releaseDate); + } + else { + /** + * Insert current date + */ + releaseDate = (0, dayjs_1.default)().format('LL'); + } + var chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); + }); + novel.chapters = chapters.reverse(); + return [2 /*return*/, novel]; + } + }); + }); + }; + MadaraPlugin.prototype.parseChapter = function (chapterUrl) { + return __awaiter(this, void 0, void 0, function () { + var body, loadedCheerio, chapterText; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, (0, fetch_1.fetchApi)(chapterUrl).then(function (res) { return res.text(); })]; + case 1: + body = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + chapterText = loadedCheerio('.text-left').html() || + loadedCheerio('.text-right').html() || + loadedCheerio('.entry-content').html() || ""; + return [2 /*return*/, chapterText]; + } + }); + }); + }; + MadaraPlugin.prototype.searchNovels = function (searchTerm, pageNo) { + return __awaiter(this, void 0, void 0, function () { + var novels, url, body, loadedCheerio; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + novels = []; + url = this.site + "?s=" + searchTerm + "&post_type=wp-manga"; + return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })]; + case 1: + body = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.c-tabs-item__content').each(function () { + var novelName = loadedCheerio(this).find('.post-title').text().trim(); + var image = loadedCheerio(this).find('img'); + var novelCover = image.attr('data-src') || image.attr('src'); + var novelUrl = loadedCheerio(this) + .find('.post-title') + .find('a') + .attr('href') || ''; + var novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + novels.push(novel); + }); + return [2 /*return*/, novels]; + } + }); + }); + }; + MadaraPlugin.prototype.fetchImage = function (url) { + return __awaiter(this, void 0, void 0, function () { + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, (0, fetch_1.fetchFile)(url, {})]; + case 1: return [2 /*return*/, _a.sent()]; + } + }); + }); + }; + return MadaraPlugin; +}()); +var plugin = new MadaraPlugin({ "id": "meionovel", "sourceSite": "https://meionovel.id/", "sourceName": "MeioNovel", "filters": [{ "key": "sort", "label": "Order by", "values": [{ "label": "Rating", "value": "rating" }, { "label": "A-Z", "value": "alphabet" }, { "label": "Latest", "value": "latest" }, { "label": "Most Views", "value": "views" }, { "label": "New", "value": "new-manga" }, { "label": "Trending", "value": "trending" }], "inputType": "Picker" }, { "key": "genres", "label": "GENRES", "values": [{ "label": "Action", "value": "action" }, { "label": "Adventure", "value": "adventure" }, { "label": "Comedy", "value": "comedy" }, { "label": "Cooking", "value": "cooking" }, { "label": "Drama", "value": "drama" }, { "label": "Ecchi", "value": "ecchi" }, { "label": "Fanfiction", "value": "fanfiction" }, { "label": "Fantasy", "value": "fantasy" }, { "label": "Gender Bender", "value": "gender-bender" }, { "label": "Harem", "value": "harem" }, { "label": "Historical", "value": "historical" }, { "label": "Horror", "value": "horror" }, { "label": "Isekai", "value": "isekai" }, { "label": "Josei", "value": "josei" }, { "label": "Magic", "value": "magic" }, { "label": "Martial Arts", "value": "martial-arts" }, { "label": "Mature", "value": "mature" }, { "label": "Mecha", "value": "mecha" }, { "label": "Mystery", "value": "mystery" }, { "label": "One shot", "value": "one-shot" }, { "label": "Psychological", "value": "psychological" }, { "label": "Reverse Harem", "value": "reverse-harem" }, { "label": "Romance", "value": "romance" }, { "label": "School Life", "value": "school-life" }, { "label": "Sci-fi", "value": "sci-fi" }, { "label": "Seinen", "value": "seinen" }, { "label": "Shoujo", "value": "shoujo" }, { "label": "Shoujo Ai", "value": "shoujo-ai" }, { "label": "Shounen", "value": "shounen" }, { "label": "Shounen Ai", "value": "shounen-ai" }, { "label": "Slice of Life", "value": "slice-of-life" }, { "label": "Smut", "value": "smut" }, { "label": "Sports", "value": "sports" }, { "label": "Supernatural", "value": "supernatural" }, { "label": "Tragedy", "value": "tragedy" }, { "label": "Virtual Reality", "value": "virtual-reality" }, { "label": "Wuxia", "value": "wuxia" }, { "label": "Xianxia", "value": "xianxia" }, { "label": "Xuanhuan", "value": "xuanhuan" }, { "label": "Yuri", "value": "yuri" }], "inputType": "Picker" }], "options": { "useNewChapterEndpoint": true, "lang": "Indonesian" } }); +exports.default = plugin; diff --git a/.js/plugins/indonesian/MoreNovel[madara].js b/.js/plugins/indonesian/MoreNovel[madara].js new file mode 100644 index 0000000..ce9c9ee --- /dev/null +++ b/.js/plugins/indonesian/MoreNovel[madara].js @@ -0,0 +1,269 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __generator = (this && this.__generator) || function (thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (g && (g = 0, op[0] && (_ = 0)), _) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +}; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var fetch_1 = require("@libs/fetch"); +var cheerio_1 = require("cheerio"); +var defaultCover_1 = require("@libs/defaultCover"); +var novelStatus_1 = require("@libs/novelStatus"); +var parseMadaraDate_1 = require("@libs/parseMadaraDate"); +var dayjs_1 = __importDefault(require("dayjs")); +var MadaraDefaultPath = { + novels: 'novel', + novel: 'novel', + chapter: 'novel' +}; +var MadaraPlugin = /** @class */ (function () { + function MadaraPlugin(metadata) { + this.id = metadata.id; + this.name = metadata.sourceName + "[madara]"; + var iconFileName = metadata.sourceName.replace(/\s+/g, "").toLowerCase(); + this.icon = "multisrc/madara/icons/".concat(iconFileName, ".png"); + this.site = metadata.sourceSite; + this.version = "1.0.0"; + this.userAgent = ""; + this.cookieString = ""; + this.options = metadata.options; + this.filter = metadata.filters; + } + MadaraPlugin.prototype.popularNovels = function (pageNo, _a) { + var _b, _c, _d, _e, _f, _g; + var filters = _a.filters, showLatestNovels = _a.showLatestNovels; + return __awaiter(this, void 0, void 0, function () { + var novels, url, body, loadedCheerio; + return __generator(this, function (_h) { + switch (_h.label) { + case 0: + novels = []; + url = this.site; + if ((filters === null || filters === void 0 ? void 0 : filters.genres) && ((_c = (_b = this.options) === null || _b === void 0 ? void 0 : _b.path) === null || _c === void 0 ? void 0 : _c.genres)) { + url += ((_e = (_d = this.options) === null || _d === void 0 ? void 0 : _d.path) === null || _e === void 0 ? void 0 : _e.genres) + filters.genres + '/'; + } + else { + url += ((_g = (_f = this.options) === null || _f === void 0 ? void 0 : _f.path) === null || _g === void 0 ? void 0 : _g.novels) ? this.options.path.novels : MadaraDefaultPath.novels; + } + url += '/page/' + pageNo + '/' + + '?m_orderby=' + (showLatestNovels ? 'latest' : ((filters === null || filters === void 0 ? void 0 : filters.sort) || 'rating')); + return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })]; + case 1: + body = _h.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.manga-title-badges').remove(); + loadedCheerio('.page-item-detail').each(function () { + var novelName = loadedCheerio(this).find('.post-title').text().trim(); + var image = loadedCheerio(this).find('img'); + var novelCover = image.attr('data-src') || image.attr('src'); + var novelUrl = loadedCheerio(this).find('.post-title') + .find('a') + .attr('href') || ''; + var novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + novels.push(novel); + }); + return [2 /*return*/, novels]; + } + }); + }); + }; + MadaraPlugin.prototype.parseNovelAndChapters = function (novelUrl) { + var _a; + return __awaiter(this, void 0, void 0, function () { + var novel, body, loadedCheerio, html, novelId, formData, chapters; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + novel = { + url: novelUrl, + }; + return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl).then(function (res) { return res.text(); })]; + case 1: + body = _b.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.manga-title-badges, #manga-title span').remove(); + novel.name = + loadedCheerio('.post-title h1').text().trim() || + loadedCheerio('#manga-title h1').text(); + novel.cover = + loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || + loadedCheerio('.summary_image > a > img').attr('data-src') || + loadedCheerio('.summary_image > a > img').attr('src') || + defaultCover_1.defaultCover; + loadedCheerio('.post-content_item, .post-content').each(function () { + var detailName = loadedCheerio(this).find('h5').text().trim(); + var detail = loadedCheerio(this).find('.summary-content').text().trim(); + switch (detailName) { + case 'Genre(s)': + case 'التصنيفات': + novel.genres = detail.replace(/[\\t\\n]/g, ','); + break; + case 'Author(s)': + case 'المؤلف': + case 'المؤلف (ين)': + novel.author = detail; + break; + case 'Status': + case 'الحالة': + novel.status = + detail.includes('OnGoing') || detail.includes('مستمرة') + ? novelStatus_1.NovelStatus.Ongoing + : novelStatus_1.NovelStatus.Completed; + break; + } + }); + loadedCheerio('div.summary__content .code-block,script').remove(); + novel.summary = + loadedCheerio('div.summary__content').text().trim() || + loadedCheerio('#tab-manga-about').text().trim() || + loadedCheerio('.post-content_item h5:contains("Summary")').next().text().trim(); + if (!(((_a = this.options) === null || _a === void 0 ? void 0 : _a.useNewChapterEndpoint) !== true)) return [3 /*break*/, 3]; + novelId = loadedCheerio('.rating-post-id').attr('value') || + loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; + formData = new FormData(); + formData.append("action", "manga_get_chapters"); + formData.append("manga", novelId); + return [4 /*yield*/, (0, fetch_1.fetchApi)(this.site + 'wp-admin/admin-ajax.php', { + method: 'POST', + body: formData, + }) + .then(function (res) { return res.text(); })]; + case 2: + html = _b.sent(); + return [3 /*break*/, 5]; + case 3: return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl + 'ajax/chapters/', { method: 'POST' }) + .then(function (res) { return res.text(); })]; + case 4: + html = _b.sent(); + _b.label = 5; + case 5: + if (html !== '0') { + loadedCheerio = (0, cheerio_1.load)(html); + } + chapters = []; + loadedCheerio('.wp-manga-chapter').each(function () { + var chapterName = loadedCheerio(this).find('a').text().trim(); + var releaseDate = null; + releaseDate = loadedCheerio(this) + .find('span.chapter-release-date') + .text() + .trim(); + if (releaseDate) { + releaseDate = (0, parseMadaraDate_1.parseMadaraDate)(releaseDate); + } + else { + /** + * Insert current date + */ + releaseDate = (0, dayjs_1.default)().format('LL'); + } + var chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); + }); + novel.chapters = chapters.reverse(); + return [2 /*return*/, novel]; + } + }); + }); + }; + MadaraPlugin.prototype.parseChapter = function (chapterUrl) { + return __awaiter(this, void 0, void 0, function () { + var body, loadedCheerio, chapterText; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, (0, fetch_1.fetchApi)(chapterUrl).then(function (res) { return res.text(); })]; + case 1: + body = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + chapterText = loadedCheerio('.text-left').html() || + loadedCheerio('.text-right').html() || + loadedCheerio('.entry-content').html() || ""; + return [2 /*return*/, chapterText]; + } + }); + }); + }; + MadaraPlugin.prototype.searchNovels = function (searchTerm, pageNo) { + return __awaiter(this, void 0, void 0, function () { + var novels, url, body, loadedCheerio; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + novels = []; + url = this.site + "?s=" + searchTerm + "&post_type=wp-manga"; + return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })]; + case 1: + body = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.c-tabs-item__content').each(function () { + var novelName = loadedCheerio(this).find('.post-title').text().trim(); + var image = loadedCheerio(this).find('img'); + var novelCover = image.attr('data-src') || image.attr('src'); + var novelUrl = loadedCheerio(this) + .find('.post-title') + .find('a') + .attr('href') || ''; + var novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + novels.push(novel); + }); + return [2 /*return*/, novels]; + } + }); + }); + }; + MadaraPlugin.prototype.fetchImage = function (url) { + return __awaiter(this, void 0, void 0, function () { + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, (0, fetch_1.fetchFile)(url, {})]; + case 1: return [2 /*return*/, _a.sent()]; + } + }); + }); + }; + return MadaraPlugin; +}()); +var plugin = new MadaraPlugin({ "id": "morenovel", "sourceSite": "https://morenovel.net/", "sourceName": "MoreNovel", "filters": [{ "key": "sort", "label": "Order by", "values": [{ "label": "Rating", "value": "rating" }, { "label": "A-Z", "value": "alphabet" }, { "label": "Latest", "value": "latest" }, { "label": "Most Views", "value": "views" }, { "label": "New", "value": "new-manga" }, { "label": "Trending", "value": "trending" }], "inputType": "Picker" }, { "key": "genres", "label": "GENRES", "values": [{ "label": "Action", "value": "action" }, { "label": "Adventure", "value": "adventure" }, { "label": "Comedy", "value": "comedy" }, { "label": "Drama", "value": "drama" }, { "label": "Ecchi", "value": "ecchi" }, { "label": "Fantasy", "value": "fantasy" }, { "label": "Gender Bender", "value": "gender-bender" }, { "label": "Harem", "value": "harem" }, { "label": "Historical", "value": "historical" }, { "label": "Horror", "value": "horror" }, { "label": "Josei", "value": "josei" }, { "label": "Martial Arts", "value": "martial-arts" }, { "label": "Mature", "value": "mature" }, { "label": "Mecha", "value": "mecha" }, { "label": "Mystery", "value": "mystery" }, { "label": "Psychological", "value": "psychological" }, { "label": "Romance", "value": "romance" }, { "label": "School Life", "value": "school-life" }, { "label": "Sci-fi", "value": "sci-fi" }, { "label": "Seinen", "value": "seinen" }, { "label": "Shoujo", "value": "shoujo" }, { "label": "Shoujo Ai", "value": "shoujo-ai" }, { "label": "Shounen", "value": "shounen" }, { "label": "Shounen Ai", "value": "shounen-ai" }, { "label": "Slice of Life", "value": "slice-of-life" }, { "label": "Sports", "value": "sports" }, { "label": "Supernatural", "value": "supernatural" }, { "label": "Tragedy", "value": "tragedy" }, { "label": "Wuxia", "value": "wuxia" }, { "label": "Xianxia", "value": "xianxia" }, { "label": "Xuanhuan", "value": "xuanhuan" }, { "label": "Yaoi", "value": "yaoi" }, { "label": "Yuri", "value": "yuri" }], "inputType": "Picker" }], "options": { "useNewChapterEndpoint": true, "lang": "Indonesian" } }); +exports.default = plugin; diff --git a/.js/plugins/indonesian/WBNovel[madara].js b/.js/plugins/indonesian/WBNovel[madara].js new file mode 100644 index 0000000..405c815 --- /dev/null +++ b/.js/plugins/indonesian/WBNovel[madara].js @@ -0,0 +1,269 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __generator = (this && this.__generator) || function (thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (g && (g = 0, op[0] && (_ = 0)), _) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +}; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var fetch_1 = require("@libs/fetch"); +var cheerio_1 = require("cheerio"); +var defaultCover_1 = require("@libs/defaultCover"); +var novelStatus_1 = require("@libs/novelStatus"); +var parseMadaraDate_1 = require("@libs/parseMadaraDate"); +var dayjs_1 = __importDefault(require("dayjs")); +var MadaraDefaultPath = { + novels: 'novel', + novel: 'novel', + chapter: 'novel' +}; +var MadaraPlugin = /** @class */ (function () { + function MadaraPlugin(metadata) { + this.id = metadata.id; + this.name = metadata.sourceName + "[madara]"; + var iconFileName = metadata.sourceName.replace(/\s+/g, "").toLowerCase(); + this.icon = "multisrc/madara/icons/".concat(iconFileName, ".png"); + this.site = metadata.sourceSite; + this.version = "1.0.0"; + this.userAgent = ""; + this.cookieString = ""; + this.options = metadata.options; + this.filter = metadata.filters; + } + MadaraPlugin.prototype.popularNovels = function (pageNo, _a) { + var _b, _c, _d, _e, _f, _g; + var filters = _a.filters, showLatestNovels = _a.showLatestNovels; + return __awaiter(this, void 0, void 0, function () { + var novels, url, body, loadedCheerio; + return __generator(this, function (_h) { + switch (_h.label) { + case 0: + novels = []; + url = this.site; + if ((filters === null || filters === void 0 ? void 0 : filters.genres) && ((_c = (_b = this.options) === null || _b === void 0 ? void 0 : _b.path) === null || _c === void 0 ? void 0 : _c.genres)) { + url += ((_e = (_d = this.options) === null || _d === void 0 ? void 0 : _d.path) === null || _e === void 0 ? void 0 : _e.genres) + filters.genres + '/'; + } + else { + url += ((_g = (_f = this.options) === null || _f === void 0 ? void 0 : _f.path) === null || _g === void 0 ? void 0 : _g.novels) ? this.options.path.novels : MadaraDefaultPath.novels; + } + url += '/page/' + pageNo + '/' + + '?m_orderby=' + (showLatestNovels ? 'latest' : ((filters === null || filters === void 0 ? void 0 : filters.sort) || 'rating')); + return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })]; + case 1: + body = _h.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.manga-title-badges').remove(); + loadedCheerio('.page-item-detail').each(function () { + var novelName = loadedCheerio(this).find('.post-title').text().trim(); + var image = loadedCheerio(this).find('img'); + var novelCover = image.attr('data-src') || image.attr('src'); + var novelUrl = loadedCheerio(this).find('.post-title') + .find('a') + .attr('href') || ''; + var novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + novels.push(novel); + }); + return [2 /*return*/, novels]; + } + }); + }); + }; + MadaraPlugin.prototype.parseNovelAndChapters = function (novelUrl) { + var _a; + return __awaiter(this, void 0, void 0, function () { + var novel, body, loadedCheerio, html, novelId, formData, chapters; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + novel = { + url: novelUrl, + }; + return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl).then(function (res) { return res.text(); })]; + case 1: + body = _b.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.manga-title-badges, #manga-title span').remove(); + novel.name = + loadedCheerio('.post-title h1').text().trim() || + loadedCheerio('#manga-title h1').text(); + novel.cover = + loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || + loadedCheerio('.summary_image > a > img').attr('data-src') || + loadedCheerio('.summary_image > a > img').attr('src') || + defaultCover_1.defaultCover; + loadedCheerio('.post-content_item, .post-content').each(function () { + var detailName = loadedCheerio(this).find('h5').text().trim(); + var detail = loadedCheerio(this).find('.summary-content').text().trim(); + switch (detailName) { + case 'Genre(s)': + case 'التصنيفات': + novel.genres = detail.replace(/[\\t\\n]/g, ','); + break; + case 'Author(s)': + case 'المؤلف': + case 'المؤلف (ين)': + novel.author = detail; + break; + case 'Status': + case 'الحالة': + novel.status = + detail.includes('OnGoing') || detail.includes('مستمرة') + ? novelStatus_1.NovelStatus.Ongoing + : novelStatus_1.NovelStatus.Completed; + break; + } + }); + loadedCheerio('div.summary__content .code-block,script').remove(); + novel.summary = + loadedCheerio('div.summary__content').text().trim() || + loadedCheerio('#tab-manga-about').text().trim() || + loadedCheerio('.post-content_item h5:contains("Summary")').next().text().trim(); + if (!(((_a = this.options) === null || _a === void 0 ? void 0 : _a.useNewChapterEndpoint) !== true)) return [3 /*break*/, 3]; + novelId = loadedCheerio('.rating-post-id').attr('value') || + loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; + formData = new FormData(); + formData.append("action", "manga_get_chapters"); + formData.append("manga", novelId); + return [4 /*yield*/, (0, fetch_1.fetchApi)(this.site + 'wp-admin/admin-ajax.php', { + method: 'POST', + body: formData, + }) + .then(function (res) { return res.text(); })]; + case 2: + html = _b.sent(); + return [3 /*break*/, 5]; + case 3: return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl + 'ajax/chapters/', { method: 'POST' }) + .then(function (res) { return res.text(); })]; + case 4: + html = _b.sent(); + _b.label = 5; + case 5: + if (html !== '0') { + loadedCheerio = (0, cheerio_1.load)(html); + } + chapters = []; + loadedCheerio('.wp-manga-chapter').each(function () { + var chapterName = loadedCheerio(this).find('a').text().trim(); + var releaseDate = null; + releaseDate = loadedCheerio(this) + .find('span.chapter-release-date') + .text() + .trim(); + if (releaseDate) { + releaseDate = (0, parseMadaraDate_1.parseMadaraDate)(releaseDate); + } + else { + /** + * Insert current date + */ + releaseDate = (0, dayjs_1.default)().format('LL'); + } + var chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); + }); + novel.chapters = chapters.reverse(); + return [2 /*return*/, novel]; + } + }); + }); + }; + MadaraPlugin.prototype.parseChapter = function (chapterUrl) { + return __awaiter(this, void 0, void 0, function () { + var body, loadedCheerio, chapterText; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, (0, fetch_1.fetchApi)(chapterUrl).then(function (res) { return res.text(); })]; + case 1: + body = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + chapterText = loadedCheerio('.text-left').html() || + loadedCheerio('.text-right').html() || + loadedCheerio('.entry-content').html() || ""; + return [2 /*return*/, chapterText]; + } + }); + }); + }; + MadaraPlugin.prototype.searchNovels = function (searchTerm, pageNo) { + return __awaiter(this, void 0, void 0, function () { + var novels, url, body, loadedCheerio; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + novels = []; + url = this.site + "?s=" + searchTerm + "&post_type=wp-manga"; + return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })]; + case 1: + body = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.c-tabs-item__content').each(function () { + var novelName = loadedCheerio(this).find('.post-title').text().trim(); + var image = loadedCheerio(this).find('img'); + var novelCover = image.attr('data-src') || image.attr('src'); + var novelUrl = loadedCheerio(this) + .find('.post-title') + .find('a') + .attr('href') || ''; + var novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + novels.push(novel); + }); + return [2 /*return*/, novels]; + } + }); + }); + }; + MadaraPlugin.prototype.fetchImage = function (url) { + return __awaiter(this, void 0, void 0, function () { + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, (0, fetch_1.fetchFile)(url, {})]; + case 1: return [2 /*return*/, _a.sent()]; + } + }); + }); + }; + return MadaraPlugin; +}()); +var plugin = new MadaraPlugin({ "id": "wbnovel", "sourceSite": "https://wbnovel.com/", "sourceName": "WBNovel", "filters": [{ "key": "sort", "label": "Order by", "values": [{ "label": "Rating", "value": "rating" }, { "label": "A-Z", "value": "alphabet" }, { "label": "Latest", "value": "latest" }, { "label": "Most Views", "value": "views" }, { "label": "New", "value": "new-manga" }, { "label": "Trending", "value": "trending" }], "inputType": "Picker" }, { "key": "genres", "label": "GENRES", "values": [{ "label": "Action", "value": "action" }, { "label": "Adventure", "value": "adventure" }, { "label": "Alchemy", "value": "alchemy" }, { "label": "Comedy", "value": "comedy" }, { "label": "Crafting", "value": "crafting" }, { "label": "Cultivation", "value": "cultivation" }, { "label": "Drama", "value": "drama" }, { "label": "Dungeon Crawling", "value": "dungeon-crawling" }, { "label": "Eci", "value": "eci" }, { "label": "Fantasy", "value": "fantasy" }, { "label": "Game", "value": "game" }, { "label": "Harem", "value": "harem" }, { "label": "Horror", "value": "horror" }, { "label": "Josei", "value": "josei" }, { "label": "Kingdom Building", "value": "kingdom-building" }, { "label": "Martial Arts", "value": "martial-arts" }, { "label": "Mature", "value": "mature" }, { "label": "Mecha", "value": "mecha" }, { "label": "Modern Setting", "value": "modern-setting" }, { "label": "Mystery", "value": "mystery" }, { "label": "Pets", "value": "pets" }, { "label": "Psychological", "value": "psychological" }, { "label": "Reincarnator", "value": "reincarnator" }, { "label": "Romance", "value": "romance" }, { "label": "School Life", "value": "school-life" }, { "label": "Sci-fi", "value": "sci-fi" }, { "label": "Seinen", "value": "seinen" }, { "label": "Shounen", "value": "shounen" }, { "label": "Slice of Life", "value": "slice-of-life" }, { "label": "Sports", "value": "sports" }, { "label": "Supernatural", "value": "supernatural" }, { "label": "Tragedy", "value": "tragedy" }, { "label": "Transmigration", "value": "transmigration" }, { "label": "Virtual Reality", "value": "virtual-reality" }, { "label": "Wuxia", "value": "wuxia" }, { "label": "Xianxia", "value": "xianxia" }, { "label": "Xuanhuan", "value": "xuanhuan" }], "inputType": "Picker" }], "options": { "lang": "Indonesian" } }); +exports.default = plugin; diff --git a/.js/plugins/portuguese/lightnovelbrasil.js b/.js/plugins/portuguese/lightnovelbrasil.js new file mode 100644 index 0000000..33c26e5 --- /dev/null +++ b/.js/plugins/portuguese/lightnovelbrasil.js @@ -0,0 +1,378 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __generator = (this && this.__generator) || function (thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (g && (g = 0, op[0] && (_ = 0)), _) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var cheerio_1 = require("cheerio"); +var fetch_1 = require("@libs/fetch"); +var filterInputs_1 = require("@libs/filterInputs"); +var LightNovelBrasil = /** @class */ (function () { + function LightNovelBrasil() { + this.id = "lightnovelbrasil"; + this.name = "Light Novel Brasil"; + this.icon = "multisrc/wpmangastream/icons/lightnovelbrasil.png"; + this.site = "https://lightnovelbrasil.com/"; + this.version = "1.0.0"; + this.userAgent = ""; + this.cookieString = ""; + this.filters = [ + { + key: "order", + label: "Sort By", + values: [ + { label: "Default", value: "" }, + { label: "A-Z", value: "title" }, + { label: "Z-A", value: "titlereverse" }, + { label: "Latest Update", value: "update" }, + { label: "Latest Added", value: "latest" }, + { label: "Popular", value: "popular" }, + ], + inputType: filterInputs_1.FilterInputs.Picker, + }, + { + key: "status", + label: "Status", + values: [ + { label: "All", value: "" }, + { label: "Ongoing", value: "ongoing" }, + { label: "Hiatus", value: "hiatus" }, + { label: "Completed", value: "completed" }, + ], + inputType: filterInputs_1.FilterInputs.Picker, + }, + { + key: "type", + label: "Type", + values: [ + { label: "Chinese novel", value: "chinese-novel" }, + { label: "habyeol", value: "habyeol" }, + { label: "korean novel", value: "korean-novel" }, + { label: "Web Novel", value: "web-novel" }, + { label: "삼심", value: "%ec%82%bc%ec%8b%ac" }, + { label: "호곡", value: "%ed%98%b8%ea%b3%a1" }, + ], + inputType: filterInputs_1.FilterInputs.Checkbox, + }, + { + key: "genres", + label: "Genres", + values: [ + { label: "A.I", value: "a.i" }, + { label: "Academy", value: "academy" }, + { label: "Action", value: "action" }, + { label: "Adult", value: "adult" }, + { label: "Adventure", value: "adventure" }, + { label: "Alternative History", value: "alternative-history" }, + { label: "Another World", value: "another-world" }, + { label: "Apocalypse", value: "apocalypse" }, + { label: "Bromance", value: "bromance" }, + { label: "Comedy", value: "comedy" }, + { label: "Dark fantasy", value: "dark-fantasy" }, + { label: "Demons", value: "demons" }, + { label: "Drama", value: "drama" }, + { label: "Dystopia", value: "dystopia" }, + { label: "Ecchi", value: "ecchi" }, + { label: "Entertainment", value: "entertainment" }, + { label: "Exhaustion", value: "exhaustion" }, + { label: "Fanfiction", value: "fanfiction" }, + { label: "fantasy", value: "fantasy" }, + { label: "finance", value: "finance" }, + { label: "Full color", value: "full-color" }, + { label: "Game", value: "game" }, + { label: "Gender Bender", value: "gender-bender" }, + { label: "Genius", value: "genius" }, + { label: "Harem", value: "harem" }, + { label: "Hero", value: "hero" }, + { label: "Historical", value: "historical" }, + { label: "Hunter", value: "hunter" }, + { label: "korean novel", value: "korean-novel" }, + { label: "Light Novel", value: "light-novel" }, + { + label: "List Adventure Manga Genres", + value: "list-adventure-manga-genres", + }, + { label: "Long Strip", value: "long-strip" }, + { label: "Love comedy", value: "love-comedy" }, + { label: "magic", value: "magic" }, + { label: "Manhua", value: "manhua" }, + { label: "Martial Arts", value: "martial-arts" }, + { label: "Mature", value: "mature" }, + { label: "Medieval", value: "medieval" }, + { label: "Misunderstanding", value: "misunderstanding" }, + { label: "Modern", value: "modern" }, + { label: "modern fantasy", value: "modern-fantasy" }, + { label: "music", value: "music" }, + { label: "Mystery", value: "mystery" }, + { label: "Necromancy", value: "necromancy" }, + { label: "No Romance", value: "no-romance" }, + { label: "NTL", value: "ntl" }, + { label: "o", value: "o" }, + { label: "Obsession", value: "obsession" }, + { label: "Politics", value: "politics" }, + { label: "Possession", value: "possession" }, + { label: "Programming", value: "programming" }, + { label: "Psychological", value: "psychological" }, + { label: "Pure Love", value: "pure-love" }, + { label: "Redemption", value: "redemption" }, + { label: "Regression", value: "regression" }, + { label: "Regret", value: "regret" }, + { label: "Reincarnation", value: "reincarnation" }, + { label: "Revenge", value: "revenge" }, + { label: "Romance", value: "romance" }, + { label: "Romance Fanrasy", value: "romance-fanrasy" }, + { label: "Salvation", value: "salvation" }, + { label: "School Life", value: "school-life" }, + { label: "Sci-fi", value: "sci-fi" }, + { label: "Science fiction", value: "science-fiction" }, + { label: "Seinen", value: "seinen" }, + { label: "Shounen", value: "shounen" }, + { label: "Slice of Life", value: "slice-of-life" }, + { label: "Soft yandere", value: "soft-yandere" }, + { label: "Sports", value: "sports" }, + { label: "Supernatural", value: "supernatural" }, + { label: "Survival", value: "survival" }, + { label: "system", value: "system" }, + { label: "Time limit", value: "time-limit" }, + { label: "Tragedy", value: "tragedy" }, + { label: "Transmigration", value: "transmigration" }, + { label: "TS", value: "ts" }, + { label: "Tsundere", value: "tsundere" }, + { label: "Unique", value: "unique" }, + { label: "Wholesome", value: "wholesome" }, + { label: "Wuxia", value: "wuxia" }, + { label: "Xuanhuan", value: "xuanhuan" }, + { label: "Yandere", value: "yandere" }, + { label: "Yuri", value: "yuri" }, + ], + inputType: filterInputs_1.FilterInputs.Checkbox, + }, + ]; + } + LightNovelBrasil.prototype.popularNovels = function (pageNo, _a) { + var filters = _a.filters; + return __awaiter(this, void 0, void 0, function () { + var link, headers, body, loadedCheerio, novels; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + link = "".concat(this.site, "series/?page=").concat(pageNo); + if (filters) { + if (Array.isArray(filters.genres) && filters.genres.length) { + link += filters.genres.map(function (i) { return "&genre[]=".concat(i); }).join(""); + } + if (Array.isArray(filters.type) && filters.type.length) + link += filters.type.map(function (i) { return "&lang[]=".concat(i); }).join(""); + } + link += "&status=" + ((filters === null || filters === void 0 ? void 0 : filters.status) ? filters.status : ""); + link += "&order=" + ((filters === null || filters === void 0 ? void 0 : filters.order) ? filters.order : "popular"); + headers = new Headers(); + if (this.cookieString) { + headers.append("cookie", this.cookieString); + } + return [4 /*yield*/, (0, fetch_1.fetchApi)(link, { headers: headers }).then(function (result) { + return result.text(); + })]; + case 1: + body = _b.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + novels = []; + loadedCheerio("article.bs").each(function () { + var novelName = loadedCheerio(this).find(".ntitle").text().trim(); + var image = loadedCheerio(this).find("img"); + var novelCover = image.attr("data-src") || image.attr("src"); + var novelUrl = loadedCheerio(this).find("a").attr("href"); + if (!novelUrl) + return; + var novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + novels.push(novel); + }); + return [2 /*return*/, novels]; + } + }); + }); + }; + ; + LightNovelBrasil.prototype.parseNovelAndChapters = function (novelUrl) { + return __awaiter(this, void 0, void 0, function () { + var url, headers, result, body, loadedCheerio, novel, chapter; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + url = novelUrl; + headers = new Headers(); + if (this.cookieString) { + headers.append("cookie", this.cookieString); + } + return [4 /*yield*/, (0, fetch_1.fetchApi)(url, { headers: headers })]; + case 1: + result = _a.sent(); + return [4 /*yield*/, result.text()]; + case 2: + body = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + novel = { + url: url, + chapters: [], + }; + novel.name = loadedCheerio(".entry-title").text(); + novel.cover = + loadedCheerio("img.wp-post-image").attr("data-src") || + loadedCheerio("img.wp-post-image").attr("src"); + loadedCheerio("div.spe > span").each(function () { + var detailName = loadedCheerio(this).find("b").text().trim(); + var detail = loadedCheerio(this).find('b').remove().end().text().trim(); + switch (detailName) { + case "Autor:": + case "Author:": + novel.author = detail; + break; + case "Status:": + novel.status = detail; + break; + } + }); + novel.genres = loadedCheerio(".genxed") + .text() + .trim() + .replace(/\s/g, ","); + loadedCheerio('div[itemprop="description"] h3,p.a,strong').remove(); + novel.summary = loadedCheerio('div[itemprop="description"]') + .find("br") + .replaceWith("\n") + .end() + .text(); + chapter = []; + loadedCheerio(".eplister") + .find("li") + .each(function () { + var chapterName = loadedCheerio(this).find(".epl-num").text() + + " - " + + loadedCheerio(this).find(".epl-title").text(); + var releaseDate = loadedCheerio(this) + .find(".epl-date") + .text() + .trim(); + var chapterUrl = loadedCheerio(this).find("a").attr("href"); + if (!chapterUrl) + return; + chapter.push({ + name: chapterName, + releaseTime: releaseDate, + url: chapterUrl, + }); + }); + novel.chapters = chapter.reverse(); + return [2 /*return*/, novel]; + } + }); + }); + }; + LightNovelBrasil.prototype.parseChapter = function (chapterUrl) { + return __awaiter(this, void 0, void 0, function () { + var headers, result, body, loadedCheerio, chapterText; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + headers = new Headers(); + if (this.cookieString) { + headers.append("cookie", this.cookieString); + } + return [4 /*yield*/, (0, fetch_1.fetchApi)(chapterUrl, { headers: headers })]; + case 1: + result = _a.sent(); + return [4 /*yield*/, result.text()]; + case 2: + body = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + chapterText = loadedCheerio(".epcontent").html() || ""; + return [2 /*return*/, chapterText]; + } + }); + }); + }; + LightNovelBrasil.prototype.searchNovels = function (searchTerm, pageNo) { + return __awaiter(this, void 0, void 0, function () { + var url, headers, result, body, loadedCheerio, novels; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + url = "".concat(this.site, "?s=").concat(searchTerm); + headers = new Headers(); + if (this.cookieString) { + headers.append("cookie", this.cookieString); + } + return [4 /*yield*/, (0, fetch_1.fetchApi)(url, { headers: headers })]; + case 1: + result = _a.sent(); + return [4 /*yield*/, result.text()]; + case 2: + body = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + novels = []; + loadedCheerio("article.bs").each(function () { + var novelName = loadedCheerio(this).find(".ntitle").text().trim(); + var novelCover = loadedCheerio(this).find("img").attr("src"); + var novelUrl = loadedCheerio(this).find("a").attr("href"); + if (!novelUrl) + return; + novels.push({ + name: novelName, + url: novelUrl, + cover: novelCover, + }); + }); + return [2 /*return*/, novels]; + } + }); + }); + }; + LightNovelBrasil.prototype.fetchImage = function (url) { + return __awaiter(this, void 0, void 0, function () { + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, (0, fetch_1.fetchFile)(url)]; + case 1: return [2 /*return*/, _a.sent()]; + } + }); + }); + }; + return LightNovelBrasil; +}()); +exports.default = new LightNovelBrasil(); diff --git a/.js/plugins/spanish/tunovelaligera.js b/.js/plugins/spanish/tunovelaligera.js new file mode 100644 index 0000000..be932e5 --- /dev/null +++ b/.js/plugins/spanish/tunovelaligera.js @@ -0,0 +1,416 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __generator = (this && this.__generator) || function (thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (g && (g = 0, op[0] && (_ = 0)), _) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var cheerio_1 = require("cheerio"); +var fetch_1 = require("@libs/fetch"); +var filterInputs_1 = require("@libs/filterInputs"); +var showToast_1 = require("@libs/showToast"); +var defaultCover_1 = require("@libs/defaultCover"); +var novelStatus_1 = require("@libs/novelStatus"); +var TuNovelaLigera = /** @class */ (function () { + function TuNovelaLigera() { + this.id = "tunovelaligera"; + this.name = "TuNovelaLigera"; + this.icon = "src/es/tunovelaligera/icon.png"; + this.site = "https://tunovelaligera.com/"; + this.version = "1.0.0"; + this.userAgent = ""; + this.cookieString = ""; + this.filters = [ + { + key: "order", + label: "Ordenado por", + values: [ + { label: "Lo mas reciente", value: "?m_orderby=latest" }, + { label: "A-Z", value: "?m_orderby=alphabet" }, + { label: "Clasificación", value: "?m_orderby=rating" }, + { label: "Trending", value: "?m_orderby=trending" }, + { label: "Mas visto", value: "?m_orderby=views" }, + { label: "Nuevo", value: "?m_orderby=new-manga" }, + ], + inputType: filterInputs_1.FilterInputs.Picker, + }, + { + key: "genres", + label: "Generos", + values: [ + { label: "Acción", value: "accion" }, + { label: "Adulto", value: "adulto" }, + { label: "Artes Marciales", value: "artes-marciales" }, + { label: "Aventura", value: "aventura" }, + { label: "Ciencia Ficción", value: "ciencia-ficcion" }, + { label: "Comedia", value: "comedia" }, + { label: "Deportes", value: "deportes" }, + { label: "Drama", value: "drama" }, + { label: "Eastern Fantasy", value: "eastern-fantasy" }, + { label: "Ecchi", value: "ecchi" }, + { label: "FanFiction", value: "fan-fiction" }, + { label: "Fantasía", value: "fantasia" }, + { label: "Fantasía oriental", value: "fantasia-oriental" }, + { label: "Ficción Romántica", value: "ficcion-romantica" }, + { label: "Gender Bender", value: "gender-bender" }, + { label: "Harem", value: "harem" }, + { label: "Histórico", value: "historico" }, + { label: "Horror", value: "horror" }, + { label: "Josei", value: "josei" }, + { label: "Maduro", value: "maduro" }, + { label: "Mecha", value: "mecha" }, + { label: "Misterio", value: "misterio" }, + { label: "Novela China", value: "novela-china" }, + { label: "Novela FanFiction", value: "novela-fanfiction" }, + { label: "Novela Japonesa", value: "novela-japonesa" }, + { label: "Novela Koreana", value: "novela-koreana" }, + { label: "Novela ligera", value: "novela-ligera" }, + { label: "Novela original", value: "novela-original" }, + { label: "Novela Web", value: "web-novel" }, + { label: "Psicológico", value: "psicologico" }, + { label: "Realismo Mágico", value: "realismo-magico" }, + { label: "Recuento de vida", value: "recuento-de-vida" }, + { label: "Romance", value: "romance" }, + { label: "Romance contemporáneo", value: "romance-contemporaneo" }, + { label: "Romance Moderno", value: "romance-moderno" }, + { label: "Seinen", value: "seinen" }, + { label: "Shoujo", value: "shoujo" }, + { label: "Shounen", value: "shounen" }, + { label: "Sobrenatural", value: "sobrenatural" }, + { label: "Tragedia", value: "tragedia" }, + { label: "Vampiros", value: "vampiros" }, + { label: "Vida Escolar", value: "vida-escolar" }, + { label: "Western Fantasy", value: "western-fantasy" }, + { label: "Wuxia", value: "wuxia" }, + { label: "Xianxia", value: "xianxia" }, + { label: "Xuanhuan", value: "xuanhuan" }, + { label: "Yaoi", value: "yaoi" }, + ], + inputType: filterInputs_1.FilterInputs.Picker, + }, + ]; + } + TuNovelaLigera.prototype.popularNovels = function (pageNo, _a) { + var filters = _a.filters; + return __awaiter(this, void 0, void 0, function () { + var link, headers, result, body, loadedCheerio, novels; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + link = "".concat(this.site); + link += ((filters === null || filters === void 0 ? void 0 : filters.genres) ? "genero/" + filters.genres : "novelas"); + link += "/page/".concat(pageNo); + link += ((filters === null || filters === void 0 ? void 0 : filters.order) ? filters.order : "?m_orderby=rating"); + headers = new Headers(); + if (this.cookieString) { + headers.append("cookie", this.cookieString); + } + return [4 /*yield*/, (0, fetch_1.fetchApi)(link, { headers: headers })]; + case 1: + result = _b.sent(); + return [4 /*yield*/, result.text()]; + case 2: + body = _b.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + novels = []; + loadedCheerio(".page-item-detail").each(function (i, el) { + var novelName = loadedCheerio(el).find(".h5 > a").text(); + var novelCover = loadedCheerio(el).find("img").attr("src"); + var novelUrl = loadedCheerio(el).find(".h5 > a").attr("href"); + if (!novelUrl) + return; + var novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + novels.push(novel); + }); + return [2 /*return*/, novels]; + } + }); + }); + }; + ; + TuNovelaLigera.prototype.parseNovelAndChapters = function (novelUrl) { + return __awaiter(this, void 0, void 0, function () { + var url, headers, result, body, loadedCheerio, novel, novelCover, chapter, delay, lastPage, getChapters, getPageChapters, _a, _b; + var _this = this; + return __generator(this, function (_c) { + switch (_c.label) { + case 0: + url = novelUrl; + headers = new Headers(); + if (this.cookieString) { + headers.append("cookie", this.cookieString); + } + return [4 /*yield*/, (0, fetch_1.fetchApi)(url, { headers: headers })]; + case 1: + result = _c.sent(); + return [4 /*yield*/, result.text()]; + case 2: + body = _c.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + novel = { + url: url, + chapters: [], + }; + loadedCheerio(".manga-title-badges").remove(); + novel.name = loadedCheerio(".post-title > h1").text().trim(); + novelCover = loadedCheerio(".summary_image > a > img"); + novel.cover = + novelCover.attr("data-src") || + novelCover.attr("src") || + novelCover.attr('data-cfsrc') || + defaultCover_1.defaultCover; + loadedCheerio(".post-content_item").each(function () { + var detailName = loadedCheerio(this) + .find(".summary-heading > h5") + .text() + .trim(); + var detail = loadedCheerio(this) + .find(".summary-content") + .text() + .trim(); + switch (detailName) { + case "Generos": + novel.genres = detail.replace(/, /g, ","); + break; + case "Autores": + novel.author = detail; + break; + case "Estado": + novel.status = + detail.includes("OnGoing") || + detail.includes("Updating") + ? novelStatus_1.NovelStatus.Ongoing + : novelStatus_1.NovelStatus.Completed; + break; + } + }); + novel.summary = loadedCheerio("div.summary__content > p").text().trim(); + chapter = []; + delay = function (ms) { return new Promise(function (res) { return setTimeout(res, ms); }); }; + lastPage = 1; + lastPage = +loadedCheerio('.lcp_paginator li:last').prev().text(); + getChapters = function () { return __awaiter(_this, void 0, void 0, function () { + var n, novelName, formData, result, text; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + n = url.split('/'); + novelName = n[4]; + (0, showToast_1.showToast)('Cargando desde Archivo...'); + formData = new FormData(); + formData.append("action", "madara_load_more"); + formData.append("page", "0"); + formData.append("template", "html/loop/content"); + formData.append("vars[category_name]", novelName); + formData.append("vars[posts_per_page]", "10000"); + return [4 /*yield*/, (0, fetch_1.fetchApi)("".concat(this.site, "wp-admin/admin-ajax.php"), { + method: "POST", + body: formData, + headers: headers + })]; + case 1: + result = _a.sent(); + return [4 /*yield*/, result.text()]; + case 2: + text = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(text); + loadedCheerio('.heading').each(function (i, el) { + var chapterName = loadedCheerio(el) + .text() + .replace(/[\t\n]/g, '') + .trim(); + var releaseDate = null; + var chapterUrl = loadedCheerio(el).find('a').attr('href') || ""; + chapter.push({ + name: chapterName, + url: chapterUrl, + releaseTime: releaseDate, + }); + }); + return [2 /*return*/, chapter.reverse()]; + } + }); + }); }; + getPageChapters = function () { return __awaiter(_this, void 0, void 0, function () { + var _loop_1, i; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + _loop_1 = function (i) { + var chaptersUrl, result_1, chaptersHTML, chapterCheerio; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + chaptersUrl = "".concat(novelUrl, "?lcp_page0=").concat(i); + (0, showToast_1.showToast)("Cargando desde la p\u00E1gina ".concat(i, "/").concat(lastPage, "...")); + return [4 /*yield*/, (0, fetch_1.fetchApi)(chaptersUrl, { headers: headers })]; + case 1: + result_1 = _b.sent(); + return [4 /*yield*/, result_1.text()]; + case 2: + chaptersHTML = _b.sent(); + chapterCheerio = (0, cheerio_1.load)(chaptersHTML); + chapterCheerio('.lcp_catlist li').each(function (i, el) { + var chapterName = chapterCheerio(el) + .find('a') + .text() + .replace(/[\t\n]/g, '') + .trim(); + var releaseDate = chapterCheerio(el) + .find('span') + .text() + .trim(); + var chapterUrl = chapterCheerio(el).find('a').attr('href') || ""; + chapter.push({ + name: chapterName, + releaseTime: releaseDate, + url: chapterUrl, + }); + }); + return [4 /*yield*/, delay(1000)]; + case 3: + _b.sent(); + return [2 /*return*/]; + } + }); + }; + i = 1; + _a.label = 1; + case 1: + if (!(i <= lastPage)) return [3 /*break*/, 4]; + return [5 /*yield**/, _loop_1(i)]; + case 2: + _a.sent(); + _a.label = 3; + case 3: + i++; + return [3 /*break*/, 1]; + case 4: return [2 /*return*/, chapter.reverse()]; + } + }); + }); }; + _a = novel; + return [4 /*yield*/, getChapters()]; + case 3: + _a.chapters = _c.sent(); + if (!!novel.chapters.length) return [3 /*break*/, 6]; + (0, showToast_1.showToast)('¡Archivo no encontrado!'); + return [4 /*yield*/, delay(1000)]; + case 4: + _c.sent(); + _b = novel; + return [4 /*yield*/, getPageChapters()]; + case 5: + _b.chapters = _c.sent(); + _c.label = 6; + case 6: return [2 /*return*/, novel]; + } + }); + }); + }; + TuNovelaLigera.prototype.parseChapter = function (chapterUrl) { + return __awaiter(this, void 0, void 0, function () { + var headers, result, body, loadedCheerio, chapterText; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + headers = new Headers(); + if (this.cookieString) { + headers.append("cookie", this.cookieString); + } + return [4 /*yield*/, (0, fetch_1.fetchApi)(chapterUrl)]; + case 1: + result = _a.sent(); + return [4 /*yield*/, result.text()]; + case 2: + body = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio("#hola_siguiente").next().find('div').remove(); + chapterText = loadedCheerio("#hola_siguiente").next().html() || ""; + return [2 /*return*/, chapterText]; + } + }); + }); + }; + ; + TuNovelaLigera.prototype.searchNovels = function (searchTerm, pageNo) { + return __awaiter(this, void 0, void 0, function () { + var url, result, body, loadedCheerio, novels; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + url = "".concat(this.site, "?s=").concat(searchTerm, "&post_type=wp-manga"); + return [4 /*yield*/, (0, fetch_1.fetchApi)(url)]; + case 1: + result = _a.sent(); + return [4 /*yield*/, result.text()]; + case 2: + body = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + novels = []; + loadedCheerio(".c-tabs-item__content").each(function (i, el) { + var novelName = loadedCheerio(el).find(".h4 > a").text(); + var novelCover = loadedCheerio(el).find("img").attr("src"); + var novelUrl = loadedCheerio(el).find(".h4 > a").attr("href"); + if (!novelUrl) + return; + novels.push({ + name: novelName, + url: novelUrl, + cover: novelCover, + }); + }); + return [2 /*return*/, novels]; + } + }); + }); + }; + ; + TuNovelaLigera.prototype.fetchImage = function (url) { + return __awaiter(this, void 0, void 0, function () { + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, (0, fetch_1.fetchFile)(url)]; + case 1: return [2 /*return*/, _a.sent()]; + } + }); + }); + }; + return TuNovelaLigera; +}()); +exports.default = new TuNovelaLigera(); diff --git a/.js/plugins/turkish/TurkceLightNovels[madara].js b/.js/plugins/turkish/TurkceLightNovels[madara].js new file mode 100644 index 0000000..dc6ea8b --- /dev/null +++ b/.js/plugins/turkish/TurkceLightNovels[madara].js @@ -0,0 +1,269 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __generator = (this && this.__generator) || function (thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (g && (g = 0, op[0] && (_ = 0)), _) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +}; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var fetch_1 = require("@libs/fetch"); +var cheerio_1 = require("cheerio"); +var defaultCover_1 = require("@libs/defaultCover"); +var novelStatus_1 = require("@libs/novelStatus"); +var parseMadaraDate_1 = require("@libs/parseMadaraDate"); +var dayjs_1 = __importDefault(require("dayjs")); +var MadaraDefaultPath = { + novels: 'novel', + novel: 'novel', + chapter: 'novel' +}; +var MadaraPlugin = /** @class */ (function () { + function MadaraPlugin(metadata) { + this.id = metadata.id; + this.name = metadata.sourceName + "[madara]"; + var iconFileName = metadata.sourceName.replace(/\s+/g, "").toLowerCase(); + this.icon = "multisrc/madara/icons/".concat(iconFileName, ".png"); + this.site = metadata.sourceSite; + this.version = "1.0.0"; + this.userAgent = ""; + this.cookieString = ""; + this.options = metadata.options; + this.filter = metadata.filters; + } + MadaraPlugin.prototype.popularNovels = function (pageNo, _a) { + var _b, _c, _d, _e, _f, _g; + var filters = _a.filters, showLatestNovels = _a.showLatestNovels; + return __awaiter(this, void 0, void 0, function () { + var novels, url, body, loadedCheerio; + return __generator(this, function (_h) { + switch (_h.label) { + case 0: + novels = []; + url = this.site; + if ((filters === null || filters === void 0 ? void 0 : filters.genres) && ((_c = (_b = this.options) === null || _b === void 0 ? void 0 : _b.path) === null || _c === void 0 ? void 0 : _c.genres)) { + url += ((_e = (_d = this.options) === null || _d === void 0 ? void 0 : _d.path) === null || _e === void 0 ? void 0 : _e.genres) + filters.genres + '/'; + } + else { + url += ((_g = (_f = this.options) === null || _f === void 0 ? void 0 : _f.path) === null || _g === void 0 ? void 0 : _g.novels) ? this.options.path.novels : MadaraDefaultPath.novels; + } + url += '/page/' + pageNo + '/' + + '?m_orderby=' + (showLatestNovels ? 'latest' : ((filters === null || filters === void 0 ? void 0 : filters.sort) || 'rating')); + return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })]; + case 1: + body = _h.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.manga-title-badges').remove(); + loadedCheerio('.page-item-detail').each(function () { + var novelName = loadedCheerio(this).find('.post-title').text().trim(); + var image = loadedCheerio(this).find('img'); + var novelCover = image.attr('data-src') || image.attr('src'); + var novelUrl = loadedCheerio(this).find('.post-title') + .find('a') + .attr('href') || ''; + var novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + novels.push(novel); + }); + return [2 /*return*/, novels]; + } + }); + }); + }; + MadaraPlugin.prototype.parseNovelAndChapters = function (novelUrl) { + var _a; + return __awaiter(this, void 0, void 0, function () { + var novel, body, loadedCheerio, html, novelId, formData, chapters; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + novel = { + url: novelUrl, + }; + return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl).then(function (res) { return res.text(); })]; + case 1: + body = _b.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.manga-title-badges, #manga-title span').remove(); + novel.name = + loadedCheerio('.post-title h1').text().trim() || + loadedCheerio('#manga-title h1').text(); + novel.cover = + loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || + loadedCheerio('.summary_image > a > img').attr('data-src') || + loadedCheerio('.summary_image > a > img').attr('src') || + defaultCover_1.defaultCover; + loadedCheerio('.post-content_item, .post-content').each(function () { + var detailName = loadedCheerio(this).find('h5').text().trim(); + var detail = loadedCheerio(this).find('.summary-content').text().trim(); + switch (detailName) { + case 'Genre(s)': + case 'التصنيفات': + novel.genres = detail.replace(/[\\t\\n]/g, ','); + break; + case 'Author(s)': + case 'المؤلف': + case 'المؤلف (ين)': + novel.author = detail; + break; + case 'Status': + case 'الحالة': + novel.status = + detail.includes('OnGoing') || detail.includes('مستمرة') + ? novelStatus_1.NovelStatus.Ongoing + : novelStatus_1.NovelStatus.Completed; + break; + } + }); + loadedCheerio('div.summary__content .code-block,script').remove(); + novel.summary = + loadedCheerio('div.summary__content').text().trim() || + loadedCheerio('#tab-manga-about').text().trim() || + loadedCheerio('.post-content_item h5:contains("Summary")').next().text().trim(); + if (!(((_a = this.options) === null || _a === void 0 ? void 0 : _a.useNewChapterEndpoint) !== true)) return [3 /*break*/, 3]; + novelId = loadedCheerio('.rating-post-id').attr('value') || + loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; + formData = new FormData(); + formData.append("action", "manga_get_chapters"); + formData.append("manga", novelId); + return [4 /*yield*/, (0, fetch_1.fetchApi)(this.site + 'wp-admin/admin-ajax.php', { + method: 'POST', + body: formData, + }) + .then(function (res) { return res.text(); })]; + case 2: + html = _b.sent(); + return [3 /*break*/, 5]; + case 3: return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl + 'ajax/chapters/', { method: 'POST' }) + .then(function (res) { return res.text(); })]; + case 4: + html = _b.sent(); + _b.label = 5; + case 5: + if (html !== '0') { + loadedCheerio = (0, cheerio_1.load)(html); + } + chapters = []; + loadedCheerio('.wp-manga-chapter').each(function () { + var chapterName = loadedCheerio(this).find('a').text().trim(); + var releaseDate = null; + releaseDate = loadedCheerio(this) + .find('span.chapter-release-date') + .text() + .trim(); + if (releaseDate) { + releaseDate = (0, parseMadaraDate_1.parseMadaraDate)(releaseDate); + } + else { + /** + * Insert current date + */ + releaseDate = (0, dayjs_1.default)().format('LL'); + } + var chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); + }); + novel.chapters = chapters.reverse(); + return [2 /*return*/, novel]; + } + }); + }); + }; + MadaraPlugin.prototype.parseChapter = function (chapterUrl) { + return __awaiter(this, void 0, void 0, function () { + var body, loadedCheerio, chapterText; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, (0, fetch_1.fetchApi)(chapterUrl).then(function (res) { return res.text(); })]; + case 1: + body = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + chapterText = loadedCheerio('.text-left').html() || + loadedCheerio('.text-right').html() || + loadedCheerio('.entry-content').html() || ""; + return [2 /*return*/, chapterText]; + } + }); + }); + }; + MadaraPlugin.prototype.searchNovels = function (searchTerm, pageNo) { + return __awaiter(this, void 0, void 0, function () { + var novels, url, body, loadedCheerio; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + novels = []; + url = this.site + "?s=" + searchTerm + "&post_type=wp-manga"; + return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })]; + case 1: + body = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.c-tabs-item__content').each(function () { + var novelName = loadedCheerio(this).find('.post-title').text().trim(); + var image = loadedCheerio(this).find('img'); + var novelCover = image.attr('data-src') || image.attr('src'); + var novelUrl = loadedCheerio(this) + .find('.post-title') + .find('a') + .attr('href') || ''; + var novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + novels.push(novel); + }); + return [2 /*return*/, novels]; + } + }); + }); + }; + MadaraPlugin.prototype.fetchImage = function (url) { + return __awaiter(this, void 0, void 0, function () { + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, (0, fetch_1.fetchFile)(url, {})]; + case 1: return [2 /*return*/, _a.sent()]; + } + }); + }); + }; + return MadaraPlugin; +}()); +var plugin = new MadaraPlugin({ "id": "turkcelightnovels", "sourceSite": "https://turkcelightnovels.com/", "sourceName": "TurkceLightNovels", "filters": [{ "key": "sort", "label": "Order by", "values": [{ "label": "Rating", "value": "rating" }, { "label": "A-Z", "value": "alphabet" }, { "label": "Latest", "value": "latest" }, { "label": "Most Views", "value": "views" }, { "label": "New", "value": "new-manga" }, { "label": "Trending", "value": "trending" }], "inputType": "Picker" }], "options": { "path": { "novels": "light-novel", "novel": "light-novel", "chapter": "light-novel" }, "lang": "Turkish" } }); +exports.default = plugin; diff --git a/.js/plugins/turkish/WebNovelOku[madara].js b/.js/plugins/turkish/WebNovelOku[madara].js new file mode 100644 index 0000000..122c9c0 --- /dev/null +++ b/.js/plugins/turkish/WebNovelOku[madara].js @@ -0,0 +1,269 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __generator = (this && this.__generator) || function (thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (g && (g = 0, op[0] && (_ = 0)), _) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +}; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var fetch_1 = require("@libs/fetch"); +var cheerio_1 = require("cheerio"); +var defaultCover_1 = require("@libs/defaultCover"); +var novelStatus_1 = require("@libs/novelStatus"); +var parseMadaraDate_1 = require("@libs/parseMadaraDate"); +var dayjs_1 = __importDefault(require("dayjs")); +var MadaraDefaultPath = { + novels: 'novel', + novel: 'novel', + chapter: 'novel' +}; +var MadaraPlugin = /** @class */ (function () { + function MadaraPlugin(metadata) { + this.id = metadata.id; + this.name = metadata.sourceName + "[madara]"; + var iconFileName = metadata.sourceName.replace(/\s+/g, "").toLowerCase(); + this.icon = "multisrc/madara/icons/".concat(iconFileName, ".png"); + this.site = metadata.sourceSite; + this.version = "1.0.0"; + this.userAgent = ""; + this.cookieString = ""; + this.options = metadata.options; + this.filter = metadata.filters; + } + MadaraPlugin.prototype.popularNovels = function (pageNo, _a) { + var _b, _c, _d, _e, _f, _g; + var filters = _a.filters, showLatestNovels = _a.showLatestNovels; + return __awaiter(this, void 0, void 0, function () { + var novels, url, body, loadedCheerio; + return __generator(this, function (_h) { + switch (_h.label) { + case 0: + novels = []; + url = this.site; + if ((filters === null || filters === void 0 ? void 0 : filters.genres) && ((_c = (_b = this.options) === null || _b === void 0 ? void 0 : _b.path) === null || _c === void 0 ? void 0 : _c.genres)) { + url += ((_e = (_d = this.options) === null || _d === void 0 ? void 0 : _d.path) === null || _e === void 0 ? void 0 : _e.genres) + filters.genres + '/'; + } + else { + url += ((_g = (_f = this.options) === null || _f === void 0 ? void 0 : _f.path) === null || _g === void 0 ? void 0 : _g.novels) ? this.options.path.novels : MadaraDefaultPath.novels; + } + url += '/page/' + pageNo + '/' + + '?m_orderby=' + (showLatestNovels ? 'latest' : ((filters === null || filters === void 0 ? void 0 : filters.sort) || 'rating')); + return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })]; + case 1: + body = _h.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.manga-title-badges').remove(); + loadedCheerio('.page-item-detail').each(function () { + var novelName = loadedCheerio(this).find('.post-title').text().trim(); + var image = loadedCheerio(this).find('img'); + var novelCover = image.attr('data-src') || image.attr('src'); + var novelUrl = loadedCheerio(this).find('.post-title') + .find('a') + .attr('href') || ''; + var novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + novels.push(novel); + }); + return [2 /*return*/, novels]; + } + }); + }); + }; + MadaraPlugin.prototype.parseNovelAndChapters = function (novelUrl) { + var _a; + return __awaiter(this, void 0, void 0, function () { + var novel, body, loadedCheerio, html, novelId, formData, chapters; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + novel = { + url: novelUrl, + }; + return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl).then(function (res) { return res.text(); })]; + case 1: + body = _b.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.manga-title-badges, #manga-title span').remove(); + novel.name = + loadedCheerio('.post-title h1').text().trim() || + loadedCheerio('#manga-title h1').text(); + novel.cover = + loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || + loadedCheerio('.summary_image > a > img').attr('data-src') || + loadedCheerio('.summary_image > a > img').attr('src') || + defaultCover_1.defaultCover; + loadedCheerio('.post-content_item, .post-content').each(function () { + var detailName = loadedCheerio(this).find('h5').text().trim(); + var detail = loadedCheerio(this).find('.summary-content').text().trim(); + switch (detailName) { + case 'Genre(s)': + case 'التصنيفات': + novel.genres = detail.replace(/[\\t\\n]/g, ','); + break; + case 'Author(s)': + case 'المؤلف': + case 'المؤلف (ين)': + novel.author = detail; + break; + case 'Status': + case 'الحالة': + novel.status = + detail.includes('OnGoing') || detail.includes('مستمرة') + ? novelStatus_1.NovelStatus.Ongoing + : novelStatus_1.NovelStatus.Completed; + break; + } + }); + loadedCheerio('div.summary__content .code-block,script').remove(); + novel.summary = + loadedCheerio('div.summary__content').text().trim() || + loadedCheerio('#tab-manga-about').text().trim() || + loadedCheerio('.post-content_item h5:contains("Summary")').next().text().trim(); + if (!(((_a = this.options) === null || _a === void 0 ? void 0 : _a.useNewChapterEndpoint) !== true)) return [3 /*break*/, 3]; + novelId = loadedCheerio('.rating-post-id').attr('value') || + loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; + formData = new FormData(); + formData.append("action", "manga_get_chapters"); + formData.append("manga", novelId); + return [4 /*yield*/, (0, fetch_1.fetchApi)(this.site + 'wp-admin/admin-ajax.php', { + method: 'POST', + body: formData, + }) + .then(function (res) { return res.text(); })]; + case 2: + html = _b.sent(); + return [3 /*break*/, 5]; + case 3: return [4 /*yield*/, (0, fetch_1.fetchApi)(novelUrl + 'ajax/chapters/', { method: 'POST' }) + .then(function (res) { return res.text(); })]; + case 4: + html = _b.sent(); + _b.label = 5; + case 5: + if (html !== '0') { + loadedCheerio = (0, cheerio_1.load)(html); + } + chapters = []; + loadedCheerio('.wp-manga-chapter').each(function () { + var chapterName = loadedCheerio(this).find('a').text().trim(); + var releaseDate = null; + releaseDate = loadedCheerio(this) + .find('span.chapter-release-date') + .text() + .trim(); + if (releaseDate) { + releaseDate = (0, parseMadaraDate_1.parseMadaraDate)(releaseDate); + } + else { + /** + * Insert current date + */ + releaseDate = (0, dayjs_1.default)().format('LL'); + } + var chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); + }); + novel.chapters = chapters.reverse(); + return [2 /*return*/, novel]; + } + }); + }); + }; + MadaraPlugin.prototype.parseChapter = function (chapterUrl) { + return __awaiter(this, void 0, void 0, function () { + var body, loadedCheerio, chapterText; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, (0, fetch_1.fetchApi)(chapterUrl).then(function (res) { return res.text(); })]; + case 1: + body = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + chapterText = loadedCheerio('.text-left').html() || + loadedCheerio('.text-right').html() || + loadedCheerio('.entry-content').html() || ""; + return [2 /*return*/, chapterText]; + } + }); + }); + }; + MadaraPlugin.prototype.searchNovels = function (searchTerm, pageNo) { + return __awaiter(this, void 0, void 0, function () { + var novels, url, body, loadedCheerio; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + novels = []; + url = this.site + "?s=" + searchTerm + "&post_type=wp-manga"; + return [4 /*yield*/, (0, fetch_1.fetchApi)(url).then(function (res) { return res.text(); })]; + case 1: + body = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + loadedCheerio('.c-tabs-item__content').each(function () { + var novelName = loadedCheerio(this).find('.post-title').text().trim(); + var image = loadedCheerio(this).find('img'); + var novelCover = image.attr('data-src') || image.attr('src'); + var novelUrl = loadedCheerio(this) + .find('.post-title') + .find('a') + .attr('href') || ''; + var novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + novels.push(novel); + }); + return [2 /*return*/, novels]; + } + }); + }); + }; + MadaraPlugin.prototype.fetchImage = function (url) { + return __awaiter(this, void 0, void 0, function () { + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, (0, fetch_1.fetchFile)(url, {})]; + case 1: return [2 /*return*/, _a.sent()]; + } + }); + }); + }; + return MadaraPlugin; +}()); +var plugin = new MadaraPlugin({ "id": "webnoveloku", "sourceSite": "https://www.webnoveloku.com/", "sourceName": "WebNovelOku ", "filters": [{ "key": "sort", "label": "Sırala", "values": [{ "label": "A-Z", "value": "alphabet" }, { "label": "En Son", "value": "latest" }, { "label": "Görüntülenme", "value": "views" }, { "label": "Popülarite", "value": "trending" }, { "label": "Reyting", "value": "rating" }, { "label": "Yeni", "value": "new-manga" }], "inputType": "Picker" }], "options": { "lang": "Turkish" } }); +exports.default = plugin; diff --git a/.js/plugins/turkish/lshnovel.js b/.js/plugins/turkish/lshnovel.js new file mode 100644 index 0000000..21807e0 --- /dev/null +++ b/.js/plugins/turkish/lshnovel.js @@ -0,0 +1,324 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __generator = (this && this.__generator) || function (thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (g && (g = 0, op[0] && (_ = 0)), _) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var cheerio_1 = require("cheerio"); +var fetch_1 = require("@libs/fetch"); +var filterInputs_1 = require("@libs/filterInputs"); +var LSHNovel = /** @class */ (function () { + function LSHNovel() { + this.id = "lshnovel"; + this.name = "Liebe Schnee Hiver Novel"; + this.icon = "multisrc/wpmangastream/icons/lshnovel.png"; + this.site = "https://lshnovel.com/"; + this.version = "1.0.0"; + this.userAgent = ""; + this.cookieString = ""; + this.filters = [ + { + key: "order", + label: "Önerilen", + values: [ + { label: "Varsayılan", value: "" }, + { label: "A-Z", value: "title" }, + { label: "Z-A", value: "titlereverse" }, + { label: "Son Yüklemeler", value: "update" }, + { label: "Son Eklenenler", value: "latest" }, + { label: "Bestimiz", value: "popular" }, + ], + inputType: filterInputs_1.FilterInputs.Picker, + }, + { + key: "status", + label: "Statü", + values: [ + { label: "Tümü", value: "" }, + { label: "Ongoing", value: "ongoing" }, + { label: "Hiatus", value: "hiatus" }, + { label: "Completed", value: "completed" }, + ], + inputType: filterInputs_1.FilterInputs.Picker, + }, + { + key: "type", + label: "Tür", + values: [ + { label: "Çeviri Novel", value: "ceviri-novel" }, + { label: "Liz-Chan", value: "liz-chan" }, + { label: "Manhwa", value: "manhwa" }, + { label: "Orijinal Novel", value: "orijinal-novel" }, + { label: "Web Novel", value: "web-novel" }, + ], + inputType: filterInputs_1.FilterInputs.Checkbox, + }, + { + key: "genres", + label: "Kategori", + values: [ + { label: "+18", value: "18" }, + { label: "Action", value: "action" }, + { label: "Adult", value: "adult" }, + { label: "Aksiyon", value: "aksiyon" }, + { label: "BL", value: "bl" }, + { label: "Comedy", value: "comedy" }, + { label: "Doğaüstü", value: "dogaustu" }, + { label: "Dram", value: "dram" }, + { label: "Drama", value: "drama" }, + { label: "Ecchi", value: "ecchi" }, + { label: "Fantastik", value: "fantastik" }, + { label: "Fantasy", value: "fantasy" }, + { label: "Gizem", value: "gizem" }, + { label: "Harem", value: "harem" }, + { label: "Historical", value: "historical" }, + { label: "Josei", value: "josei" }, + { label: "Macera", value: "macera" }, + { label: "Manhwa", value: "manhwa" }, + { label: "Martial Arts", value: "martial-arts" }, + { label: "Mature", value: "mature" }, + { label: "Novel", value: "novel" }, + { label: "Okul", value: "okul" }, + { label: "Psikolojik", value: "psikolojik" }, + { label: "Psychological", value: "psychological" }, + { label: "Reverse Harem", value: "reverse-harem" }, + { label: "Romance", value: "romance" }, + { label: "Romantik", value: "romantik" }, + { label: "Shoujo", value: "shoujo" }, + { label: "Slice Of Life", value: "slice-of-life" }, + { label: "Smut", value: "smut" }, + { label: "Supernatural", value: "supernatural" }, + { label: "Tarihi", value: "tarihi" }, + { label: "Tragedy", value: "tragedy" }, + { label: "Yaoi", value: "yaoi" }, + ], + inputType: filterInputs_1.FilterInputs.Checkbox, + }, + ]; + } + LSHNovel.prototype.popularNovels = function (pageNo, _a) { + var filters = _a.filters; + return __awaiter(this, void 0, void 0, function () { + var link, headers, body, loadedCheerio, novels; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + link = "".concat(this.site, "series/?page=").concat(pageNo); + if (filters) { + if (Array.isArray(filters.genres) && filters.genres.length) { + link += filters.genres.map(function (i) { return "&genre[]=".concat(i); }).join(""); + } + if (Array.isArray(filters.type) && filters.type.length) + link += filters.type.map(function (i) { return "&lang[]=".concat(i); }).join(""); + } + link += "&status=" + ((filters === null || filters === void 0 ? void 0 : filters.status) ? filters.status : ""); + link += "&order=" + ((filters === null || filters === void 0 ? void 0 : filters.order) ? filters.order : "popular"); + headers = new Headers(); + if (this.cookieString) { + headers.append("cookie", this.cookieString); + } + return [4 /*yield*/, (0, fetch_1.fetchApi)(link, { headers: headers }).then(function (result) { + return result.text(); + })]; + case 1: + body = _b.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + novels = []; + loadedCheerio("article.bs").each(function () { + var novelName = loadedCheerio(this).find(".ntitle").text().trim(); + var image = loadedCheerio(this).find("img"); + var novelCover = image.attr("data-src") || image.attr("src"); + var novelUrl = loadedCheerio(this).find("a").attr("href"); + if (!novelUrl) + return; + var novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + novels.push(novel); + }); + return [2 /*return*/, novels]; + } + }); + }); + }; + ; + LSHNovel.prototype.parseNovelAndChapters = function (novelUrl) { + return __awaiter(this, void 0, void 0, function () { + var url, headers, result, body, loadedCheerio, novel, chapter; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + url = novelUrl; + headers = new Headers(); + if (this.cookieString) { + headers.append("cookie", this.cookieString); + } + return [4 /*yield*/, (0, fetch_1.fetchApi)(url, { headers: headers })]; + case 1: + result = _a.sent(); + return [4 /*yield*/, result.text()]; + case 2: + body = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + novel = { + url: url, + chapters: [], + }; + novel.name = loadedCheerio(".entry-title").text(); + novel.cover = + loadedCheerio("img.wp-post-image").attr("data-src") || + loadedCheerio("img.wp-post-image").attr("src"); + loadedCheerio("div.spe > span").each(function () { + var detailName = loadedCheerio(this).find("b").text().trim(); + var detail = loadedCheerio(this).find('b').remove().end().text().trim(); + switch (detailName) { + case "Yazar:": + novel.author = detail; + break; + case "Seviye:": + novel.status = detail; + break; + } + }); + novel.genres = loadedCheerio(".genxed") + .text() + .trim() + .replace(/\s/g, ","); + loadedCheerio('div[itemprop="description"] h3,p.a,strong').remove(); + novel.summary = loadedCheerio('div[itemprop="description"]') + .find("br") + .replaceWith("\n") + .end() + .text(); + chapter = []; + loadedCheerio(".eplister") + .find("li") + .each(function () { + var chapterName = loadedCheerio(this).find(".epl-num").text() + + " - " + + loadedCheerio(this).find(".epl-title").text(); + var releaseDate = loadedCheerio(this) + .find(".epl-date") + .text() + .trim(); + var chapterUrl = loadedCheerio(this).find("a").attr("href"); + if (!chapterUrl) + return; + chapter.push({ + name: chapterName, + releaseTime: releaseDate, + url: chapterUrl, + }); + }); + novel.chapters = chapter.reverse(); + return [2 /*return*/, novel]; + } + }); + }); + }; + LSHNovel.prototype.parseChapter = function (chapterUrl) { + return __awaiter(this, void 0, void 0, function () { + var headers, result, body, loadedCheerio, chapterText; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + headers = new Headers(); + if (this.cookieString) { + headers.append("cookie", this.cookieString); + } + return [4 /*yield*/, (0, fetch_1.fetchApi)(chapterUrl, { headers: headers })]; + case 1: + result = _a.sent(); + return [4 /*yield*/, result.text()]; + case 2: + body = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + chapterText = loadedCheerio(".epcontent").html() || ""; + return [2 /*return*/, chapterText]; + } + }); + }); + }; + LSHNovel.prototype.searchNovels = function (searchTerm, pageNo) { + return __awaiter(this, void 0, void 0, function () { + var url, headers, result, body, loadedCheerio, novels; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + url = "".concat(this.site, "?s=").concat(searchTerm); + headers = new Headers(); + if (this.cookieString) { + headers.append("cookie", this.cookieString); + } + return [4 /*yield*/, (0, fetch_1.fetchApi)(url, { headers: headers })]; + case 1: + result = _a.sent(); + return [4 /*yield*/, result.text()]; + case 2: + body = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + novels = []; + loadedCheerio("article.bs").each(function () { + var novelName = loadedCheerio(this).find(".ntitle").text().trim(); + var novelCover = loadedCheerio(this).find("img").attr("src"); + var novelUrl = loadedCheerio(this).find("a").attr("href"); + if (!novelUrl) + return; + novels.push({ + name: novelName, + url: novelUrl, + cover: novelCover, + }); + }); + return [2 /*return*/, novels]; + } + }); + }); + }; + LSHNovel.prototype.fetchImage = function (url) { + return __awaiter(this, void 0, void 0, function () { + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, (0, fetch_1.fetchFile)(url)]; + case 1: return [2 /*return*/, _a.sent()]; + } + }); + }); + }; + return LSHNovel; +}()); +exports.default = new LSHNovel(); diff --git a/.js/plugins/vietnamese/LNHako.js b/.js/plugins/vietnamese/LNHako.js new file mode 100644 index 0000000..2133d02 --- /dev/null +++ b/.js/plugins/vietnamese/LNHako.js @@ -0,0 +1,219 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __generator = (this && this.__generator) || function (thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (g && (g = 0, op[0] && (_ = 0)), _) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var cheerio_1 = require("cheerio"); +var fetch_1 = require("@libs/fetch"); +var isAbsoluteUrl_1 = require("@libs/isAbsoluteUrl"); +var HakoPlugin = /** @class */ (function () { + function HakoPlugin() { + this.id = "ln.hako"; + this.name = "Hako"; + this.icon = "src/vi/hakolightnovel/icon.png"; + this.site = "https://ln.hako.vn"; + this.version = "1.0.0"; + this.userAgent = ""; + this.cookieString = ""; + } + HakoPlugin.prototype.parseNovels = function (loadedCheerio) { + var _this = this; + var novels = []; + loadedCheerio(".row > .thumb-item-flow").each(function (index, ele) { + var url = loadedCheerio(ele) + .find("div.thumb_attr.series-title > a") + .attr("href"); + if (url && !(0, isAbsoluteUrl_1.isUrlAbsolute)(url)) { + url = _this.site + url; + } + if (url) { + var name_1 = loadedCheerio(ele) + .find(".series-title") + .text() + .trim(); + var cover = loadedCheerio(ele) + .find(".img-in-ratio") + .attr("data-bg"); + if (cover && !(0, isAbsoluteUrl_1.isUrlAbsolute)(cover)) { + cover = _this.site + cover; + } + var novel = { name: name_1, url: url, cover: cover }; + novels.push(novel); + } + }); + return novels; + }; + HakoPlugin.prototype.popularNovels = function (pageNo, options) { + return __awaiter(this, void 0, void 0, function () { + var link, result, body, loadedCheerio; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + link = this.site + "/danh-sach?truyendich=1&sapxep=topthang&page=" + pageNo; + return [4 /*yield*/, fetch(link)]; + case 1: + result = _a.sent(); + return [4 /*yield*/, result.text()]; + case 2: + body = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + return [2 /*return*/, this.parseNovels(loadedCheerio)]; + } + }); + }); + }; + HakoPlugin.prototype.parseNovelAndChapters = function (novelUrl) { + return __awaiter(this, void 0, void 0, function () { + var novel, result, body, loadedCheerio, background, novelCover, chapters; + var _this = this; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + novel = { + url: novelUrl, + }; + return [4 /*yield*/, fetch(novelUrl)]; + case 1: + result = _a.sent(); + return [4 /*yield*/, result.text()]; + case 2: + body = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + novel.name = loadedCheerio(".series-name").text(); + background = loadedCheerio(".series-cover > .a6-ratio > div").attr("style") || ""; + novelCover = background.substring(background.indexOf("http"), background.length - 2); + novel.cover = novelCover + ? (0, isAbsoluteUrl_1.isUrlAbsolute)(novelCover) + ? novelCover + : this.site + novelCover + : ""; + novel.summary = loadedCheerio(".summary-content").text().trim(); + novel.author = loadedCheerio("#mainpart > div:nth-child(2) > div > div:nth-child(1) > section > main > div.top-part > div > div.col-12.col-md-9 > div.series-information > div:nth-child(2) > span.info-value > a") + .text() + .trim(); + novel.genres = loadedCheerio(".series-gernes") + .text() + .trim() + .replace(/ +/g, " ") + .split("\n") + .filter(function (e) { return e.trim(); }) + .join(", "); + novel.status = loadedCheerio("#mainpart > div:nth-child(2) > div > div:nth-child(1) > section > main > div.top-part > div > div.col-12.col-md-9 > div.series-information > div:nth-child(4) > span.info-value > a") + .text() + .trim(); + chapters = []; + loadedCheerio(".list-chapters li").each(function (index, ele) { + var chapterUrl = loadedCheerio(ele).find("a").attr("href"); + if (chapterUrl && !(0, isAbsoluteUrl_1.isUrlAbsolute)(chapterUrl)) { + chapterUrl = _this.site + chapterUrl; + } + if (chapterUrl) { + var chapterName = loadedCheerio(ele) + .find(".chapter-name") + .text() + .trim(); + var releaseTime = loadedCheerio(ele) + .find(".chapter-time") + .text(); + var chapter = { + name: chapterName, + releaseTime: releaseTime, + url: chapterUrl, + }; + chapters.push(chapter); + } + }); + novel.chapters = chapters; + return [2 /*return*/, novel]; + } + }); + }); + }; + HakoPlugin.prototype.parseChapter = function (chapterUrl) { + return __awaiter(this, void 0, void 0, function () { + var result, body, loadedCheerio, chapterText; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, fetch(chapterUrl)]; + case 1: + result = _a.sent(); + return [4 /*yield*/, result.text()]; + case 2: + body = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + chapterText = loadedCheerio("#chapter-content").html() || ""; + return [2 /*return*/, chapterText]; + } + }); + }); + }; + HakoPlugin.prototype.searchNovels = function (searchTerm, pageNo) { + return __awaiter(this, void 0, void 0, function () { + var url, result, body, loadedCheerio; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + url = this.site + "/tim-kiem?keywords=" + searchTerm; + return [4 /*yield*/, fetch(url)]; + case 1: + result = _a.sent(); + return [4 /*yield*/, result.text()]; + case 2: + body = _a.sent(); + loadedCheerio = (0, cheerio_1.load)(body); + return [2 /*return*/, this.parseNovels(loadedCheerio)]; + } + }); + }); + }; + HakoPlugin.prototype.fetchImage = function (url) { + return __awaiter(this, void 0, void 0, function () { + var headers; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + headers = { + Referer: "https://ln.hako.vn", + }; + return [4 /*yield*/, (0, fetch_1.fetchFile)(url, { headers: headers })]; + case 1: return [2 /*return*/, _a.sent()]; + } + }); + }); + }; + return HakoPlugin; +}()); +exports.default = new HakoPlugin(); diff --git a/README.md b/README.md index c070119..5a73cd8 100644 --- a/README.md +++ b/README.md @@ -11,16 +11,15 @@

Repository to host plugins and related issues, and requests for [LNReader](https://github.com/LNReader/lnreader). +## Prerequisites +- Nodejs >= 18 +## Contributing -## Contributing - -1. Please use this [template](./template.ts) or [template.min](./template.min.ts) - -2. Choose your language in [./plugins](./plugins) +1. Choose your language in [plugins/](./plugins) + If your language doenst exist or you need some other packages, please request us. We will add it soon. -3. Write your scripts +2. Write your scripts + See example: [Hako](./plugins/vietnamese/LNHako.ts) diff --git a/icons/src/cn/linovelib/icon.png b/icons/src/cn/linovelib/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..ee97ed6db787ce231fa6b8fb8764d70aa9f96f0b GIT binary patch literal 1053342 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 z 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%0A7bNr2?=WVE1b$4#Z9y4yr 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%0D=~>?U1Mdk{zgs0F?kApVCkSU_PE8 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%0A#=V zqiI^P_lR*rW}?w5Hv!W*0)Qxb5da?X0FbGkA3zojP@@5G2Q*S}&l&7t1yE!!^9Gnu zqXQWCZwdlyUH~f&z!m`zeq)X|hX-0N0c%@E1=v7vn4<&CIRebs02wkUaRY7(Kud-O ziaVea0^kt@z>58wXk`m&c|9!v{1#UPfb~dRNvf;?>$TGQy2|5Zhdx%5KRl{>_(J$X z_QcbvcRY_&-g$ZVr45j_U?-3szYzaAunY+C&j2#!KL@0OVIU5O-~Ti4A&_3b_WeIi z{t<8&=n1-mPM{@d$_+LGSA$yIWHk`Udk_wS5deV*0Do@U7t@65^|S3d$3g%n)!M(? zX@gnJh1K5tLjqj^5(7YwU(En00f4meZgamw1V}j?^=lzq_)F(_60e(B?HD^J|7aq% z$~=UClzHv9IZVnm^!4<%M_LtU%lVb;<6Ms~sK2nPNOsDX*CeiP#^b}xn^MPcQ|7Vm z<2}`r`v=h1^W0xmMay~mTxY7wJ zoFaH7kNh!koIpXDLqKK|JVBg*OeK6Kkc9_=*BJ-HzF$7G+Ee3mYu+|0t#0?6AWP4F{yE{HBXIuyJ^b64-f!f zHccMbr&;o#xMsr#4sV_^D7$6yz_IO9hfKaRXT+Y6AgtLk(6x!hfD% z2>{{&?0`Tl0j#|%P~?vbKm`R_0%mN0IinyW2Hfreb26cDW)u`RKvXc0 zHHe7`5UW54(^6K)UC=Bb+V#R)FJKke1M%-AJ&h>H1IL*|-~_IM6Icn3`y4P%`Z1RP z^Io4|1&rgtTgwlGkK4Vr+RNElHSf>Ls&~i8>?Sv*CbqmjC$(M2?4j4T88NIU!|3j8 znKSr)%;%4`OdIrUOmf^`o2Lx?d()%=|7@B(;NMLW2mGh$@VM`q4jnikdia3EmWhM1 zx}+tJesxsVg(Q@pAf(F{P%-BK;C(I_oeqQZNX}=3@ie3z$7pRWP>CS z2fhbif{($!!0X@@@MrJ@cnI7JZU@(cP9PSFH-uGASnx~^^*LkFyu%Rii6KBEBwq#b8;mzn^G&Yc7RRwVz5 zWDUot6@VP6B4;=ERC-PY?sFb*^Pupa<{Cx#=C&q#ovP#Q<1|k>&b4^TgUc*V^(@nz zDEI8no5u(T3rwzb=XJT6Uh<1Mzog{#7u9()wZ4Gk!}NLb;rdveH}~nAl~f<2%P!{! z(8oGc$?JR3mFg(7E8MaMh(*A(3RnUlKv@R#OoH-oscD6A3xtReAQgyvAS{>|0mxqo z0o()C87Uz7NUR1m!m6=cRb5xgwBc9)_CflG@ME3DLU0lnK_1&;9XN`W;21Mqong#t zfnOf$3mh?yhaNUgM$9<=Q?+;JPOSa6`9C)N>-3S$o}D?m)t$Mi9lB?xT;DM>p(hIf z-N9V+_r|0Rc(i$9|EFV;2D}hGyx+^shWCA|>9Bt9HyJwM<7Pt#eif6{e?Y6G!9%;I zrKG;SZcXmOvu7q8D=nT*%P<>4UI3N@dFe&%h!sFXh6ieh2xz1Q zfYTbF@*)7NKtLgXEdZ=kTLY9O0QZ2l2wcN{B?=G*Hu)n8WR3un_;u9oSiX?Y$3HJEi?_DsvBK@Y+m`hQUkxG2ILWPlD|A=-sCUD zzZ+=cmv>&?eQ5)hg9Ts?m<}d_5g-i=0|SBd`ac05fVYA4`d{x^haC(w}Bf$ z7yN>4Nn3y>Jo5D*e(CvFKXdV9Gqp&HM5td`gWX1VE|lKyjXn zV_n}QeCzV_iJ}dz;qndfbp;0F24MbwX`4;|zuDFc`HLuUivV~;ZJT@|+-32ShX8Pt z+gzmi>vB?0vb8wU<{H!YFT`IN`8&%i?AKf-*Ai~ksYhP+X%4i%pZcEqdztrVT|=&^ zcv|k$%{MUaSvk%R@hmqh#9gLuR;O~)&b;TBaGzIIxjt7?6YhKA3sPyeD3A*D zfbABrEda_Ipr#X+DTRRy9n|pw${Jt_fv^w}0b$AwAVMHY<`Q6%3Yl^^I1Ebwa|cAa z>bX7|@NZWk0^k^yfMcvQxZl`C?|%nEU_U}YrW!sd`~K zKHM~+Pw%F~`~JD<(7u0bGNkY8F~bJF+dQ$~r>%z%`}X$S5&iq@-jOgf?^ycblA;k8 z3F_fRn*?To`MhL{fiwVX*%mj!79c`kA5fM6UThgba2{w8;B*amkU!^m{K+=w*(gWe z%irUviAJZK!Az}d2>{67EdV4a&0eN%;@+irhC6ARnUc}L9rz5q2i^oi{C@#Yfya1$AL0h? zohKUD|Z>&mNiJ z$L;#^Cb&u%T3yWIKj#Si+r{Xr8}I4G>VJ_;02JZ!4~6{2>@Vhi0=d-$K+?Wf36nG{ z;SgH@usEIMFPr2hJY-JBXO@}A*(7hDZ*i6)ZSyna z9-JKKyr;_Y?qkjKypQ>fUtWmSU2(cHq)a|gr@C^S$Lf8a#P4}M&*Q!K>1}5!`HHZA z4Eb@qE7jVTxB!$SB0wO)B_?Ff0Br>jA)v$nB0#JGGLvAKj2yu1FR=iUhO-@xSdf_p zLqhx+HW;eaP!DaNoNl*a96;K4k5@5RmIL<=^ zuxbCvK904?PKE(py#oY6iz-e49(TmV=A7*pR|FBwcsfW1C z<=t)o)$>OHG}3^?B{slz2e2)10cznOB?P{)311VxopPQTBOs(NV&HqDG1nEc7vfi= z2CUSaJ3!V9KmZUB*giGhxF-+2oNj4E+A(A^+0<6%YYUE(jG|fe-y|9DIfvJkiRd%$3Xo4e+ME0 zo&&vs5&_)6oxJO}vfYD#p=(Qx(oSVYN!v3Q_Qp(_n9}&&fBvn(z4zQ(r_t5dR0|6V z4-b!s3JoDA-Q$Sr)qNvEtNYYz(8%ZZyYFz_`M_PSUXR@Gs?)TE%O@bh73LS_3a%dN z@(Fa|mc{hXJOHu;u(a7C45}6a@B&S%nhDUsSr*6GVu0;R#DH*$o70@Uq&d&zI5`Fg zr>Nu2bKIO`?Xx&Xmuo?wQ#rSSAkgP1fl*Nqn4f3fr~CfAx1C(=-Y4g}&mkV5+GnRf z^(b-fy;R=K`c_R?wNTkPT9SAw0M9$Q^gi!n^|t$)Ri*}Xnf`oR9q1aiQ`?j>L0+<$j{>+%&M26{=q?^0pWhZe$^wQ!s}EEt5HA171+2*)21!% zdF`1ti;bi0laKH0+&#H(_l~Jw-_&UESGP2c|Mt#n27d8C%-|m$Z5`k5$&SN^y>Q2< zF@Jw`>GHQf`FYca19$KI&$z>f`|iG27!Ml_=gm#ytsP1FBdK%+W`c!mD?b70PhdN5 z_g-)a;3EZBPWPFs9iaFo{ zMp`VO)CHdZ9=zmTPaB0D z=Pa4tu4Szjt-@V3n+3SS8ioc&)(Z{@trZd!8tEGl80L~dY=6JNK)(P#)_C^~3Jj(o z%;oO`t25YNqWeM^>@TL(z%bfI#sNx?%U{@1wZk0a2mlavb*g~?objIQ@8k*19haXv zSyS>AAUvXboO-|F7N-i(OfQV?EH@e6Rs=RDY37$}TgN*-!{ph@znA7aZ!UIz59hvL zEdb;LoELC@pmU$j>(qIUGw-=yUt3a*%l)w`o-5ZjudlCVrdpDjX@wvGMgBaTZZV+D z1D2`45&%jVP;O2=XbJ=+3dBqRWZuf)5Uw4J9SeaVwyZ!I*MhkqK*qBuyOt$q5dv(p z>?PltMKAd;l>bKshXmFP3Ja(k77^N@c4W<_k-;@%n#MM7_17={8vAzk7oB>1@t3ZR z-g~8c^cNr9*flNb_RjGMcRx6K+yk#JSoqjS8-ITOI5E zvjAE9Ps%w~2>?|{!T6tkHo74IS~EppEF{?me?TjO0`wAsO^FIr!2x=BK(aMupa=l* z2>`uVfTSV<#5`c8=GZ_F0ia9(mKgxDSLOkTUIz-8a|gT40@vV65K*AOai)2|B7G|& zPy~RGznXDKA_=_&fXpAB0PsEd4|pGl58!X$ z1@Jg{kPp5W^a3~Y{Pv)%8|cCS{&u^MY;D8DeJ$&U)sGGc4Qu2d8geyG{5k;v0o9qv zKitpHKZG%TG`q~@6BO)6J4eSS$R|iTP_(O(2GOQU`zReQe`fm$rrhlQOFL~5BkiS= z^gZ*J%NLh_oF>l-O4pCl|$WQg~~NWfQm8^;`e~% zCxF03ohnO!B7Px%%Q~QJQ>J}Nm5GXFpBbte;G%EO{m3=~0QD+kT9h42L;?9Ad7uOR zeE_Q1KOmTcLxKXrxsNEOzN*RR)(Hp>s2>s*-Y7DtR^!l+@Meu-8?|`ot@~U5eds5# zZ;Z|A@YsmVYyW4~v>ttaT7L7upEvjFyKTpVKWyLjM8DlTpNrqU=aroO2j1RMbnb)m zhVdyc?>D@(14)O16!H@KJD&VhFq;>95m*B@0c{CTGYheO8i)`m1&((l{LVcR6r~MLj2+vP=NuY zN(69CnTJ@c11d6*g#*L_&>jJBQ_?Ww<&l=fB@0nlxwNrKX@ix5zxUzHGm z*xX$8$K)#~eGKd8En^z6y|`%6TNgspPF3Ty{h2;{*Lh#Mfl&le~WKv{^0 zfY6|TsL(+F8l-hXLISP|2@SkDA~38$L`d~(-t70!CI^gj%~l!5VpbccV&|9c>oBHZ zcb8!Ywq75-v{u>B@cW6aE;>G=jm$n~>C!a)` z3nXH23j0L_ECcI+wgem`e+--er#Vi>3+h>fq#=?9Ng5{MHk;o#)-KSD_rb(zOb{@@ zXhTmw7LpVJAmaj6Pyl1FJx~ zZw?EPyk+{=ZUDRYuU!Hr`KurSYo8uAphbZQ1l8-;J%3UaWFX=|ECCW2psWBgSpd@o zaxd-D1{pn)hZ)bOBpC-zv$8auv|=hjR}%Gi7QkoQX-BZ2h( zMFfZ-KL=!XuTww^0SN@y4#Wzu28b0vguo;)7KjBP2}nE8A4uomWAH8z3&1Pj8Sn_# zypQw_a09p&bOP-tZ$;YtRMFXHq)qO-`<_M(g6h`~4iCN>lV;tJfRLIY0YTNU0z?G) z`G*Ss1FZVKeyrt7IF#EVFDCL}Wg+#aO_jEnHq=SvJnVu2M1JZQ9r5t?$v1I!*o_g1|n;OH634a$eKQ3qM!Rsg>XRrTF|05Ci%{E33eY zWtxaDbyMcPisx2+jvTAuydPcWnd*B`sr>_3ii_U55V$$BkUWT53|OfZL1+pD%5+2_ zV^>t%fT&x!hV=u=LkYiQ5di#f{*=pN*1P~#%Dr)nC4z`j@kbE&6HefdC&51y5fC00 z6^6~@sPBa3&o$vm^G z>vhWhzn?j2vG3=SOc1h5FkQO2>~nuO=PSfVn8h=C}JQ95+-e|gn`5X zh(NI111fby2`V8V+hPTe{(;qk1A-!$ z&o?yC*FQMG4=aEl3c%0Lm()kvM1gMW%}$xwd9w4)Hr;9?WuIy$;SqyKhQAyywnQhYvlxuHej5XN~edLq4zaV!s1E0^mg^J%5d`9!l!i);C6v}n{c+-%qEh3Q_#sAHR@I4Rb)B{u z+8SWF0|*8bYk(302!N&t03lQ%f5A0LSOCNdV8L8ZShj_bEo*>w2?*&+uU(TrbB2}nGESUb8T z4>JCgm~L!6%vw?WV*s?(jVm`rk*=F7>6IF&SOdIb>T!{GNi1*D+ZQXGCViRTTg13b z^C`1??FBNl=Vu_~FR?xIz%LjE%LPX+yvJ_7CnH-qj#di_HD z(Vz*}Ysg)(%-_Yj$;0C7T;Ap*i_zd~vEJjkCm(8q!j z0MZ%KZL)BK&bw1bn{5%RDF8UuCVp=&Ft??X<;_KA$E#ww_i^6aN_Ys_%ROk)cjldC z)_vN?I<_l_0=3UU_TJkbpDFe8>+k(i=ltOpywrzz?$bZ^ANz$oKSQpqD@}i%XKJb~ zZxLW^bFS*mE2{wHuY32BS`cAiTLYBaz!VAUf#JuL2V8pos@HFkzX$=XfZY!%_hmjP zKAa1Pn8kAzOq5_~KwvN;AS8^j0^y+{p}cIN!ThgQaLup=)ndYPw#|q{090SiQiKbQ z6Ln@9N3I@Sw7+R~{+?FZC-=0^J-VmcxMPQJTT_sK?-`@~VFZ9g_PzukzYgT(7a{O1 z7|8ZekPbuyh$UbSSOV4pi4PEKfJ`E=2dHTUIsY&?29ARh;3N?Lq#Zm+zO=N+DBGJ~ zPP{#x45dwPg09ynoF<_FsDF)mDg5Dy)v=$%&oI*g02-1ck7Q`Kp zh8Q4~b&N%jG$9s1<`8a~Ie?(RIOER5Ok?`;C8#47J>#DUBI*#x)|J2ihigE7-phgc zIJl3MWjZCsM&fOR_=WH_*-KAf2wz0F^!7!NOOIa`1K9#(G>=RJx(LhylYs>OrGf+? zL4V@=mv>&?{nx=u;3@DhW%rTZ4utqSf;K>izah8^)aJphSx|B@>cqKIkw1*~C`)sy*R?pY7eKy;3vmLcX z0moNt=iNM_+f>!YRzaBhm`h!!vVA7`JNSa@+k!yyUf;#NE&DFD-*HWSobZpjzGqt5 zef`$5OIGA>z3Bgr^PCTf&U-&xdfV~CDAITS7?KxKx5~5#utb47e!vt3dRwVfuB9JB zdGKxGCvUz0)`Kk%w7$NXiU{x(5r8YgA9ET~8X-VH0wN$VA|wQpKuBOjSV&-_sQQ65 z8^#7t%U=_^%s3pj)Ho47-^i;rxoCgg(S`dPjX1qKdQ{$?w&U`SbX#@qY|m3hSugB} zGNsp3;6)(TfPaFIfw%sj-n-d_ZRgTHmIm==D^|(>G37)G6t2zX2zAY${1J@lQysv0iY0_ zHlP&pFH=bADW_@2~>c0zg{>AaSeL zZ;uqPwzUAz76B0v%J=Uf0)+Sx14;nMC;^!~00BVSGQB@*2=_O-;{r&WITMq}S!}ps z9MLVk2mor({=eF#N~kw$PsLRB>HRuiRcc+V>9G5a?L z^*FW$X(V8c-?A{aLwa?;Be;Ip)xiWX1w{sg1%>(2J_UpYhGPH-!t2k}e&PVY_mBBs z+C|j{n(d!#Yaw9w?xoCX7j7C*i2@pgO<)Vy26lj5U=I*sAj1l!@j695zogVC$X&Je-1RB( z=i6q*6}C@{yU;Ep?gG|;i->`Xj1VYlo;E;G+&r~^adc|`62w3$LZD1wiGlLQNk5ch z1%UW}fb>nsHt_+fTnPY#fd~Su0t!-Q1`BEtV5X)kz_bXs#Q^&xCO}Bv77vyMK?H$^ z7~ot>3}`{ngvAA9fq|He{zkLRAD9|(sPU)%gN()dq^d3$g(VU`LCxBK)TT}EW}%cg zK^@xLlD{0tCscKu^V&Mk;s3Qi{TY{=R(0Q%mCN`1qhMXXGV=E*<9j$s-_CO@@)h-M z%57nMQ@(ud&qs@^wYi1xFIW)&eg$(s7m;~6j&P9!U=P>{c7Uy5GuX)f4L~e)%fS+^ zBSU<}3NQhT1Q}o$=nK9CLjK|kl<0pM_NS}>q(c5TQ{IhKtN=p(jeuAHYET}=w+g;+ zp(yBrQ6Bi+S6>A*2(0T*8{{7m9O@70`$q+b`-KKz5AY=lz%Rg;HV-KBw*-K;j6&AZ z4q9!WNywU%J=wB02!~LCp?RTi^`2V^9(3Piun2I;zP1Jw=iXdDY( zY@CQ3e|}%B@%j53Ouvv9v$*hdy8}jP7wG2(8jHJlsUISJob-9{cOZd+A5!)O=nsa0 zG%x~81k=H6j+qanu~|;zumZ^Nqjg{d*a$X*?Lc}dDt>^xxC`>WnmFxbx0JY39Wvw3 zbj*l9+csm++142Y3lIS35CG>}WW=4vDo}_3xPVLGA})dAW~u#35CFCiXpB{WA%c)S zBG~iez0Mbm0z%}W(CU6fl!5YvUOF)Z^A6OY_fN^8`aHH3Np~l!vtBnKs zVk{}9J*5d(d_hvlAN8yDdZwlYLH=*L6UX{>75x@BIRrEfoC_jPr>q~E6APaLy zP@gjS^La7~=MdP(_uUP)qatMe@1MYWw%3A{U^!R{M3~P7Gr?4@^CQRssUQLL1OEXZ z@Y!zz>G?kg9tSenkNEy?1lNN0pe1Mo>VRtO4;Y z9O4tsI)1f7qkL+FM$ldb`au2!{Q28{e~-?Oqg~YPo|B+er^#vqHDP++ zuGxN?+jbkQuBXd%yKlC&a;`q7vQ!hVCVM$X=hZ$TZz*%8-g()+Bq|XBj%%8qsqb5- zm%i`HzDs3gm;CaTo$&uonRi9XwgdcN9@{3_s~^%)E&+U+_{9RCw)KAXP+AYGllb)m ztjqMaK2O)NJXlgD508vcV1TU)w}2~*akCLjrV+_-#E8%^SGCAU7n2CN8izD=#dhiD zTFasYOO5@$OIeL*k#QnycInZYvx|>6SXOeT*&d^)6}I_~G#WSXV&6uCaS!Rk;8|Ys zmq{f?;9c-J_yNQLWep%51;%oW^e&{KnaMe`z#Jgsj~9cbKt#bBAZAG!Ubqbg*vA|}Nfb{T10GL9+3=VYn z{IvzZN|j&`(cmr@5#Y7}5Ic}AlLeV`1*nk$>3t9YajcHi$LKs_n9*hMaO1g@9Am=z zmB!A~ho}!ZQ>nIAM_JnHe{-u@YNH=X$yB^zmAH~i;UHo52y>Cyp z^(|Gl&t_MSQ~UV}QYI{G@4Hl9R}X2~uRytVUX^Nu{g%Qo)lw;USH>Ncac4G4$%FDz zgg{AInZPLFHcCoCNr{Q#Vx#0DCVH9m+f8in%Jr zb#;w8%#$AKie&MW+N_io9u(@rLWv2V`A_TsXtT%f9RnckqHg0faaT;uUVO!Ji|`$! zuiH>>ZqOX#t=Gg1)xiCY5V&-CuLRzvkHg z+J%43P5hrZRujBQvTpMAF0XRGN%n5i*W|BK{lM7|rG8*7L135j18YB*x(6*hB(-2Z z1Oy&J{Od84L*-8koT2Vx}ELj-pY8KMO)#aIoTsw?YF5CfrYmEG$CB~_U z1*OO9tTIkF*kPP&dd4VgO{39;m%j%M#;rg^z+=4V&yxNHyhhpkKt#Z|U;q$nKq~t( zK`s~r#&gaDFbPZpA_!)Kc|gR#3XT!K~3ys(IM~5Zsyf$Odp3Z3r`#Yr%KG;5U z&>;lCkv5re#~2oPoT-BITBHp;i3Q*^I2)bTzW@PnzFBJDi?{%aKrt{yfCvFV?_Xe& zzX$<~_$5BT1n~h9BOqiiOZ$T*|ji2la4V-k#8vJ#E^)6$HOW=%Gd*Df^{9N%dyJ+YS- z|AeuV$%GEm;+}-5&QghHFoik9LhQ#P87=}-GDtU5Q04%uvchB#j}3^){8wJW+|B}~ zbceDOpsiB;Gi3_!8{;@kP*zO7SW=yrZ4F&sby~`KZtyw9o+x444eq!I2z~wnirFtH zsuU%ZyHQ-iv3$qkQWGV7|6(Bjq>i{FRbM64VG(&yegT}vWlsc0`RVeD<$0y&%Z`?u zD?4y8zie;enX;V)Crh{H=av3+>S*cu6Guu{9Y0*M;@F|$C5I0bEjoPQ;{1dA&d=Sy zuVBu;z4^2D?m0bU&z_UhckjuYx@-6GDLZ!^ow{q+;pw|~A7bCZdHeV6Uv%)`?&U`g z?_8UAY}-$#PHfp;kiTJH;knhvYQK{5rH%zCDOz!=taLHY!#u>nEX2VK-l?fzB7$H% z@AOz8B0U?VgJj-4Z2=J9|EJ(R@DK1Jcp6Cb|J^_)|LH;61&9!kvHp!fUCN_KLx4Z< z$uBQdEBv%-+{)FUT0@ph4RJ*T1iKnmtK+K8dg|dJVTb@GMuWKAL!cezf66sUd#2L% z>h{(oJ-Z#1b1G{?y~~`(S)Ze?A=lQQ_ggtfld)R_SY*w$D_8`a=Ko(51D2Q&@gUdI zsXouTzTCHb&TqZ{OP%*$x#*=n@PE%fC+X`4P?ve9dcRJk*Dn)X*uDP>c^*1^U~Uy^ z=d~E9WM5T+#C$L;ivS{kkpjvpfLj1T5aME9VbX9{^{DEuYT?ygHGQvkz4*ynt~JIX z-}T1vz>P*h*a{=B#(E?Fsx8LpMyHI@<}@JfX)LY<;u^S}7ybcWbTJP;L;fZ37WjaD zpMh`4iy#<6IvgZ(Tqei?Bfuyi!eAnp3`7{r0pgn!x4}x<*mb9hjE(ms#BJ%E5x1>t zdcw|5>G8YUXAIgKn-RC4DT5ET&WJmVAUKL3I2MyS-~`ry)6uE@@>!M-%Rs-vrpbLS zU=6@B(5IM~fD%MOX%jCopxgi|E&w5rWQqV8+DG0N0VeS~M1WWWluLkP6!B~8fRtk) z5ZL7+3glc<94O0yxDPax7?2=B))qhzMB@&K&S1D8Xn|XxRc2qKO)fJfW)Cu2=dyfa z>QJL?N|Mob*f22MXg6f2(Q)uF}lB z8Bb>A7|-VB8ZYFIH2yMjwDIcLvBvA;e>C2nIMH~2%4FlC>C=q=%$#9-GiRpJXWkrR z;DUL^kVW&2)a8qe?A1$+QEQePeZ|pvPz`}lGPu>Az?}-B{-E&;F_Zxe`KFao! z?$6t2>_5Rasf`ol!QSJ0jXlTrDC|16$JlvnH=nhO&)Q{dJ+f0_%i$fymcu)ZO{5#a zhJ)NASbKo`-M`gXxlitWi?L+aCS%dgO~(8k8`bxk`SS*2+Lrak#Eol>u^ZMHx$9OL znQK-W$t#u_LzgWv1}$D>^k2BZ_g~yJrTXpip%1vj_EZJRnZo%QAi?dIbmP})8$)rNWH-c~+ z@9#(iKrYBe00{9XfuSIt_f5?IUx81+```^AB45b=QE)%+=53${dF=ua|Nk|h9;gYz zK@jh)-^s$$J{;%j)~>UwUcgnXna=v@SOTuDR)e<3vFm9%}dd1f0Y zsfM$yHOuU_Qrbw}Ub;zN+Etlfz)Y>{$T{w7dgkRCRqeY}xts7UqIZ0T?xj~00G2p# z3IQSZO5qRydOx3Gey$}7tZnl?rLKP4cd6<;+e~t)3asknKcf7Xew@ngOUg9l9&}!( zzw5sEA>8NdynaZf^1VsFq7dLdv_+tD5m3oJ%e{MkuJxIY`;muDk1thj0c8ZbU6t^`NFc-_J_--D%_nY&1@UY&XtDZ8i#OZ74r|^2dqUiruBn68Uz;{`bC=8^KX=HA-_|yB(2m&5LAzTc23n=Z?QfMn@K8)j z|D!Rf{qvfq_B#pjpJ|rTrvT!|JpHSjo=VnvtU%!*f&BelqkXGkIYm?){0%EuE=AZ3G@Kxv3V>+~T^ zJj5bPX&`+VlPo0|v51J+)L}*}(-OB$K}4h^8toAk9a55w4#~+z$D|aa6X=|jYII3T zGp@;sm8qm^7ju+GaexSK%9vO2c;ShlK&Ieco;k~*us!hX z9_L;jPs}hLPXfsq#uF)-3cb@1JL%a9y)&|n-kE|Nqjy%W(L38hPOkAJLg>knf>B2A zQKO9~M~^XjgD1y~HF_hCo)`zlk29Y5ah%b6!g!o)9)`)SkmAsaVuP1>?`OZwLBn{s#TT0d^j-ZfM9A6Pl(@ZqIP^N!D7d+OAz ztp#VN?Y(e*;<3__F{jJRMq&xb;oZ$d1f)RzNnkkd@DSc%8QR+yi1}Xv|NadmzUOry zg8nHWlm6Tfdht%)0J@UzK-wBKA%8WgxB;qxP#htFr;5+|9X)c`=epJ%UCqL;an-C9 zoqCA^z2AAh z%A40TKiB>F`aXVdYFD23k94U@{JkIgd(W@zUY%vX_xk4f76Gdt-C6Nk0C*F>bK6p< zrb?~6j`hRMkL-NtJ@4JT2UBIb9~^n82oN-_0Qlg<0w5wld~*?D5w56e)e!+#yZl_W zeC8cl;7`d7roo4RG#Fws z{2LG0GK&)?S{F%QU@*Unl@w! z0$^pA%=k4OG6$_|mlgjLLjvDPOdGhnMe2b4SOE^<5;)5AyLkwJ(@m0o z$VUVe;AcNi@Bac52H_(3p@>O?iV*-M!~rO`0I>mP@1I_}nmEWJe`Us3J$I`Y?Uc>@T5 zG-9&`GehDaqb+MD#HQdXNM*t#pk_|A(l(MZk&=l)q*xAQie(_F3D#Ut>n#;t-;874+&7`Hia`Gu~e%lr4z zn>SOd0yw`$$beO9mE+<(o64TIKgTsw5b=GDoYeqNFF^Nz)% zckEs;anHWFGY=e`x$wx5Nh|a6#%(-vX5`Lu1z86!Tu8|)DH)z`lqX;Xh(`eQhy441 z?|F~E;T`@DkRJbsKt}fn@k@Nq^Po3)0Nlwjw~|UMP-ostdG}kAZ$?_5RFi-Bh2r8M z%KT0i9P@2iznQCX-Duhs+LrJT*HyGHQTYF>hekq(tbtwjA%={v+~Q1eooxo8;x%c9|k~i`1oDiveeOWqEz9bDz4d zT-${C9h@BW$9+fp2lA+JKG=J^s*3z?RJeSW_jSGRr>bpzu0CI?eufe2TG z2!d+iu7*(!d};(X^d0^4kN)^ILpGKjjo4-6S3hiAsEawV5oSa!0^0HNiz!fg1-F2^ zfCLQn2G4<)z-!>2;9c-P;A0>QjK~awUxDv|Qw)d@NCVlBzgPt({LjcAr{0!6WX5&r z!{;CX7Iw*qU)m{a@bY$D%!1gK9)GN?p}^G0LiVu`eOttVPTR^<$|4jp1Y!lSQkGnnWtU?!O~P-J1?daf zXAd{p<|L6q__@hOJBYn~Zi>-$%4D5W0eu?*XA}+(7McZzsJ&0O9wtaMz^K#$6Lf8+Swe_e>gN+zal5@b82C zA0T}YJOuIoX$k^h%8v?_p5$Fw`!XohW^vUJV&X`j6{LE`oYpA2R~Z2bl<1Tm+$&~#qzCR zu3Wk4n^miR`eF5&b$wT_T{&Rwx@Ga}HY^$T)20P!n|_|1vvtSxal7_RnYwr1gt-R~ zjarrv7&cJH0vtP*weIA}v~6eehwm*sKj=ttQGa3s`XJ=LLkxV05cnK?iWv9^;+9w* z>HUivPe%HP`CqJhkAnw6FVK@?#0Aimce5?25(1=+D6dOdjiRDbnFAoS#3&5-?EUwA ztGmK|8r8VQ6AwhxF1BgY!|Ic~=E~fwYiUGKM9?@-{M|4|1o2sC)eK8D=lvU8eVW_WnKFa*t#5H6+!r#Dw`BJo)I4{9dkV zpPl~HW+D5R;4Ui5%O~q{=UwPBNuA|?RNi_0-;@9K_fvJvTi?~83QQHiXV_)G=U(-> z<~^G-Q}XhJ=+yKLFl<1X27+ASq6%1VvsyT^Jvf}VG}ILp73otitdVb&-&OvfefoCr z@)K*rwi<_`jv0lu3XIbFv>=T^G%Y|YT7r(e{h|tb08s_^08s@`fM>y9!K*-&!CT-R z@ILqed;~rRUxIHyA20}ri6EH}tW45TuViG8zddKj#Ou?CO}#F4$n5K~;^%eBj9=J3 zGkytXft3UXtR-4-L(9|wn^6SYQ3QMN3!n=6A4U=6p$twD9H3MIzJYU$6)eOYaDjPx zQ3c-@1BMRB7(pfw5Jdp{Yp9?AVSk4bP~Cma>`DR9{nskMDp%W9nNkH(E~>#+4wflE z9WP4{ngIc7U1FsQzE35r0V)qye-q+=prb|G0{KvGc$tinhNvdU*LE_H_FVsF2jT%N`Pao z=Uf}AOv>>|pbRu_7@cX{fMU4OftyeXf}2qZH(O~>^0%N6dZHd~v2ZKO;Wi7mV;Z;v zlYpQXxbw%6#$Bj{y9KBOWgb8!+=EKEPt*Z;U^3@1K{DQmcR z`o!|5W=t-7cGlF==VwhTeqr{sq8H~(zxdMJnHOG}H|spA;OuMj=bU+C;k;9*f;?2g zVN}8X50)(6jVjpo>GGwUK3~3U{Z}hjtoe4;%9Y=*TD_$2>NN`otX?~B@VfQ05;ts| zlD=ungpu2}kDIuA&&Zkk_h&3Td^l-UUS7iHGpFNroh$g^;Kd7H=am$H$-Lj6UBu?k zyZb*VfcJQR{{_VHFYGVAJTc`x4I}_S6u@0T6u|XBe1IL;ZbceR+L*Kf?`Q3E#TUgF z5RsXg71Fk0+ko1x+P;zDHGQIpJg!a@a_z84h9!ln;Q+E6s_6%?CP1}p8QI5J*N|;}9glrhxwA|k_s69sAGpl}4))jGdG4cvBGCIRR=4-- zayduAQW5sHlvm9`f7JJ~N!?j_zbEf~V{$F;vR}J>$@{s~L&Il#pZjY+yJ8fJ$M=Eo zoe_ez05Bi?NuRU2X6o|6}$(WVnBQb{eTF8VFl+drae4(aQ1CkgGVx8er%7-;ghb-jGxve zd&ta=*+b?sRA3RNfn`Jpu56V$U|p-Ufty>U4cLYN*o9d@M8FY5z;Q&t3Cseg2o%W2 zCr|*+V-6^U_%DKD`~sf70a;vtIfca(pvMN95q)mIfCvHA{Z}OJ_5o;UU~@!(0<#LWNbjqL60~3q;+D)X)Jmot z#7v-o7+@SFB4Gei5t7f0Baa}+!bdO%7rp2Xg^vmx~z4MGP=b zvHghQmT1g0Vcz(e3q)5ePsD1T)7k7bX~m{qo{px}_Ctq7QH}8#w^Nzf=X#W0xEncwey(J5`eXw-#rjM2{S@X&Ar7Qol zV)?Q!S1w=l^~x1h9Xr#e?AbGP?tz1G z%Z?rEyW!NSZ!iUXw*NxmN5@KvKR8of_Ac-5TL^&Hd3XN-f&UFiw_j%bl3_mL1NalT zmvWgAtS9;Ipfh=i25tkI%ezn7koU7*QAv4CMrcMQ59uFX*Qai9&Csg?Lc$_^>F)bf zgY>ViR?Afzb7Le?fMSZ&eTr_JFek*ukvt;QZ$8twgM;-Aj1WKj2Wzk zPoTOC;FTGLg2Q~n!)}TFb z`UrZleIIxTh!}VrJPn=&&jS$!uK+Cy-X-zj^@q>fpGXSC0XpVKZgegVDPCG>b#BLJ`l^xqPb(r-shYQMb* zfP>M=eGfNF>30kfZ~`m9DFOt}AOg-J00!0K|!=(Nq z0xAdqdhN=tuX^=XUWox632656EBFKC7$pSEo%(S*oAA%C|e!156& zKLNuB5ChQ&fo7mN{(|OAFd%4wWk4a5v4)^IRsu<5q?`bQmP8h|VCh9cO92swEfEHi z%J73$*#r;d0Ma%&SP4d89Z(o*v>S;iaG=8|ECnMG2c(^B3^zKDHqmL+a8=%!)W&Fp zgSEd4`7Y$mRPtbq2#Q3b>sZ8u&XaZ>3q)X0eysumVw@Y@#vu|wcMI2#M-*7Nf%JwS z(@k+edgG4>g9(}V4G;sQJttr#P{2w+dg}xP0l0l)j&a8%!~nQ+5@G<{H5m&5xMvDM z15*han2HdXHm3Z6X=BSCnm)Glq3Pp_AD%J3=#d#eUU+=wgu>plC!Kq0&Xlvy%$aiL zxw%tM|9Rf@lP}Jjar~8qvyQyFaQ30s7R}lB=Hhuf-da3w^E*oyYz3eq0xYv|Ogjg)IS+e+_k=f2;Q zcN4$vv0I%o83w>TIK_aSmvRk z-uLv|wmp=h76IxWCA zML>jrSOx9{A_g7?kAf$_GeG7Y{R10bscV#2w%rEhw%5Hymbt ztA}rn546hd-oN8G#DKB_NY7u~01_Mkny{X*PMaVInu-XpVG01T1SlW?g#4o+eVs;Q z6%a8XshRJ`wm<{`Vn9+vKn#`vl_CIQL<~UwF<1#C6*1641OWn|6#_ueI+s+e1-S$m z01*YYFkrl5yAdJ`hFJmus{vx5y;UZHK}3QQ3zlHe!oe&b&VGPM=m=Db0Fcxy!}5T| zpd)31PKbd{2mwK73tbQdU6eS$>M)ilMX@3v1O%oqz|DZA;CieB8a>DhL<}fFfEc(5 zC{ch_;1&eHtrG>f3&8DI1$s@!O#to$cTKT`03rY(P=4REF{KYoA6xR^^sz+`%@|+! z@XR02Ju-7b!DF)~=07oe(y1qBPd@p~+-Z5w&zpAa&+}&-`pf*82VR;#b1x!bCn8|; zTTAAxe|yQiRqrmDzXSm=_utDF&G>lP;whglUozqIv3z;XH!D_Ve7|C4a{rZU zhQzN~H!yMi#=gfpy|O^Z0%UF8`t8{5J3pJYXYU8|4;^}E#B%`p;w1pRlPxQATyIx503PY@C);;8CuP!8tz4DXG91nD*!~LhXQ!CWsbJX zgWSE_Mos9>RJVWLWpb|Gr}N&|W82+c{&({>;q#f5=iTjer2@eFJP`-F%>Eu8Jo8`u zZoiGRxY5df_+Kjf%_MoL&(jagrH-j&pT3v>)`Rm)b>XpJe+TD-ZryXm`!fZBtt6ER zN|rG+1wk0=8jBcEGYJI;`$UC=`9=kY`Gp0A23CuV3The=9n!gbk1(bxjl5u#h#;r| zYSReRBW(a0fu=w#1F@h3&@O@-$@c`efjhxHK&%800xb%jBL6&i8N9|IW3deU&xc9r zpFf;A`0Kl~lfJ(rGqL~8nL~%%m@_P~TXsTf*X)F>F4==e5gRbRV`luM_UUoc!F-nA zTS~b6s@ACk5Cj8$#yYTr7=hi0f_+#AunhD$LVUn6YY4$f#KCFA0B!P{IH) zfH)AywxqTYz)~TW00qQ=2!d!O0>mO9mH{BK14C}*xd;OXT8O0p zLC}I}3u81yAmoTZkQ9NCD=-Cuhy+2K5r~A5U7N)$M(1HC3=9hf45fZ+vGu?$QdRfZrad0_gOBE&%9 zgEPhzAO`Zm=|^WxJo)(SNqGo@V^{@_JTrIdp%>;)-}mBz8M|LvFl)!(7S8_p9}8!% ze{=ENRsUKtf9bnR7tDWe$%5%0E?+bWK`{Q~WlKg8ACUR^vSle>E?++U+Z8K@^jW#O z-@w&tzZY7GzAj*Sq|;Y@0-F5j>x33jk*i-&rns=RQUD zn(%ch*D(oSr@!Uie(O2EiOB6A)2jUcqucu7kkkpeH@)u?_xW2ZuB!8XS6y7q z2T8dF)Wc;iZ)mP%EFyrhgIWXxhx$Z?hWkc^g!(abAb_d7f~rSW53U>4IArFM8Q}%S z#R$kb5{M9}1?m8?4Aci=8HfgA8E^^#aT9b0H-ejiSPAX`GPdx3AXb9Mz%xL(3AXG# z^2Q_I^m*^W?1Yc*%}Dy}uI!|*Zp%&V+cP&Y?uP7PgS%%B8{RD^A-!wXkR03tqdH~8 z|JW&G(6kO2gXV%oh=Jv8)8f{}rVZTG3iklk0frDD1XB9#HDd)311WtG1ATE5^vOdA zh!|izA(nyU?{N`)U(|&0gNOhY8~7gbWvyQeS^&sQLb@04OqCFTtd&3@b-N8Lv7q*u z0m`(603jg6--3w=Vw4aVXzdeGUh>4rP5=2X^Ji@O+rnAvum&uDbJ5&I?<}1^_x+{wr@g;)!T1lCEgbdXk_9>c zUa~0dlVyvCeY$K({C}1$8~D}oWqrO`y6nq-D_4CQzk2PzQ-0d??uaehUZ1dY*UK~a z?R#P2!9!22IiB~(=F_Jh*nO_x-lN4ucb+XTzm1^4o(O=OAa&{OcZ2xF?B5wkz@Pa1 zh4>}lS9<;R!BwCR=hR}@PPKxv!l?YBvk|SYX&+uIv~Fm4ct~(mSY%K*iiAb`AmLinsj!-^25=)~uP`PWH@tXU*&xYyx2T4$$cM znRbe4Z!rge-99nSpOGYw9{*>`vnA6`vu$kMG@nTmY0%l%W_0G-j1OS!&l_TAJ7psQ zFbv1GApp1++SwDy(p%>Tm=FhY4ntXTZ|v)|-fLSD^;g*cZx8_X3uCI|$Ni&Dnf$;^ z*?;xNW{&@tBy;cNK8Vh`AEG~YPb_w6YmK1+5(R+sC%{&oWHk>u0)QpGKma;ecCvS{ z!a$#OPmK3D4j5;9_t9NDtd?pIM~#R8y+Ala21rzZkO3wtz>onF6&MDP$%AChz!-o; z2gs1YRA45+3>z$gPND*Cg32>%U1P#GE>4fyx-2(s=aT%CpoRGxi^pb0D@LbBm5oY|0ui7i0u9)kw|PkF z$@7C#LN5+Z4gG9TYUq_gDWP8tOgVvh11J7AASL8FAp-+aPy7fX05WhK3kw{-2j`E? z2e8B-))gk`iyemgVt1jwsd@=Qfb^%BKkyig1i?6L04GnA1u_JnClDYQ$FQ5xr;vJ} zr{98}z7ZH6Xo1sjLC@cSkQO-n7C3ua!tu8ZLYkIDrx6O zuoe)2Hb6w61rDDEh(ODr%!n3ZBRU8|3!J|ZaQH2bxzR0%3bZ)p#n2!+oz9JF0V!x1 zo*!$#sTMeY*jho-AObW%5Da=8qyYtSEg%9$AWG0OvXCI56-CgC5?h>$6I(zAT0jI^ zMi(cwAQ}K9w~R#;fPfHz35W_zKoo!;D!`BdnPg~~H_(C!g)P$nIDZ-#7I?@2WZ>Z( zE%1PQplR9yTw3<+EX3HWN6lye0n z;Imb7-bGiX;5?!L%^&~`UMg|jI<=(QPbVweq?0TB%M{`ryCs%Rm0Os`C9Kl~sWu)wMgK>Q4tGHJ#m%bK#O#>F1YSF$}Ow z^S8e*uKDh}dCfokFzd?CKTrGS-rdPJfB$_vCIyaxGam(~J`!+((9@hFb{wU{WI+pnbcZ1T;V*z%Ui6H^@wuA(bEe5f@pshVU3_ys0Lx&EQ_*~Gk zyG0MH#N0INJCAN#!%5o!wtyYL5CTF5x&ma*z{|jEKyRQA&<_{{Fob|a2*@Xe3>laP zoeUF@sKAn=8QhhtlVVq|%1!j~D9zpAQkogCtR!RilH!cLZx^K>Tu_wu(fs1HV{;0U z!)E6vN6pGlj+>E}m_98hA$Lknd@;bEoE;~dm~~1uHZw+xwS_B2W<=Et&xojZOb>4u zmLA?XBsKIbh`jpa<{6jeZhj9LMxmG>{$GGPn8NNAZ@oYDg4--5}5EmKO;TBa1IKExLW4?zHapI(~& zfM7;R`h7$I2!5N*$t1Wpr!@24Tu#>AdED$@-{fZhvVfO+>n&dHj|=&E-@h%$|8|j} z;BSjXg)!R)E(Ggp$k4xUbgFl@`^1V>ni+8 zgAYbBa{)rDYrW$d8a=blU07at>9coum%mt`{Q7URE3aRl()7cP@t1Gi8uQKFyUss8 zc;E;!Fcf59Fq}Mb{$$C&KB#-7zP=8S`uh@WU6J1j=m3y1c0qWZwrfs8l1TwT$#$KFa14DB$=8VLYtn@x#=kpPgqw$XxTU;A12 z_Wb$A-wyZE`a>eY&iJ3#O<%l!@%f(T5A-knX3PuBNaj9G@86K$_I~hU;)QEN2oMoy zB?Puq2h0f|`+VZF9?bLwDd^bQypuy`^OrjIw0PO!4T~GMu3FrC^ou1L1_CQI7*>#k zAP{oEL@^69^{5&A#ICdxs0ghvrqT^VP`1l1IDVvzjl?~G%I z!`DX-=%@j4_=qaBI{x2Lp1}hUfCq5yG>DFK8q8H;B+?)P4-gT6j5K0s zcH{#BkOBZQC;9;h0c6wzL=U;vawz7~x!$@BpOX_fdt3zhfdH!9xNNf`=dj4>2!*1_;5!Nx)=61WM9= z2Oi*4!~4@p(tZOOxC=6HXC^^u#;>zVGkyUX_yxlPKhNc6-JHkC`VnN{#(ZAxKR^h+ zeT$#>H6j9Ef)HHBynu^{2sDEboWZcbX%K=s5P~X11S&8$plp>wpmC84>O(<*~^=#;y*tL59aE99H@D3t5= zDO9VER#dr0*PmXVe)ink`4=zE<6iz^2Id4zD*yJ|(P#eo&k>*By6O1M-8(~mdhlQX z2mo2%gN*U_0!Xi)IDJw_iQ^|de+QrgV2gZGr>(G7ht=&zzgqt7AJ;AWbbZ63N7t7y zahQBP)WN)4hfbJCY;WGd8qVL!hB$uO`O`a`nYK@)oq~dx4U< zo@qPDPD6jJoqWt@TE;Z}I5BAB_}e&neK=q5+}k4nOnxf?Aos^63T^M#^j=5l(XOLe=PsShdO5sq=C^i}8Fpd?T7X9k%%NM* z4Te5aKza^j?m%aNi4ZVkfIVa|0QrLfGF(803MOGIx9M9BhtK^;RkA2RkoE31C1<6d zB;VafTIjt-Qsn0$E!wJUZnCJV!sUbH8r-2lth5Q8E1b!Zvdi*wU z2PEMxNWpJ#-uD?NPDlZ9=8QyWA43esfaAZBvNX~{?!n0e$M4~@zk9IJX*hg?JaG@s z-Uv8*=%M$Bgk#rB=y3jeq(hRt^pkWxDMNH(gY$2-WrRZyqXCDnKPS>eCwBDu4LT{; z3XlQhh2NtkbbNAn4+P*IJ}U&GXdR?LFLR^sfe_q7L_iO=o*Q!yQ32Quk{nO#v9JUA zr|uy-K zAR0ge1mFP(z=KIeDfbZ#_zk!_wK(+-2*7QuFYq%6z)d*+pJtY({|EwbV-_dl``M)# z{{R8FK98IAcSHoP&FAHOg&~0}z(tUNvmgOy-WC+pEfN-1fdG^(5tnF}ic8cW0dkN4 zDTW5bE988^D!G7zs6a7DKmq0lWP2!tDV|Dk+-jvLYK=+~x>hOv#78ALd<+DN=QkTs^ z$jyHF{jM420ho;(=xo-v%Nu464t8etm^buNr*39lZ9CA>Lt8BWM}`1M&tE?Wz;r)f z{rErKzA^2RL6UY!Z#NJEdbq&Q#+sDX69qPzrrEhjiTS5ry$I5E-~Vq5wKn{_3)}?(xC;Vs2ly4k0>4ZtNxg*# zz)v6mKTI!4`+i1g`gd^t*WvuXna#=g8qWVJ@FnI1T!!<%2%LM9o703SKm(kA^;`V> zazp?$m>j480T3@16$#!E7xNGWC|xQkEqqtP$$wAE&Bf3_7LbOo1d>4l65JHRSdf4) z52fgsr&9C@@V=))7`R3$+P+pH@?WPAZ}3%!*ZRuE9zGJG%Q_)%nJ<^O$gh|)|A0(2 zC%n3LdU8YK`235XIdd;xal#P5psH`L_i4UynT-y5U9 zI7u8f8w>$pq~4*omLYb=)~dI?A3_G6kBGEAzV(@(WPg&c`qK{aNhkid*$sd6HrIQS z&D2iPrZ(oKdWs}Ja+~Y5mu~O8rZ(pK&nsEiqyOM!7=V6(AekWnL;`F`G=P~Phzi~T z3kP91fa=l#`+kB1AoNGQ-t`r#@2if~-)~%`etGmudjx>kNMwMC3OtDnkjMb@RRI|y z=nD+`;vd%?6NZdVBw`6;;XdMiqnuThk`cqxm$Jmp2} zJQRouD2n{u6-B$;752STR`?H&nPEQxx3Glo z&macBU?sm_;Dl+3(EQKPe}=Qa1^pHr^-U0mn{d=Oi4F&Ub8x0!8g-Hf=*#GJ{c$*! z9M2$~oJ)Tm^!D4>htPQ>pCAl*VK;{Wj84*eTe!idmxI!XJpwkQGYo(}G&Axh2*6Dc z0LVx>4Tn#s;rxwxaQ-*p{BI&MKue<2Hj>T-AmQ+7uyv4un*<~ej-S?vgyX*n5^xhv zpVmPPZXyx@#NR{|fCknkxQX=#fP|YM0JjhYxCIjM^Ed#D4E=&dhklt@oczlqf})h4 zCl{x{@u$M^r|KPlN!oRU{{If=|21$GJ^wF306xcrz>DbppNHdbMg-tACIr@^=U)Ys zfdDAc`#1_4N1CgsM10K}}6^CMTv_+c&z zK?o)aeuA$B4uJ^lMKoX+2!OwrLg?qE5Ug9H5U%!C2v&K^_{-Kxc}rG{xNrM#`Ext} za?F{T3*g7$&)CWpPC2Tn7@t&odSt=bb3;W}t_;+E{dJ$Z>wkas(#;z^zPbBzw;zAM z+vV3szjwS30)Q|-LjcGy9;v7Lp1;2S(sdhTf%+X};Nhd+sJPfLtorvV)ul^k%FfP) zddUI%j$(1~m}NC*KU1NI#|P`&J4qvnsDOWl0NtVRF{6_sw_FOQdaQk3R!*#5cZxV zH}V}}cGTPajM#*S3gnR<{stn^0%PX7iR_zhYT8`4B4$B;6#o{r;*EuEAl=OE?ufa9m_MAEj* za7YFuPY*-{aE|aBhydI`@1K?+11KATdyTv?6q4vhWJcmTuxCZ-^RtQ6>u~-zFida* z5duiqNIEC_2G$w4fi(tb49$(c0jH0A$efrPm@G)A;q-5S5CB9PKx_cWfC2G05EZzA zNWcw{fg6|@2qYLJ^umN6Mi(XgfHebtBp6qm^b-idPZLX$f1Fg3^5c}!)E}{;;13`I z-y;I>-3(6pH#0fuU(e#Ce>sbraRu^o5P^#z0%t)08t3z~8|L$KYTx8#S1jP?=s*Ni z_&PwgP?#@3B%l zD)13L9o&yq1q0ocf*tM(!4?mNz}HhLShHFs@Bk@Tn#^9@|FqSS|=6HU7c4v z-H$Jvyf(Xde6T<^DoR&1jN5#1VD-1(^*!^??_WRv!}mR|{d%k0_xFG8e5>U*hkK7& z>@XL=26c^b{G?to!+As+>+${j52!njS}1j`n(B&wFLine(LfujYo|{1_M=_V7IeVs zqBbN7U>pL_w~h4VKc-DYJJj0VwAEXQz*9)TQ`)gMZR7Kl!@ZGvBFD4ujkL||^uMk@ z-b-hkIFYUAB?N#W0gNP0-V|-iwI0tt*NfGk=BJ+90Y2?y|228!1tKp6L3=L~+s>4G z4oUuK#`CwQv#(F`nR{S#MzZaUjgd^=vm_}G=wBo~2_Vj&o*O_94UmXH>t}-`8bHv= zj%)zl340C`=|H_<)r<1=^+ls`7mdYF#>RuykgyvUh6J!917wImPXbyVb;rtMuiU!( zp!Yu?{MrxpK{a2M4VN`@N4@Q}bll1hc1{YA&SSUzOSt!iNd`pm)H=mbUGM}HypT|oP&E=)Y=5SLq zvpLD-v$@GtGdW4MK*RLX#OA3b@#m%#$6uUUl5lxaQQTJ(i%wmeP;~0=;|pWH9aj+Z z-MGS7f`5!DAc*;gb6(VUBY_dQQQr;EiM&2MFY3BeZsc{xoQUg=xsl%v%L@M%#NgXu z*%8-=W`!F8M}D0Fu|xlsMh5HvoW4Gv)=AlLz0H_U%8}y$+D4=SblKK42mp=+V8_=2 zv;-M|Eds{_S&^{mC7sTUybi}s+wu9}bpnzGSzt-%Inmd#@*tj*NImGX&_M#OgAiPI z%sU0dvhgi!-@@r%CxGLpr4uC4hZn?O2LS*QzQv@#Z!rw;EeODM$m{qz07$xy&ji1N z^Z#yqN%D7?5cm&#BKVI?5DD9q!(EzB!{MQsRE(Xy?<40mQKy`WzPUEA z=zL?J%5Sc{e&wfIFJHU;OSf--`?d3p2X{K&#wWeMJ$k@6|Hpd#sBcCBaPQuI>c-t) zC`Fl?>So=UdZpW|aQ@a93dGv~R(4c3vgbH910uc9HqPJB?pV@2dN_5Hc8P8Sk!NfR zjXnPtOaM%-Yivsm_s3jc-~O@NLZ(f8(emjIyzMYR>$QzUfV9ahqQKmDt9+brwC1&* z?|E!b^HooGWCrK*v=jW-Jo=UT_2G~0kpNR0Lj*`K z#1{Jk*pu&$f4O(3)4fOcyWhcNC26DbwS~(T_vzi=aiC47E*~~dP*3MQg<<2o zrP&i*6h%|k$P1^hRTa)zr{&D|DdQ~kE$1!qDHp8pDHpo=RtQ%E>(-SCHh7ouxA;^D z0=&z4+g58zcY3HxcDt*K16>q_!7Jqj`wuwPrRa<@790a`Vj6qzf}j z5aEctCK(oKn$*d7<@gx@YL613u3N~%8R}>DnI(Fb6)h-k&px<@}j>Q zZh&KU#8nUgAe;sq{xzhpfgD^#M1TgIKa+2x0CBcT*X8{AW|=lX}ulffX>5QfU9~$K@#ZGhz8)^ zf!r7%`YP5N0Q8dB@Ff8dYs9czy^d(WRXBcvYjFP8KnSj4c;G4s01Xg;uMh?J%DE_! z;3}d4S3v@W2_Ny2*UseF&S__NI)6@c+Q1<; zT?Y&pFlXf(+fPKk`pu(|82|5K+nwsr*@o%@=kH((iLgIu3rNpjzx*#D0eUB6>S)_fKOx*t zw^uKi2rzA+X`9Mw|Jdy<(;gBVqrW(*chapP{Kv1+>g4qi0QR+8Ny3YF_U!BY5#RiO zlK>cA3gZtzULI4MX__g+NRrRiP0P2JCgs^+&hf9<*vC9gXWa+=$0yDon^(}|N`wH= zB)~8?07C+V2-uQ+1u#LdBX<9Cut86N%niU$Ko5sb)T>lCYMqZK8j@So&n-8o2aoQz zX;h4jOv@vx1-NsU?ro4>2$_Ur^VJVu*u|yCbX>T2UYBlNdUm%kw|u!vx9+cZe5rFE za|f#d_Fe4@Bs@H#b&`7j3MO zF5OfoTfV7Q>bkj3=DDd(x^`o&#Ct=H$j7%z=m%`{uHbE2Th80!RmR!6TF2SpsV&)s z2tlBSw&Z|^ruakPh`XjJ#7$io<*F)(b5Ru}tx^`GuT{AAQ*=HwuWn3^D*jU2)8bq%kZf;tEK>702AD zE6^`Prvc}G*@(=r%W&|3L6ST=9if*QOd68WiDYz?g_GBV=rkfO!`WX337{p>(X*%X zh>dM0dHS*_lO1(=Xig*~0d#{z&mVTAbBT<;3<97>UJRrjj`^{AJumjMWB#ejAOn}- z^e@BVUqSi`bQ|Tb9Xr zn-KQjxKbhT1AG8)d>**gMJe!fRS8|))xza&D&bOhm1q(4H$7E?+4y8|2Id4z!6d=) zUJB_LH)-jpfJWW$v(cBEn7IJv!$%Iawd^#=+QF{Bbw~R?c6Oa#bFl5%bKbHQ-C|2p zJAe7x)efKC{t63xJ+k@k(XUpJ7Qa5aZ-)5*ZR+a%-}Gq=#nJX{0UIgQcuW9%iL$k~ zq&lMKZ*OjmjsS@W>Nf+jB>Mo6Xn+w<=*YC&Cb0w~{-Uq{$Ii!o{-^0wmk)kA)aKWETIv5&dF;3EX>X9p+tluF zz?_SD>zFkAShnp&>&$fxQva5dH_`wjE6|4qm|26i*l`Fe3ejT&BsAcFF@nxyqJUi| zY#sgz<=A5gbs%69b?4WM_5TP6z<$mDG2f_=kH%%#{Y1A8Sj{1 z8SmtJ9WTmP%Z&q4k9eVv#7mP(;xA1A#umk01S`1coF97u^1{fx zm0rJAA;=~KscmTg|!bN-@fZsgj(o9~)r3J#A&*0HNdq6> z;xcK$g?A+d=YU4oPcIhb*1+pmES2V~mx%M_u#1;T3;96Na(Qvya(PkKGI?<-5Vu@j z617}WdUA!L^ce8r3I%7si;5Qn>|CYf`ManD8&@j%@cw+?RVtzPDh%=iUM?!(Y8REr z-Bl%Wb=OE-JT#IO?rQP7kc&Ok;(DN?JqBVduODS$)yLe*x|g|?)yp019bU4cI(9XqtQ;r`Yxq&!Y+mj$%zEPZ zd6pYCY%!0H2{ZfV<`<}!_c6QoHt>Mr$fcCKiw`w*(juy}#Vb@dGlT)G>?wr*=^4W| zsP`T5-7s0pmi`pLI0=BT0G9V;+9}3{G-+E%88S0a-}50J-V{t8TfQJBK(5QWA6jSI zNFH-<%)OHP{Y%iE*Kg1ES6%<<=QaLLhTq{y>DC|g83mtog8w-?`vqZM9=2rkXZ;@R z^N_NpY36vw{#Q%G_4JNkUs326pHy@jh)oeP02fV200F(_Ai4us8HB8(58`@3J7j0dcn~25qVq z4e`?n9ru2&9l5JXIV$L^c5Gm?X2PB(?bO{(+L=2W)pLOPz}q{UG>akM+0~?3y7P?c zyPs=y&sF!WqUMt8Iw@ zfE=7&tt>j@D$j3PF3o9LD#>of27ln&9A@Fb)6^J+cW-x(V_2 zCLGg*@dG-4XvWDVj1eFY`zzDsB4|6EPs$kVbRLe!xBz_~GB(1?iv_+1m4#uO$s zVgF!s_w$-pDof6KYBZ0U)?5g4(bXD{AxM}#?JhZ~io?790 zca3nZhgRf?uD!dPTIlMg7Oe!91Iygh;`cnXlBIC??|ABDi#@f{x1rC6oC5+dbG1%3 zb+t}9VYOB=c8yLpdbL_I(n}+AMBWe|nPd=U->W~i{_JCJY2J%6w|(8h!s->&lb5hk zPgiSe>&_s}9qp{`?Cd&X@jg3SD}2;%iT}+J*fRs+HtS;Z8fs!s)W=S!m$vxV0X(83 zWe(?VZcBFgp|DU0>O0aM;QZ|jodf#&KSR4j+6`kH#%il*r_V~$?Y+_IlXj0G0F2JG zg^bf@BxC=Rvb}bd*o@Di*BP=x?)R@D059sie+_B)qkj4ST>`*&0YV(7#-=UU>TDXAuDQOhK9iSYd+!tO!C@5b9t}Rua;$CS-4o_@Fr<2=Dcwau55iuXZ0au$S)9Prbu`I@@PwgR0+-bMk>Z&d3MDp$`o{ zt91%KSLPgiu6%6J*|PDFlY*MdrUBD~o6BYdpDmjSIeYK9@;Sk0b#sAv!OhwQz`~#= z^`gK=)zTo4g5V~#``#w?n&304^}!9QfW4=cyAC#Lg5Ph{96Z#hJ$$G^6Y^1mChU_& zZOq|DUDDw*+Ki)(x}4+9<%OR%mhqsAKde{DgR7+KUFD*(?d5_>|1y5ndJU)A3()~L zML`Y55Nh7!rPs{jrBzQYO|BYWoKQ8UFurn3QCy{SUToE4EL4Fc zRDnPsFOtq9`9_d)kn%*D0N?$=7Fh*HUxh(`Ae;tC!_m{Ab#h)(7B)C|T7m#n4MuuM z4$9`@p7NusKmw|U;v39i`7w~t8A)sfv9QNh6F3%}s)pkyvc?g=2Q7(S5Le@bG)O?r z@WOZ?p?X9SjVcg;%Her&mH1Au3f~A;O(;sKo>Q7pvs9Q@vqsIW@zwEbHk1pi*XsmT zJ{n%-S{1jND9TvL{W!*&qNj;q+&CYGl*bl*y-g>130>n^WbSX#VdW?|hE=wV@D(H+jY3(yHW_H?kau(q?Y1bwzd?XkfB=IFbd zTVp9dJ2Q+O0Qk6{)JqFn3I!Hk^lDz0C@q)OTl`% zO<#6nK2xqe$-KzSc^Ju@-!%VecBbrKAx-XGKSR*)VqvmC>m&g~Bmg7;TZ5qi!H@tM z762h2Y4qUHSdiI5)|4f58faK7K`6+ep(SP#!P}czT4OCyD=S1S(I_DUP9Hws!rI2t z92*%~*aIDL51nkSEV|g(Sa!p?yJH{YmpVGU)-&NN?aSG}pL-?zoBG#+E|vA#|5^DP zfoHXS_cUt-CQ;-@O=63z;k6IgU*$Y-gCBW4D_*q=XB$CH)+Nr8ZZHvxT8Ti z3BCWRI~o+zcQz%cK@Cc`y=T> zM@_m94xcMO{OS4fkfUdHQOC}e#~r^=k$mD(WybM~<@ra>=}JFp*6^>rl+GzTQU}MbLqq^FQj4g77EWI~EF)a&m>HoVI`Xt| z>e^wM5p*5~{b?Oxe@Fm%APWG>WJT)B8g0ZLu0xL2anlIS^68bk@S3=kF20y=`B zxq6A{0MfBKLu@A^~DIc`+XZpme#oAb*9lC}X9xDA`3;9OtemiCQHo z3~`Z`90m#az(roV&rQkQ>8jxPLvCBW zH|?!c?%Y?e3O;aJb>Pq$^+z8xYC;a3(L}u8ppHR0@xvx{#`_Jbyn_v@q64QD+6{WI!<@Cq@A>puk)K#qiu11$O6AV2D8OlocsQq<}!?m=z^MbU=nM zz6>M*=?K}-^e`Dn0u2xXIuE^l83Blb3=ZE25CG@~KnDSk!MV%e}bUh0J96_j=8bGDVbAFtdw9>eu8XlexhtjVX7RP zOvu-1_;UPx6&UW3Z>^TfHdlzGemcHnjfx{gG=S?WEh<_mF3ejYD$D>9S4oOuTxBH@ zZt~I)S82&dtHi|zR*H**SBi>ux=2bltrC~`tdf*^xkyW0U1Xf4E^_WdV4jPDJJU_c zo9wFOj|avAqtTOh_D~B)fCvx_$N0Y!!v6^IO91Im4~=xNyIMNXT`TRsx?JAJt3uHW zB;YmgO8Kj+%T+J0E0_21tCMx_GH7hK4mKF`H@E777=9->aR=0T&0E_frd^=hz;@dwz4NEr4P!pz z{2AGLK7B-hq|I3*K%Z{SW0(Kybf*2I+d!r*G)QBc%%n*>`F{xX-;?!h&r1LA69DGr zBo9q=(}!p0o96wIH2Zkw{A_8eGvygOb6;%xpVSFcH?no+T+DS?@`*1t96$XTK^sYW z{`ww+Eg=ImkjBm-aOP%K<_3_RM4;pPkN}YuXpGQuF~Hw}^ipsMON;`51Xx%hoM~l` z34tAK(B0`^W8JZ5hn^0DrcCYh<)hy_%O2h6qIz_{Ys#am-FBbWytJcU-6Nn*@k&6w z^0h5>ie8&)p$ z^&|~OAB6Ov)Gz>clp}H=$_)VeC5G_&6CE~^9*A=dz`2R7KV-j@6TE)O0A%0f5Is`# zlGysEpXBvRMIMb%-Ww>>2gmirdHSZ|92sE%(NA*wrG)`R(mD?k$DPDE!htY80f+)* zIKO{JIP^$<|1=___#gtjAz9J9q1iE9$E+BxQ+5nzMD{7Jb7m}eDt3@U51;3&<@2`J z%K6)Bq&)u$G1tFR%<`}k$09({A8#rxi)IG%8z^YNp zUXeUj}GNi%O{@ztwAW@`>kwj?QLwZcCk$- zyDqlfY>(qS5^;&`R zrZVC9E#;ya{^g>1+bSdrcUDT4?gA0mT`Be2Qz`Y?Qz6|1$G#w3D#s~3DrZ<)WX{mk2p~Lr zaLP#_EPF`u$?PF1VOdCL4N4Bpf-}#81J8nkhYlMgNe@K+0OT7%Y{(ywd?KqqK~h`v zL%MHL2yh~+PvUWdjx^B|L$cmTIG)uz{#aITNTT;aS%No`UwIDa;BKoD~JGe{558IT^4GcY4kkMxM_!Re9NL(`+O95bS` zhG)cN4o{2D8kG@~H7!3SYnd=V%SX-4M$bQcTa_dmVKzDmx0b(M_!@=6-Kp009!PY{8gAOJlGTvXzhTvU?ot{Q1q zH=VqTdzq}WXQkZ1vrN%(ZMC$6SB1)cL#@hgqdd>f79(Uf78bVV81FZ;u)tz6i0qqV zkPSYb?&LF_eL}Elr;l7S)G>f)ZPAtl5K@4lgf>0@cH4_~+Y`poGt#upd6Jze$K*4T zvH$gwv}yEnGLk$WY3E3qZG)X|{|tHmtNLTUka^BOARl+6f8d}$bHP7-Ec3Fm?~`pa z{IUP#>#)y7uEC_)lCd-Qz~nJ@CjA1XDFJvY31Hs`bB_iaaq{H1F-nF67;Fp)AY+O& zKn7YJKi%7Bdi_R;-v}gu1xqqMNdwcDFo2180APvb3N7ss3%~;9(CsZ>w&-aUQZBR- zJi1}Uee{#{;UAi0;@}$j^1U^3*S*zpuYI+O4bTJjAtDf5B@2e_gS|DfBbW?$95QTInJ{{1 zndsDxa$%gmmKVQ4#Z6c%D^7G3A4}+qG(jJOPD|*0;*KS}5%(!=?|teh zt&=pZBfmHFHxeM@Aps(Lk$l*C#UBNbP5>B5bf9-4@(r?g;&G&pC%lmqLZff;iNroY z-;~hAzR96U{ZmfT7?2v4G$17`X;5l-(%`g+#KEZ%i9^yN6NaWmB@EAujdx6mjCW3t zjUSsGA3r@mB>^G*1Rpgo0rLP7F$|CZA`rj1Oc=Lb%{%3*5kz~dxM6FRoa3uyrANHv zoDV#uCBdFD&d$}+(f|)h>4w!Zj+dvDISb zn_AYvT_d%3)yV8TbaGn^1K4<1Ds9%+D6BWuX{`5NZlwBnbYSKJSk3w5kd?jlOCZZ6 zkOm%rf9P$a*H0TjsA)+eZLKi&`pxOyzlAZ)A_9g;z+>&0pJ3ao=>mvkAKKmNXHJN)LWC1!&3Q*3J5Rgeq1T--K z8Nh5oz{c7f!2okxtRm3MuBZ8k>GLg09(`*Ocjt=5x>}iqZ=Kw7LoHA(vD$K4VTEXb zwO_T&8c_fn3?KW0O>^D|O9X6JU zyKOF)_S{+}dwoZ>yx*>Bx#R9?`KX{;#rS=vl~ecEE9U}lAE;9Q~17* zxdM>e4%Enl4xLsWc)wop;ek5&;l0(;x(5Rsakny3B zgMmTuCkP@2#)Z%r0NMZ4@rVI&$03i=lIZrZU7oycRbeG0JUv53A%_eB{Z`yjth ztO1NpB=UO0{sxgq6J0NlLO&YOD+VAEpzU#=M)V@(An7zq2T6!PBq5>~?x%PBaat$o zH=w@(*(c$6L?7sV6GDI!k^K@wY4lGFjT(@6GHPH_Sk$1T@TkGbkFqauf-L`Dot zjV1^mkscd9GA%ZIR3?7k?1b={1?dqW0}*ie5u3Eah^=Mfh#i&EFyLfBnK*QdR&;!` zMtIm?EBbJYMs#4aMijJODcI(#6l{X@^-=J>)+zWaz2&^6Yh}E*y`;Rkz|=J|-gqw= zZ*y)r_4AN$Uk5Sh=_=xMa~E?R+$CIl4;kOi02?8#jdr zQf%X{l-Rhdq}HBVnf2;&h1HsJm6cD0!g5QU)^b;4g$3rjSbX~JXBOku`C8amI1uk| zj%WbfK5_I=>3_7-H`Xbpo*^Ig%>Z*k0uX*@fHnbnMznR%`u4(DciXfdjDvobB0 zTO&2wT&pzO+MqGtSR*svSS>T(PzhN@q|_V)0Fao&*#i>u4ZucVQ>D~mQ>DaWQ-#EG zbA`kjj^7^Ww6jLueOHa_)jc)xe!+FhA^T6OoG=M+%)!&DDIc6s&-%Dg`{u`unnl2h zPntCDfY(Q7)V?1#Y5YHGRPFenK^X|_J5;YYbg*9W(Sg(QkArF?pKR9&4rA?rBWuKk zM_l-MhZh%S9DXx5_3(_WU*+h{OGn?g!Z~9)Ro{cMQ-=kOMkRB(0-NUjPvVTK2=S zB;60!rH^Opu=P(oakxLZ7LmY!#Ly!I0~1dk8JI-l=%D2Aqj361honRth136ZSZdT! zr_`9E!_#Ar!s#Dz&Wt-UDignBR>I*4*-4*F%t<;tB`@{xoZ_s*tHecz(epoo=+2RS zHOj*W>QtW`tW$mbex2&0eN~D>`>U1vf~(|#L6!0ydn#o9JIkcLJIbV9+jSE60JUg^ zzgoD+Un6>RlTt8ivr0H+qf$6#gHqtMK_M8jUM}e8Bjdm7Bjm3{+1Ee03 zdf9G$q#Zbur+3zbG_*Q)lE+S)>h0w-Hs-voX+0rf+yBElX~)>W@6=u!NNl8>Y2JTJ zy3I4NpXWLCwm-&m9{i$i;!mH4yzJ!O+k5GmXKF8xZDSwL=*+Q9nz;^RXCKexnc7}( zn(c6(T*;sCTQK*+Jdfcy*e|v5cVx;i&-J8dHk`BFdtsfQe4C6Y0M;A;Y%J-$jk{n` zqMnwoP%FbfrVf0jrna4{q_&>bQQMn!R6v80+TNt5b~I|JZKu^#K%I)(YCu4(l47tG z`u2Jijcs+%QD!I7yHBev0vpuUK@A%FeP^^?-ft><`A~CNuMeBc`h9Y)V#wih70yR5 zRE|4#v1;=1i&Zm^U#wgJyc2S%>ODx8;}qpeMmA%hXoCSZBXLLpn-{@ zv`*x}1b|4`;k1nym;@Wj>m|`~O!CPf%v%V;{Dq*wTB{NOR!@xkMA5`)L*BnC~)O$wZnkKeH% zHE?EOdf+TzK}mLyhomSdpiC6>VWT$aXtOTxNRxKYr)PD$L(Z4)I)1in`w@Hw`q63i z#t-ULz8}=9y*{YdxV&Gdes6z`@|}IviUq+{ikZRHiphbMvT?i1rOvy`Btv#rNc-(7 zm-O1M6TiGoC+-5+2WZ9Ch$2`Zia>2*poXp%Bdy0qt(e-Vl>ky|W0{QFTp_2nR4J(~ z)hf!rR!eQI*HXLA=^!hqL(R3+!LQCxA5>^5bE~ct*3+QO;M6f0kU}Ux-+L!c9`%ZL zo=orFNB{^aXw7f8&7+UimuZg-Fm1@w9lfdJZ!b;S8DeK7TYp9yWN0^@bpJ2R&ThxZ zHQDW$A&=eu5uIGy)b^iFGxts3AM*?^K(_uMFW_X%P5xUY`;W>z1KY;vM6$t@C6Xz_ zwwc;Zk7bTw>`Zwk{cn&=MQ+#m8m`ZjY4hx+_r^Rou|MHC*w0 zNB|l!gb*DzWw}^`U?L4&|&VT0_4YlhGoPE6%4qr|M)F=QsbOjBf z`@^=mQc7b>l@yIF^a=^(UnK*iQ~=~Ql-p6GFyC3Lu-;v#v=6LPbqU6o2K!EHUOUjB z>3gt2GXxlcg@Q(Z*rb~X%=oBTHxF_lA>;kW7%)0F z-hXs%od2loQ#70*X=KIvkIanmAIZo}q@iO%A`MKi^LNUK24eg%;Z846-Z4E2i1r@_ zIV?SrmP3imi1Mc;bjJ*WD1WC+90v@~!nue9MnESRnR7~yY+M&`)~5rUbK-zg0nWK` zTlI+FIyx_5>zKU6t>X%kwobtBF{wCp>*V6pfT^YF0n<4d{xi6l{7$RT@cm3@P1`T^7%rtY?pbOgX854I=PLsng9 z*IVOI0Ua^W4;%cogn%Isf9ziW$n(6AGE95droC!y2mjNKzrE}KRsQvVlMFCUi}eS5 z;t#~C4D`$MM~`XeB{5!ueSOpO{|D0SO5R=tVH%V6^8ToeIftoib3F6gn*0Xz3k@6j z+JGhoSaitR#)9f-WlMF(vc%nA>P>}yQGo_jMeRL*nhI{Nq5{uWP=SqTM4O;DS5mth zE2uq9kY~!NT@7W_&eJ+-2YOjMPot;B25h^L-h=!-4Lb9{2AyS4Lzzu*Lz%lg6z*3akVu78u4>pPE|<2#p=<2$D`+jlmNEZRKCv*>cVa=R@A&)_8sqYkeF?_qCFzl$>^mkm(SRi1 zF*%H$=sOPfae0Zp<53nwg_aWvl6?s#8sr4ni9V^21(F6pdT>vv>!%j#F%9~R;xxaR z#p!;tN&v_?rI~(ja9_tJae?o*1CWcEDyO*vE&${Jx8#* zvG+iqy9=w3EkN165<@qf~0^gm2H`vT4KSobQj8{e$I5B{w~%siS7n?UggNvD3_P?MZgI*0A8?_tHuL z$bOoL1b_fw(ExfmQwOs2FxEE@N{^)u{|(On%W7&%os`aQ-R^D*{qj z8IZ!JK?t!TB49v3tqem2=!w-MYCt5S2HTLgwMK4+$bq?kwZa0h-ddxy2Rd!5QFYr< ztA2TBo%)Skb(#Tt>a{}xPwR#UHR#3!H|QqrYb={~ps8%u{>HNTkc$p9>XsZhqkV5* zgJxy$X^qRCdX4MudW{=MhdT&}$JRQnM*y(7M&q%eM&rJ&QtiIBLgnrSxf*hHh0?>L zT;buSlX<$70gx-TQqSeUdm4%7yK1rL5|zmF9hJ~?u~O)+CFi*> zknubg$haPF63F$KC*yd`1?B*=q@^A+X>dGdNJ~7XO8|qMCMl-%sp3M9$-;b(Nx%d_ zp2tLh$nkuDmN_2dc-bD~xY-_~OEW#jaI!qca<1wC><1vAs<1vXG&(GCE zKx7WBPl7%P_Q{ZwVVjKeO~Emfx!LYhA*bV7(+GHZ9y0{_p0k7no^wP6p7X?oo^L|V z2Np_-JQvG~J(tKzJl|E6dMsCRJY3W~cXzG8eYH;LzP4QAzP>{0j%biaV7r{~HRebTI(kEqV9_s?jiAsRFh zf6FoZ&uE74Yfuk?9I*ei`VA}=^)h6)ef8>2d+XKqfHlfm9B9y*@2^*z?SoT4a9TrS zKL~*yT52Eky+AM!!~o8J@0l{{0Lbb`Ag@Oe0l-32)XD2L)Q{?vJy_MDuD-4+{k(m`Q6d2%gw`ah*V({C})^_=qA4)Hlp_*dQNbDfv{ z$2I(6jW3Pq^Dr+I+s@b+$>f=)89R|AkC9Bdf0Hye4y^03ZSCpgei=Jkf0~WSGnK~Q zmUVqo8?y+BzJj5Wk$sM_3^8^Wpt^PFN@3d~s{3$fYN-1PYUnywYUFM|YWOZ6YW(|K zsA)YQ;mYFfm8YTEzT-n9nTRbA(!d#|J``7J+XOe`A%wrok3 zEZZ1MGPaHa2H)#|9~fgEwy`k@p`{7ffJp*P2sD|LhfTt?)08)qloDP6gH7-Q15ThB z2#xW|EAx!_g?4hv+p_gAzjIashN+p_F8K{&VH=5&$&luKX9AZdq1#m zuh+Bhc5nFud%eB~zw52|*&W`hzx{#d|NI_r)!*Dzv+|+4(*EE5sBZOR_cgA5?18Zt zJbHiAMNd39E%($zGcJDi=Pesvcx=vw7anh2|NP_an_qpV>&jpMa>><)U+CF-_@xy) z-g;%#j^hUgt~+t)f@^Lb;Cl2MdK(_gv z*K?cRd2J1lyX@@)xy#-?kiYE2f&8Wu2i9JSGm$sG{j0U>kH3^(r|@F_lDA*XU;Ne! z`L7*&KEL)T@ymSv2=QDl2dp{#Z0p%E( zZq@5gtq zImAm3=a#;xL4MiG&_jMM?O*!)+_~VFgYQA!9#WteeBY~&=2igb0V@qw9e5(w5BS7u zPvi$)e=>jm8&4}-0D8fpr}Arl{d7Km_?i4AN1x5FKlV>+HywX&?dEr$Uwg%g7xPpwWS=7tXs<-YaNo4Gxo9L;_2UytX1_}M%8dq00azwf_)m)rlx ze_pfykMCdf;OFmMxc~F_F1YVMe=~6Jf4#Tr?$6#`amT+L@A=NB$Cljk@zJh5pB``D z{qfP(-5(vDv*)8DEw_GrbjGcp9GeC-?fL!DvG^QybWdA9(2KRxDs=hLI!U4MAXyXOx_yu1JH zsQ2T~-u5={`zvqEx@{^yO+VxMk*cL_-);GAH^58WapfbKmNpCr{o-!`I7#fmlu09l zYU^xX^4a#Hw{=pEZD;F6eu_{xI9DZYI~iQ3U8XEZIxXQ#Q~iZ9ZU*rA0Bi#IlR%?a zha-#edbF3#^2~yIoL`W|3xo~O<8UJUT%Z719Z+jfheM8{e7%>c19-*(&N{$321F`d zi;orJ`$U=A>?nM$Xk4bgVRELvaay`z^l9nFF*9pNk2|w=%=o#PaZL*{O_Mt6CQj+D zoiyc~+9}QF);7=Rt(){VmWIHQ03yt)4P`K^9a+XBC-qurm_wa}lm zc#%K(oF)BJmY>r<^}OZ%Q~Ue;sjFA{Q!nZtn0DbRh3Q}W>cHt6Ru8mXo*QV{k{g(H zMSfuRRci;%*mm*2oE_^1&f2xnKkFNt{CR)A#c%zKEBy97+x)g$f!ntG3-(^)x81SJ zZ~M!y`)%L`g~;CtTjph1oe!WK zVA1{G_PbGE_q}MtUu$&z_(s3$M>qPNKfJ;3{QmWR*AKqwcY(IwzGI;M*6jlec5fYM z+r3Sp9sK+ow+zg`;qrk6f3{^{0qFd1TsF|U>r%gU=LUcNj`jTuc5LYHxOQWI$By-W z=gy6O=k^W$qHP=fCA%*7mtMEUU%G2^|B{`XRxP=9^U9^yU49x^eQnE7y-}y=ud#wrv}; z?b|ojf~EkkW9MeC#@_o`Ns8Q>+7-; zv$feNKy$XXVFu_dU`{sEa5m72ZyL2D-347Yu(YAJVHxDhiH1yLPeW!@FOF^N1@8j7 z#-41tp{D_8OlNy>;%hHxUt^}hAluiFs_$z|*Y`CTWK;FM;Cr*FI)(aFZ7)$*lTlRo zx>TkYJE;ipdB$G!XD|9uQS!LW1RsJn_+SHUh|rFF1S#lJsb1Wy24ETysW)8%8Gt#U z()e^;uL5jwQwyYe@e{WKo^n~=b$34^p;9zVIpS8fTnhki<)qp%?SpqVQwbuYy1JVR_^*mu4$NFVWKJHTS zr+{i*;fnz3kpLeH=x9&MXe{Y4GP_Z~s_T~`*9~1C3X_dw&4e_->9#slO|h5zsoZTvq4)Bv6a9%F&WIoJ`P>_|G$(-x1qaMX`_?8S{PgT0#9vcZl7e6BsL zfrJf!1bvt4Jj^#lSnD=9xEBljwywDEq_1*)tH^}9`e9Ft9|m;;JAIfd8_smqV;Zk5 z0f~yF45x&g6NnciG~wa~)z+BFIqZ|Kf;uJ8OPeHJoWePnARJN&;uX@sLAk-64$PHF zy`)Y(#$nOf;4A5B1Awyzqw^8YQ^^$Niv%I)Sj$8W?C|zA;y)fQ0QfV-Od~J`7za!M zCIM4{W(17spfiA(;Aa760A~VcL3TDU*TOvTF6Lr$p=?Njd4#cR1&xDk6Y!E3ACFb} zu}PVSQyAvq!?KE!w?TO^NZuqHRTk@#a#X#nyAW)XZdaksw#Q~p*(pjs0InsIX(cc; zF6Kcdm_H5uR;7s5QU=}bFqdx(QdVg#hB~OEdTZo>wwSy^<6#J3k>Ym+6$bvl8(zqoh?T? za88grjwwh>nYJ@Y;#K)9*T8l-Y9qk$G8=;GP<*R6l>%@K3-ekPN`rDQG+J zEnf&^&`u&~uV?YLT-)J#(Lb@6g>p24zEFMQmNyf2gs#`7=vUp2)J#x-H1!qWbfixM zrh}h``Z1<87~2|*aSg`024h|`7GJO&4Iuc}WB~+!e%e|ckBvD~gG3GHqYKW@8UzKP z78}?AOj{5eHIE;8_TQhBcLDfgK7I={GcpdTl5Z3dezJHDB=Rl{CgWHkypsbz4I zu~Y2HCY@xvZd~b!*RwBHj(kP(rkN@&XLPU*Lk!dPhr6gEDmGG5iLLi&L5D&}ndv0BO1z?Eq31BrQ6jsp+u8ooGn0QJ7u^nqf02 z;0cS$2WQl*kpk6VnZj2}D{T+1neEWm&pvQ~{+u3 z#LU-VeW?vL%fec5QDmLD8-T<$Sfq^DJZ2rrwFyQ4VVw;IT%XKWdY!u0UrwH?+gRg= z3833;QI09)GPc7-Ro$kpk>bDj8vvPPaUCbRQj~dZ8#it1lK67-lxr7LkGojn)7nWz zbs`gL2YSdP@GHker{u^2J>`{wPAifJ*A>?`_CMv3aTt0!ZUca)-oYjyi~0y|21Wtg z2oPfcJS9kv108QL0hDM;0@@#^n+W?vpe++ipb2^nY)s&MG(_f5M6u9@JoHLtQ7I2+ z*ESK##!y$sykaM|VpEEme$v;TLLVdmf50)Z2%4ZP4QYQWJpuL;P}g{aaiC){$HxGp z4Mu@B09k{2P{eF}v=4y2IzS7WFvQj zJ#AfCHPRy$@ZEa8_!|Hjz&Pqo0NS`Rrd_$Dg~sJ^Wl6S_C+XZWN~EKKQwPlAGB^|l za|PPlypx~KBG7}kod?<#N!z+&Jj;vI2lYrB!n(sd4n0N_W&Nfuv>n%(h$7dW)E}{OQwRH3 z^(*_f6x6t3OsqhUyZjUm=uP1yOAQ2l{!)ayehmbE>;O_o=p*^UWBGzPD*>)@iZac5 z;ChlZW%F7u!M$7>mMi5Cf>z=BFg7OW%bFFM;CIa$wtX1Jb*Sro@cG483q@NbxWgYP zo>X|z4V6lnCxd?ZHUOMJ93+`Y!V49-P*?7z#jY5YJVI^TIGL?4!EgDFfk21=I;&C5r2al!@-bCPc~5=75qf0)2g|56rbjc###OroU7@91qrK z#-$9ZhnB;OyZb2km|vjJ>&4`T%zpIGp8(AKBaH{zgf%KK>y_(1So{C`lWSg*cLB5> zZBd&5{c@mwK~P>43~BP6f3eL$S?g2QpG$d-lm*u#*Htd%^~Kqme!+EP{1n&+!WX0E z+7&BfP&yeyi(*X_#7xSn0X1J@${#6t!G(=f#UoNr++<^C+j6_}UAdheL0&nEnELER z5jv@8u#Czb=jAT^q_jAMBz+}vmQ_i4VjobsKIdAXk9Rt8@?bN7Cj%)1B{Q1>+!E@| zflc}Tz@UKZRrxSppqkfZkxvHhu+xda?ISh>g@Oq_B%FKhib9~ND18r1%K;y@U{T@I++ERpEwu_;fE4=E_4 zPHRnYp4n+#whsP7tEW^uqwR>cAyF3uXa?zOK-QS17=Pu9g^FLc{h7#;sQ5eTE6JBs zUO93V($);cKCjfRpm%uCm*iH*CRBTQmDvO|yVxgNw97`Q%l;{YC zXy-boq&jWsr>YHtvDvIfoiF955-RFHy}44G zECxOo_DgcZ#k+L|^9plF&%vSJiL*?WWtSc0<=Umr;iJ)di?u1Lt4`35&fTy~*$jwY z=DMbCFn80ObGE;$XbuMJDq3gBG9(6&8mJ8bcnRLspi=h9roly??1l_m{hSE)pi0^r z;F6P~+{xtDBXyOVzldG95Eulb3quD*%BXW74vKQ&he+d`o&@$dYS*jukv8gf2O9vT zbFZ&>x@zMW^gllCqIjX@I}vwms^2#AVp7o7^4nH+TO@#&s3Q_&VH-)u1padLr8Wd^ z8DdYl&AWC?>&NfqPzLI9HVC>bncu;>konCr(me++ye@nfpuBPizfq93R7%63Ex~#? zXz{tqwPVjwH%(of%+6C)-uCBqyfD1I5s>(0%gW&;->E>qyqf_|te63el{u4e&=X1~ zPqoUk%5j5Cn3mwrg(AE~CGb-x{2*vtkPn<6%1hGQa@H^Dur1LbLT4H0$O9SrB)E3i z4tlIq-!j;j1J+Z?#z1V#ExVlSkg}vLl0JD9?@(eaN&rXX;A72Y0pI6CKreDVqK_#r z$ZK>=hxL}2Q>Eq{gL(qgyyTpeGGu<5G|pG>qCi=cS!})D>p|;NE zOX+RfLGnSsLw;EdQJEF+-AzChgMFN%62}v#3uSbm@lH=1XXs$Hos=v3B&x;^&Q|UO zgR!(_#dvoEK-X&Z`9*+wnc$Y z+)|HkCgaO?q&!ebr_JF?k^KBTu9T-fm7A7N=JIeS^5&4IM2bUqsN-Q!0RG4!;FT;x zJ&-0sJI&J;_1jRkw9`74r^;lx)&?QqP5%#iGr%>6IT1HMIj4hl2per@<}cP^x`tzj z@ug>`5LOPdI+J}DSW3BCp6W(DlPX7I9-cfqK` zwPB#AOa*)dhcNJiXW9ns>@;`=78O*i04;%9>vZ4_zHhJW!(eXP3a^5yv5Vw0!B#c^ z_)A2z*Fq5BDPyohpo1QN0jbjr{5Dd0BY?k##8_%wH29lx>^kf~Z^~75D7m@YXPuEd zfBPu_`Ec%p0o@MnmGZJ#4a?Q*Qv$IrPX{ra6`5=Rg7TlcbI(D~OFgsNU%B4sv5sknzev=5Uxg { const allPlugins = pluginApi.all_plugins(); res.json(allPlugins); }); +app.post("/filters", async (req, res) => { + const filters = await pluginApi.getFilter(req.body['pluginRequirePath']); + res.json(filters || []); +}) app.post("/popularNovels/", async (req, res) => { const filters = req.body["filters"] || {}; const showLatestNovels = req.body["showLatestNovels"] || false; diff --git a/js/plugins/arabic/ArMTL[madara].js b/js/plugins/arabic/ArMTL[madara].js deleted file mode 100644 index 86d9c38..0000000 --- a/js/plugins/arabic/ArMTL[madara].js +++ /dev/null @@ -1,178 +0,0 @@ -"use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.filters = exports.fetchImage = exports.searchNovels = exports.parseChapter = exports.parseNovelAndChapters = exports.popularNovels = exports.site = exports.version = exports.icon = exports.name = exports.id = void 0; -const cheerio_1 = require("cheerio"); -const fetch_1 = require("@libs/fetch"); -const defaultCover_1 = require("@libs/defaultCover"); -const novelStatus_1 = require("@libs/novelStatus"); -const parseMadaraDate_1 = require("@libs/parseMadaraDate"); -const dayjs_1 = __importDefault(require("dayjs")); -exports.id = "ar-mtl"; -exports.name = "ArMTL [madara]"; -exports.icon = "multisrc/madara/icons/armtl.png"; -exports.version = "1.0.0"; -exports.site = "https://ar-mtl.club/"; -const baseUrl = exports.site; -const popularNovels = (pageNo, { filters, showLatestNovels }) => __awaiter(void 0, void 0, void 0, function* () { - const novels = []; - let url = exports.site; - if (filters === null || filters === void 0 ? void 0 : filters.genres) { - url += "novel-genre/" + filters.genres + '/'; - } - else { - url += "novel/"; - } - url += '/page/' + pageNo + '/' + - '?m_orderby=' + (showLatestNovels ? 'latest' : ((filters === null || filters === void 0 ? void 0 : filters.sort) || 'rating')); - const body = yield (0, fetch_1.fetchApi)(url).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.manga-title-badges').remove(); - loadedCheerio('.page-item-detail').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - let novelUrl = loadedCheerio(this).find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - }); - return novels; -}); -exports.popularNovels = popularNovels; -const parseNovelAndChapters = (novelUrl) => __awaiter(void 0, void 0, void 0, function* () { - const novel = { - url: novelUrl, - }; - const body = yield (0, fetch_1.fetchApi)(novelUrl).then(res => res.text()); - let loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.manga-title-badges').remove(); - novel.name = loadedCheerio('.post-title h1').text().trim(); - novel.cover = - loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || - loadedCheerio('.summary_image > a > img').attr('data-src') || - loadedCheerio('.summary_image > a > img').attr('src') || - defaultCover_1.defaultCover; - loadedCheerio('.post-content_item, .post-content').each(function () { - const detailName = loadedCheerio(this).find('h5').text().trim(); - const detail = loadedCheerio(this).find('.summary-content').text().trim(); - switch (detailName) { - case 'Genre(s)': - case 'التصنيفات': - novel.genres = detail.replace(/[\t\n]/g, ','); - break; - case 'Author(s)': - case 'المؤلف': - case 'المؤلف (ين)': - novel.author = detail; - break; - case 'Status': - case 'الحالة': - novel.status = - detail.includes('OnGoing') || detail.includes('مستمرة') - ? novelStatus_1.NovelStatus.Ongoing - : novelStatus_1.NovelStatus.Completed; - break; - } - }); - loadedCheerio('div.summary__content .code-block,script').remove(); - novel.summary = loadedCheerio('div.summary__content').text().trim(); - let html; - if (true) { - const novelId = loadedCheerio('.rating-post-id').attr('value') || - loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; - const body = { - action: "manga_get_chapters", - manga: novelId, - }; - html = yield (0, fetch_1.fetchApi)(baseUrl + 'wp-admin/admin-ajax.php', { - method: 'POST', - body: JSON.stringify(body), - }) - .then(res => res.text()); - } - else { - html = yield (0, fetch_1.fetchApi)(baseUrl + 'ajax/chapters/', { method: 'POST' }) - .then(res => res.text()); - } - if (html !== '0') { - loadedCheerio = (0, cheerio_1.load)(html); - } - const chapters = []; - loadedCheerio('.wp-manga-chapter').each(function () { - const chapterName = loadedCheerio(this).find('a').text().trim(); - let releaseDate = null; - releaseDate = loadedCheerio(this) - .find('span.chapter-release-date') - .text() - .trim(); - if (releaseDate) { - releaseDate = (0, parseMadaraDate_1.parseMadaraDate)(releaseDate); - } - else { - /** - * Insert current date - */ - releaseDate = (0, dayjs_1.default)().format('LL'); - } - let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; - chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); - }); - novel.chapters = chapters.reverse(); - return novel; -}); -exports.parseNovelAndChapters = parseNovelAndChapters; -const parseChapter = (chapterUrl) => __awaiter(void 0, void 0, void 0, function* () { - const url = baseUrl + "/" + "novel" + "/" + chapterUrl; - const body = yield (0, fetch_1.fetchApi)(chapterUrl).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - const chapterText = loadedCheerio('.text-left').html() || - loadedCheerio('.text-right').html() || - loadedCheerio('.entry-content').html(); - return chapterText; -}); -exports.parseChapter = parseChapter; -const searchNovels = (searchTerm) => __awaiter(void 0, void 0, void 0, function* () { - const novels = []; - const url = baseUrl + "?s=" + searchTerm + "&post_type=wp-manga"; - const body = yield (0, fetch_1.fetchApi)(url).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.c-tabs-item__content').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - let novelUrl = loadedCheerio(this) - .find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - }); - return novels; -}); -exports.searchNovels = searchNovels; -const fetchImage = (url) => __awaiter(void 0, void 0, void 0, function* () { - return yield (0, fetch_1.fetchFile)(url); -}); -exports.fetchImage = fetchImage; -exports.filters = []; diff --git a/js/plugins/arabic/ArNovel[madara].js b/js/plugins/arabic/ArNovel[madara].js deleted file mode 100644 index b501a08..0000000 --- a/js/plugins/arabic/ArNovel[madara].js +++ /dev/null @@ -1,179 +0,0 @@ -"use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.filters = exports.fetchImage = exports.searchNovels = exports.parseChapter = exports.parseNovelAndChapters = exports.popularNovels = exports.site = exports.version = exports.icon = exports.name = exports.id = void 0; -const cheerio_1 = require("cheerio"); -const fetch_1 = require("@libs/fetch"); -const filterInputs_1 = require("@libs/filterInputs"); -const defaultCover_1 = require("@libs/defaultCover"); -const novelStatus_1 = require("@libs/novelStatus"); -const parseMadaraDate_1 = require("@libs/parseMadaraDate"); -const dayjs_1 = __importDefault(require("dayjs")); -exports.id = "arnovel"; -exports.name = "ArNovel [madara]"; -exports.icon = "multisrc/madara/icons/arnovel.png"; -exports.version = "1.0.0"; -exports.site = "https://arnovel.me/"; -const baseUrl = exports.site; -const popularNovels = (pageNo, { filters, showLatestNovels }) => __awaiter(void 0, void 0, void 0, function* () { - const novels = []; - let url = exports.site; - if (filters === null || filters === void 0 ? void 0 : filters.genres) { - url += "home/novel-genre/" + filters.genres + '/'; - } - else { - url += "novel/"; - } - url += '/page/' + pageNo + '/' + - '?m_orderby=' + (showLatestNovels ? 'latest' : ((filters === null || filters === void 0 ? void 0 : filters.sort) || 'rating')); - const body = yield (0, fetch_1.fetchApi)(url).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.manga-title-badges').remove(); - loadedCheerio('.page-item-detail').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - let novelUrl = loadedCheerio(this).find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - }); - return novels; -}); -exports.popularNovels = popularNovels; -const parseNovelAndChapters = (novelUrl) => __awaiter(void 0, void 0, void 0, function* () { - const novel = { - url: novelUrl, - }; - const body = yield (0, fetch_1.fetchApi)(novelUrl).then(res => res.text()); - let loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.manga-title-badges').remove(); - novel.name = loadedCheerio('.post-title h1').text().trim(); - novel.cover = - loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || - loadedCheerio('.summary_image > a > img').attr('data-src') || - loadedCheerio('.summary_image > a > img').attr('src') || - defaultCover_1.defaultCover; - loadedCheerio('.post-content_item, .post-content').each(function () { - const detailName = loadedCheerio(this).find('h5').text().trim(); - const detail = loadedCheerio(this).find('.summary-content').text().trim(); - switch (detailName) { - case 'Genre(s)': - case 'التصنيفات': - novel.genres = detail.replace(/[\t\n]/g, ','); - break; - case 'Author(s)': - case 'المؤلف': - case 'المؤلف (ين)': - novel.author = detail; - break; - case 'Status': - case 'الحالة': - novel.status = - detail.includes('OnGoing') || detail.includes('مستمرة') - ? novelStatus_1.NovelStatus.Ongoing - : novelStatus_1.NovelStatus.Completed; - break; - } - }); - loadedCheerio('div.summary__content .code-block,script').remove(); - novel.summary = loadedCheerio('div.summary__content').text().trim(); - let html; - if (true) { - const novelId = loadedCheerio('.rating-post-id').attr('value') || - loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; - const body = { - action: "manga_get_chapters", - manga: novelId, - }; - html = yield (0, fetch_1.fetchApi)(baseUrl + 'wp-admin/admin-ajax.php', { - method: 'POST', - body: JSON.stringify(body), - }) - .then(res => res.text()); - } - else { - html = yield (0, fetch_1.fetchApi)(baseUrl + 'ajax/chapters/', { method: 'POST' }) - .then(res => res.text()); - } - if (html !== '0') { - loadedCheerio = (0, cheerio_1.load)(html); - } - const chapters = []; - loadedCheerio('.wp-manga-chapter').each(function () { - const chapterName = loadedCheerio(this).find('a').text().trim(); - let releaseDate = null; - releaseDate = loadedCheerio(this) - .find('span.chapter-release-date') - .text() - .trim(); - if (releaseDate) { - releaseDate = (0, parseMadaraDate_1.parseMadaraDate)(releaseDate); - } - else { - /** - * Insert current date - */ - releaseDate = (0, dayjs_1.default)().format('LL'); - } - let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; - chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); - }); - novel.chapters = chapters.reverse(); - return novel; -}); -exports.parseNovelAndChapters = parseNovelAndChapters; -const parseChapter = (chapterUrl) => __awaiter(void 0, void 0, void 0, function* () { - const url = baseUrl + "/" + "novel" + "/" + chapterUrl; - const body = yield (0, fetch_1.fetchApi)(chapterUrl).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - const chapterText = loadedCheerio('.text-left').html() || - loadedCheerio('.text-right').html() || - loadedCheerio('.entry-content').html(); - return chapterText; -}); -exports.parseChapter = parseChapter; -const searchNovels = (searchTerm) => __awaiter(void 0, void 0, void 0, function* () { - const novels = []; - const url = baseUrl + "?s=" + searchTerm + "&post_type=wp-manga"; - const body = yield (0, fetch_1.fetchApi)(url).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.c-tabs-item__content').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - let novelUrl = loadedCheerio(this) - .find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - }); - return novels; -}); -exports.searchNovels = searchNovels; -const fetchImage = (url) => __awaiter(void 0, void 0, void 0, function* () { - return yield (0, fetch_1.fetchFile)(url); -}); -exports.fetchImage = fetchImage; -exports.filters = [{ "key": "sort", "label": "الترتيب حسب", "values": [{ "label": "A-Z", "value": "alphabet" }, { "label": "الآخير", "value": "latest" }, { "label": "الأكثر مشاهدة", "value": "views" }, { "label": "التقييم", "value": "rating" }, { "label": "جديد", "value": "new-manga" }, { "label": "شائع", "value": "trending" }], "inputType": filterInputs_1.FilterInputs.Picker }, { "key": "genres", "label": "التصنيفات", "values": [{ "label": "أكشن", "value": "%d8%a3%d9%83%d8%b4%d9%86" }, { "label": "إتشي", "value": "%d8%a5%d8%aa%d8%b4%d9%80%d9%8a" }, { "label": "بالغ", "value": "%d8%a8%d8%a7%d9%84%d8%ba" }, { "label": "تاريخي", "value": "%d8%aa%d8%a7%d8%b1%d9%8a%d8%ae%d9%8a" }, { "label": "تراجدي", "value": "%d8%aa%d8%b1%d8%a7%d8%ac%d8%af%d9%8a" }, { "label": "جوسي", "value": "%d8%ac%d9%88%d8%b3%d9%8a" }, { "label": "حريم", "value": "%d8%ad%d8%b1%d9%8a%d9%85" }, { "label": "حياة مدرسية", "value": "%d8%ad%d9%8a%d8%a7%d8%a9-%d9%85%d8%af%d8%b1%d8%b3%d9%8a%d8%a9" }, { "label": "خارق لطبيعية", "value": "%d8%ae%d8%a7%d8%b1%d9%82-%d9%84%d8%b7%d8%a8%d9%8a%d8%b9%d9%8a%d8%a9" }, { "label": "خيال", "value": "%d8%ae%d9%8a%d8%a7%d9%84" }, { "label": "خيال علمي", "value": "%d8%ae%d9%8a%d8%a7%d9%84-%d8%b9%d9%84%d9%85%d9%8a" }, { "label": "دراما", "value": "%d8%af%d8%b1%d8%a7%d9%85%d8%a7" }, { "label": "راشد", "value": "%d8%b1%d8%a7%d8%b4%d8%af" }, { "label": "رعب", "value": "%d8%b1%d8%b9%d8%a8" }, { "label": "رومنسي", "value": "%d8%b1%d9%88%d9%85%d9%86%d8%b3%d9%8a" }, { "label": "رياضي", "value": "%d8%b1%d9%8a%d8%a7%d8%b6%d9%8a" }, { "label": "سينين", "value": "%d8%b3%d9%8a%d9%86%d9%8a%d9%86" }, { "label": "شريحة من الحياة", "value": "%d8%b4%d8%b1%d9%8a%d8%ad%d8%a9-%d9%85%d9%86-%d8%a7%d9%84%d8%ad%d9%8a%d8%a7%d8%a9" }, { "label": "شوجو", "value": "%d8%b4%d9%88%d8%ac%d9%88" }, { "label": "شونين", "value": "%d8%b4%d9%88%d9%86%d9%8a%d9%86" }, { "label": "غموض", "value": "%d8%ba%d9%85%d9%88%d8%b6" }, { "label": "فنون قتال", "value": "%d9%81%d9%86%d9%88%d9%86-%d9%82%d8%aa%d8%a7%d9%84" }, { "label": "كوميديا", "value": "%d9%83%d9%88%d9%85%d9%8a%d8%af%d9%8a%d8%a7" }, { "label": "مغامرات", "value": "%d9%85%d8%ba%d8%a7%d9%85%d8%b1%d8%a7%d8%aa" }, { "label": "منتهية", "value": "%d9%85%d9%86%d8%aa%d9%87%d9%8a%d8%a9" }, { "label": "ميكا", "value": "%d9%85%d9%8a%d9%83%d8%a7" }, { "label": "نفسي", "value": "%d9%86%d9%81%d8%b3%d9%8a" }], "inputType": filterInputs_1.FilterInputs.Picker }]; diff --git a/js/plugins/arabic/HizoManga[madara].js b/js/plugins/arabic/HizoManga[madara].js deleted file mode 100644 index e04ed71..0000000 --- a/js/plugins/arabic/HizoManga[madara].js +++ /dev/null @@ -1,179 +0,0 @@ -"use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.filters = exports.fetchImage = exports.searchNovels = exports.parseChapter = exports.parseNovelAndChapters = exports.popularNovels = exports.site = exports.version = exports.icon = exports.name = exports.id = void 0; -const cheerio_1 = require("cheerio"); -const fetch_1 = require("@libs/fetch"); -const filterInputs_1 = require("@libs/filterInputs"); -const defaultCover_1 = require("@libs/defaultCover"); -const novelStatus_1 = require("@libs/novelStatus"); -const parseMadaraDate_1 = require("@libs/parseMadaraDate"); -const dayjs_1 = __importDefault(require("dayjs")); -exports.id = "hizomanga"; -exports.name = "HizoManga [madara]"; -exports.icon = "multisrc/madara/icons/hizomanga.png"; -exports.version = "1.0.0"; -exports.site = "https://hizomanga.com/"; -const baseUrl = exports.site; -const popularNovels = (pageNo, { filters, showLatestNovels }) => __awaiter(void 0, void 0, void 0, function* () { - const novels = []; - let url = exports.site; - if (filters === null || filters === void 0 ? void 0 : filters.genres) { - url += "manga-genre/" + filters.genres + '/'; - } - else { - url += "serie/"; - } - url += '/page/' + pageNo + '/' + - '?m_orderby=' + (showLatestNovels ? 'latest' : ((filters === null || filters === void 0 ? void 0 : filters.sort) || 'rating')); - const body = yield (0, fetch_1.fetchApi)(url).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.manga-title-badges').remove(); - loadedCheerio('.page-item-detail').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - let novelUrl = loadedCheerio(this).find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - }); - return novels; -}); -exports.popularNovels = popularNovels; -const parseNovelAndChapters = (novelUrl) => __awaiter(void 0, void 0, void 0, function* () { - const novel = { - url: novelUrl, - }; - const body = yield (0, fetch_1.fetchApi)(novelUrl).then(res => res.text()); - let loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.manga-title-badges').remove(); - novel.name = loadedCheerio('.post-title h1').text().trim(); - novel.cover = - loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || - loadedCheerio('.summary_image > a > img').attr('data-src') || - loadedCheerio('.summary_image > a > img').attr('src') || - defaultCover_1.defaultCover; - loadedCheerio('.post-content_item, .post-content').each(function () { - const detailName = loadedCheerio(this).find('h5').text().trim(); - const detail = loadedCheerio(this).find('.summary-content').text().trim(); - switch (detailName) { - case 'Genre(s)': - case 'التصنيفات': - novel.genres = detail.replace(/[\t\n]/g, ','); - break; - case 'Author(s)': - case 'المؤلف': - case 'المؤلف (ين)': - novel.author = detail; - break; - case 'Status': - case 'الحالة': - novel.status = - detail.includes('OnGoing') || detail.includes('مستمرة') - ? novelStatus_1.NovelStatus.Ongoing - : novelStatus_1.NovelStatus.Completed; - break; - } - }); - loadedCheerio('div.summary__content .code-block,script').remove(); - novel.summary = loadedCheerio('div.summary__content').text().trim(); - let html; - if (true) { - const novelId = loadedCheerio('.rating-post-id').attr('value') || - loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; - const body = { - action: "manga_get_chapters", - manga: novelId, - }; - html = yield (0, fetch_1.fetchApi)(baseUrl + 'wp-admin/admin-ajax.php', { - method: 'POST', - body: JSON.stringify(body), - }) - .then(res => res.text()); - } - else { - html = yield (0, fetch_1.fetchApi)(baseUrl + 'ajax/chapters/', { method: 'POST' }) - .then(res => res.text()); - } - if (html !== '0') { - loadedCheerio = (0, cheerio_1.load)(html); - } - const chapters = []; - loadedCheerio('.wp-manga-chapter').each(function () { - const chapterName = loadedCheerio(this).find('a').text().trim(); - let releaseDate = null; - releaseDate = loadedCheerio(this) - .find('span.chapter-release-date') - .text() - .trim(); - if (releaseDate) { - releaseDate = (0, parseMadaraDate_1.parseMadaraDate)(releaseDate); - } - else { - /** - * Insert current date - */ - releaseDate = (0, dayjs_1.default)().format('LL'); - } - let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; - chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); - }); - novel.chapters = chapters.reverse(); - return novel; -}); -exports.parseNovelAndChapters = parseNovelAndChapters; -const parseChapter = (chapterUrl) => __awaiter(void 0, void 0, void 0, function* () { - const url = baseUrl + "/" + "serie" + "/" + chapterUrl; - const body = yield (0, fetch_1.fetchApi)(chapterUrl).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - const chapterText = loadedCheerio('.text-left').html() || - loadedCheerio('.text-right').html() || - loadedCheerio('.entry-content').html(); - return chapterText; -}); -exports.parseChapter = parseChapter; -const searchNovels = (searchTerm) => __awaiter(void 0, void 0, void 0, function* () { - const novels = []; - const url = baseUrl + "?s=" + searchTerm + "&post_type=wp-manga"; - const body = yield (0, fetch_1.fetchApi)(url).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.c-tabs-item__content').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - let novelUrl = loadedCheerio(this) - .find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - }); - return novels; -}); -exports.searchNovels = searchNovels; -const fetchImage = (url) => __awaiter(void 0, void 0, void 0, function* () { - return yield (0, fetch_1.fetchFile)(url); -}); -exports.fetchImage = fetchImage; -exports.filters = [{ "key": "sort", "label": "ترتيب حسب", "values": [{ "label": "A-Z", "value": "alphabet" }, { "label": "New", "value": "new-manga" }, { "label": "الأحدث", "value": "latest" }, { "label": "الأكثر مشاهدة", "value": "views" }, { "label": "التقييم", "value": "rating" }, { "label": "الرائج", "value": "trending" }], "inputType": filterInputs_1.FilterInputs.Picker }, { "key": "genres", "label": "التصنيفات", "values": [{ "label": "آلات", "value": "mechanisms" }, { "label": "أكشن", "value": "action" }, { "label": "إثارة", "value": "excitement" }, { "label": "إيسكاي", "value": "%d8%a5%d9%8a%d8%b3%d9%83%d8%a7%d9%8a" }, { "label": "الحياة اليومية", "value": "slice-of-life" }, { "label": "الحياة مدرسية", "value": "school-life" }, { "label": "تاريخي", "value": "historical" }, { "label": "تراجيدي", "value": "tragic" }, { "label": "جريمة", "value": "%d8%ac%d8%b1%d9%8a%d9%85%d8%a9" }, { "label": "جندر بندر", "value": "%d8%ac%d9%86%d8%af%d8%b1-%d8%a8%d9%86%d8%af%d8%b1" }, { "label": "جوسي", "value": "josei" }, { "label": "حريم", "value": "harem" }, { "label": "خارق للطبيعة", "value": "supernatural" }, { "label": "خيال", "value": "fantasy" }, { "label": "خيال علمي", "value": "sci-fi" }, { "label": "دراما", "value": "drama" }, { "label": "دموي", "value": "%d8%af%d9%85%d9%88%d9%8a" }, { "label": "راشد", "value": "mature" }, { "label": "رعب", "value": "horror" }, { "label": "رومانسي", "value": "romance" }, { "label": "رياضة", "value": "sports" }, { "label": "زمنكاني", "value": "my-time" }, { "label": "زومبي", "value": "%d8%b2%d9%88%d9%85%d8%a8%d9%8a" }, { "label": "سينين", "value": "seinen" }, { "label": "شريحة من الحياة", "value": "%d8%b4%d8%b1%d9%8a%d8%ad%d8%a9-%d9%85%d9%86-%d8%a7%d9%84%d8%ad%d9%8a%d8%a7%d8%a9" }, { "label": "شوجو", "value": "shoujo" }, { "label": "شونين", "value": "shounen" }, { "label": "طبي", "value": "%d8%b7%d8%a8%d9%8a" }, { "label": "غموض", "value": "ambiguity" }, { "label": "فنون قتالية", "value": "martial-arts" }, { "label": "قوة خارقة", "value": "superpower" }, { "label": "كوميدي", "value": "comedy" }, { "label": "مغامرات", "value": "adventure" }, { "label": "نفسي", "value": "psychological" }], "inputType": filterInputs_1.FilterInputs.Picker }]; diff --git a/js/plugins/arabic/Novel4Up[madara].js b/js/plugins/arabic/Novel4Up[madara].js deleted file mode 100644 index 17abe7b..0000000 --- a/js/plugins/arabic/Novel4Up[madara].js +++ /dev/null @@ -1,179 +0,0 @@ -"use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.filters = exports.fetchImage = exports.searchNovels = exports.parseChapter = exports.parseNovelAndChapters = exports.popularNovels = exports.site = exports.version = exports.icon = exports.name = exports.id = void 0; -const cheerio_1 = require("cheerio"); -const fetch_1 = require("@libs/fetch"); -const filterInputs_1 = require("@libs/filterInputs"); -const defaultCover_1 = require("@libs/defaultCover"); -const novelStatus_1 = require("@libs/novelStatus"); -const parseMadaraDate_1 = require("@libs/parseMadaraDate"); -const dayjs_1 = __importDefault(require("dayjs")); -exports.id = "novel4up"; -exports.name = "Novel4Up [madara]"; -exports.icon = "multisrc/madara/icons/novel4up.png"; -exports.version = "1.0.0"; -exports.site = "https://novel4up.com/"; -const baseUrl = exports.site; -const popularNovels = (pageNo, { filters, showLatestNovels }) => __awaiter(void 0, void 0, void 0, function* () { - const novels = []; - let url = exports.site; - if (filters === null || filters === void 0 ? void 0 : filters.genres) { - url += "novel-genre/" + filters.genres + '/'; - } - else { - url += "novel/"; - } - url += '/page/' + pageNo + '/' + - '?m_orderby=' + (showLatestNovels ? 'latest' : ((filters === null || filters === void 0 ? void 0 : filters.sort) || 'rating')); - const body = yield (0, fetch_1.fetchApi)(url).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.manga-title-badges').remove(); - loadedCheerio('.page-item-detail').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - let novelUrl = loadedCheerio(this).find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - }); - return novels; -}); -exports.popularNovels = popularNovels; -const parseNovelAndChapters = (novelUrl) => __awaiter(void 0, void 0, void 0, function* () { - const novel = { - url: novelUrl, - }; - const body = yield (0, fetch_1.fetchApi)(novelUrl).then(res => res.text()); - let loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.manga-title-badges').remove(); - novel.name = loadedCheerio('.post-title h1').text().trim(); - novel.cover = - loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || - loadedCheerio('.summary_image > a > img').attr('data-src') || - loadedCheerio('.summary_image > a > img').attr('src') || - defaultCover_1.defaultCover; - loadedCheerio('.post-content_item, .post-content').each(function () { - const detailName = loadedCheerio(this).find('h5').text().trim(); - const detail = loadedCheerio(this).find('.summary-content').text().trim(); - switch (detailName) { - case 'Genre(s)': - case 'التصنيفات': - novel.genres = detail.replace(/[\t\n]/g, ','); - break; - case 'Author(s)': - case 'المؤلف': - case 'المؤلف (ين)': - novel.author = detail; - break; - case 'Status': - case 'الحالة': - novel.status = - detail.includes('OnGoing') || detail.includes('مستمرة') - ? novelStatus_1.NovelStatus.Ongoing - : novelStatus_1.NovelStatus.Completed; - break; - } - }); - loadedCheerio('div.summary__content .code-block,script').remove(); - novel.summary = loadedCheerio('div.summary__content').text().trim(); - let html; - if (false) { - const novelId = loadedCheerio('.rating-post-id').attr('value') || - loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; - const body = { - action: "manga_get_chapters", - manga: novelId, - }; - html = yield (0, fetch_1.fetchApi)(baseUrl + 'wp-admin/admin-ajax.php', { - method: 'POST', - body: JSON.stringify(body), - }) - .then(res => res.text()); - } - else { - html = yield (0, fetch_1.fetchApi)(baseUrl + 'ajax/chapters/', { method: 'POST' }) - .then(res => res.text()); - } - if (html !== '0') { - loadedCheerio = (0, cheerio_1.load)(html); - } - const chapters = []; - loadedCheerio('.wp-manga-chapter').each(function () { - const chapterName = loadedCheerio(this).find('a').text().trim(); - let releaseDate = null; - releaseDate = loadedCheerio(this) - .find('span.chapter-release-date') - .text() - .trim(); - if (releaseDate) { - releaseDate = (0, parseMadaraDate_1.parseMadaraDate)(releaseDate); - } - else { - /** - * Insert current date - */ - releaseDate = (0, dayjs_1.default)().format('LL'); - } - let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; - chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); - }); - novel.chapters = chapters.reverse(); - return novel; -}); -exports.parseNovelAndChapters = parseNovelAndChapters; -const parseChapter = (chapterUrl) => __awaiter(void 0, void 0, void 0, function* () { - const url = baseUrl + "/" + "novel" + "/" + chapterUrl; - const body = yield (0, fetch_1.fetchApi)(chapterUrl).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - const chapterText = loadedCheerio('.text-left').html() || - loadedCheerio('.text-right').html() || - loadedCheerio('.entry-content').html(); - return chapterText; -}); -exports.parseChapter = parseChapter; -const searchNovels = (searchTerm) => __awaiter(void 0, void 0, void 0, function* () { - const novels = []; - const url = baseUrl + "?s=" + searchTerm + "&post_type=wp-manga"; - const body = yield (0, fetch_1.fetchApi)(url).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.c-tabs-item__content').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - let novelUrl = loadedCheerio(this) - .find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - }); - return novels; -}); -exports.searchNovels = searchNovels; -const fetchImage = (url) => __awaiter(void 0, void 0, void 0, function* () { - return yield (0, fetch_1.fetchFile)(url); -}); -exports.fetchImage = fetchImage; -exports.filters = [{ "key": "sort", "label": "ترتيب حسب:", "values": [{ "label": "أ-ي", "value": "alphabet" }, { "label": "الأحدث", "value": "latest" }, { "label": "الأكثر مشاهدة", "value": "views" }, { "label": "التقييم", "value": "rating" }, { "label": "الجديد", "value": "new-manga" }, { "label": "الشائع", "value": "trending" }], "inputType": filterInputs_1.FilterInputs.Picker }, { "key": "genres", "label": "التصنيفات", "values": [{ "label": "أكشن", "value": "action" }, { "label": "الخارق للطبيعة", "value": "supernatural" }, { "label": "تاريخي", "value": "historical" }, { "label": "تحقيق", "value": "detective" }, { "label": "تراجيديا", "value": "tragedy" }, { "label": "حريم", "value": "harem" }, { "label": "حياة مدرسية", "value": "school-life" }, { "label": "خيال علمي", "value": "sci-fi" }, { "label": "دراما", "value": "drama" }, { "label": "رعب", "value": "horror" }, { "label": "رومانسي", "value": "romance" }, { "label": "رياضة", "value": "sports" }, { "label": "سحر", "value": "magic" }, { "label": "شريحة من الحياة", "value": "slice-of-life" }, { "label": "شوانهوا", "value": "xuanhuan" }, { "label": "شوجو", "value": "shoujo" }, { "label": "شونين", "value": "shounen" }, { "label": "غموض", "value": "mystery" }, { "label": "فانتازيا", "value": "fantasy" }, { "label": "فنون قتال", "value": "martial-arts" }, { "label": "كوميديا", "value": "comedy" }, { "label": "مغامرة", "value": "adventure" }, { "label": "ميكا", "value": "mecha" }, { "label": "نفسي", "value": "psychological" }, { "label": "ون شوت", "value": "one-shot" }, { "label": "ووشيا", "value": "wuxia" }], "inputType": filterInputs_1.FilterInputs.Picker }]; diff --git a/js/plugins/arabic/Riwyat[madara].js b/js/plugins/arabic/Riwyat[madara].js deleted file mode 100644 index 23e6154..0000000 --- a/js/plugins/arabic/Riwyat[madara].js +++ /dev/null @@ -1,179 +0,0 @@ -"use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.filters = exports.fetchImage = exports.searchNovels = exports.parseChapter = exports.parseNovelAndChapters = exports.popularNovels = exports.site = exports.version = exports.icon = exports.name = exports.id = void 0; -const cheerio_1 = require("cheerio"); -const fetch_1 = require("@libs/fetch"); -const filterInputs_1 = require("@libs/filterInputs"); -const defaultCover_1 = require("@libs/defaultCover"); -const novelStatus_1 = require("@libs/novelStatus"); -const parseMadaraDate_1 = require("@libs/parseMadaraDate"); -const dayjs_1 = __importDefault(require("dayjs")); -exports.id = "riwyat"; -exports.name = "Riwyat [madara]"; -exports.icon = "multisrc/madara/icons/riwyat.png"; -exports.version = "1.0.0"; -exports.site = "https://riwyat.com/"; -const baseUrl = exports.site; -const popularNovels = (pageNo, { filters, showLatestNovels }) => __awaiter(void 0, void 0, void 0, function* () { - const novels = []; - let url = exports.site; - if (filters === null || filters === void 0 ? void 0 : filters.genres) { - url += "novel-genre/" + filters.genres + '/'; - } - else { - url += "novel/"; - } - url += '/page/' + pageNo + '/' + - '?m_orderby=' + (showLatestNovels ? 'latest' : ((filters === null || filters === void 0 ? void 0 : filters.sort) || 'rating')); - const body = yield (0, fetch_1.fetchApi)(url).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.manga-title-badges').remove(); - loadedCheerio('.page-item-detail').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - let novelUrl = loadedCheerio(this).find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - }); - return novels; -}); -exports.popularNovels = popularNovels; -const parseNovelAndChapters = (novelUrl) => __awaiter(void 0, void 0, void 0, function* () { - const novel = { - url: novelUrl, - }; - const body = yield (0, fetch_1.fetchApi)(novelUrl).then(res => res.text()); - let loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.manga-title-badges').remove(); - novel.name = loadedCheerio('.post-title h1').text().trim(); - novel.cover = - loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || - loadedCheerio('.summary_image > a > img').attr('data-src') || - loadedCheerio('.summary_image > a > img').attr('src') || - defaultCover_1.defaultCover; - loadedCheerio('.post-content_item, .post-content').each(function () { - const detailName = loadedCheerio(this).find('h5').text().trim(); - const detail = loadedCheerio(this).find('.summary-content').text().trim(); - switch (detailName) { - case 'Genre(s)': - case 'التصنيفات': - novel.genres = detail.replace(/[\t\n]/g, ','); - break; - case 'Author(s)': - case 'المؤلف': - case 'المؤلف (ين)': - novel.author = detail; - break; - case 'Status': - case 'الحالة': - novel.status = - detail.includes('OnGoing') || detail.includes('مستمرة') - ? novelStatus_1.NovelStatus.Ongoing - : novelStatus_1.NovelStatus.Completed; - break; - } - }); - loadedCheerio('div.summary__content .code-block,script').remove(); - novel.summary = loadedCheerio('div.summary__content').text().trim(); - let html; - if (true) { - const novelId = loadedCheerio('.rating-post-id').attr('value') || - loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; - const body = { - action: "manga_get_chapters", - manga: novelId, - }; - html = yield (0, fetch_1.fetchApi)(baseUrl + 'wp-admin/admin-ajax.php', { - method: 'POST', - body: JSON.stringify(body), - }) - .then(res => res.text()); - } - else { - html = yield (0, fetch_1.fetchApi)(baseUrl + 'ajax/chapters/', { method: 'POST' }) - .then(res => res.text()); - } - if (html !== '0') { - loadedCheerio = (0, cheerio_1.load)(html); - } - const chapters = []; - loadedCheerio('.wp-manga-chapter').each(function () { - const chapterName = loadedCheerio(this).find('a').text().trim(); - let releaseDate = null; - releaseDate = loadedCheerio(this) - .find('span.chapter-release-date') - .text() - .trim(); - if (releaseDate) { - releaseDate = (0, parseMadaraDate_1.parseMadaraDate)(releaseDate); - } - else { - /** - * Insert current date - */ - releaseDate = (0, dayjs_1.default)().format('LL'); - } - let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; - chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); - }); - novel.chapters = chapters.reverse(); - return novel; -}); -exports.parseNovelAndChapters = parseNovelAndChapters; -const parseChapter = (chapterUrl) => __awaiter(void 0, void 0, void 0, function* () { - const url = baseUrl + "/" + "novel" + "/" + chapterUrl; - const body = yield (0, fetch_1.fetchApi)(chapterUrl).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - const chapterText = loadedCheerio('.text-left').html() || - loadedCheerio('.text-right').html() || - loadedCheerio('.entry-content').html(); - return chapterText; -}); -exports.parseChapter = parseChapter; -const searchNovels = (searchTerm) => __awaiter(void 0, void 0, void 0, function* () { - const novels = []; - const url = baseUrl + "?s=" + searchTerm + "&post_type=wp-manga"; - const body = yield (0, fetch_1.fetchApi)(url).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.c-tabs-item__content').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - let novelUrl = loadedCheerio(this) - .find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - }); - return novels; -}); -exports.searchNovels = searchNovels; -const fetchImage = (url) => __awaiter(void 0, void 0, void 0, function* () { - return yield (0, fetch_1.fetchFile)(url); -}); -exports.fetchImage = fetchImage; -exports.filters = [{ "key": "sort", "label": "Order by", "values": [{ "label": "Rating", "value": "rating" }, { "label": "A-Z", "value": "alphabet" }, { "label": "Latest", "value": "latest" }, { "label": "Most Views", "value": "views" }, { "label": "New", "value": "new-manga" }, { "label": "Trending", "value": "trending" }], "inputType": filterInputs_1.FilterInputs.Picker }, { "key": "genres", "label": "GENRES", "values": [{ "label": "أكشن", "value": "%d8%a3%d9%83%d8%b4%d9%86" }, { "label": "أيتشي", "value": "%d8%a3%d9%8a%d8%aa%d8%b4%d9%8a" }, { "label": "استراتجي", "value": "%d8%a7%d8%b3%d8%aa%d8%b1%d8%a7%d8%aa%d8%ac%d9%8a" }, { "label": "العصر الحديث", "value": "%d8%a7%d9%84%d8%b9%d8%b5%d8%b1-%d8%a7%d9%84%d8%ad%d8%af%d9%8a%d8%ab" }, { "label": "انتقام", "value": "%d8%a7%d9%86%d8%aa%d9%82%d8%a7%d9%85" }, { "label": "بالغ", "value": "%d8%a8%d8%a7%d9%84%d8%ba" }, { "label": "بناء مملكة", "value": "%d8%a8%d9%86%d8%a7%d8%a1-%d9%85%d9%85%d9%84%d9%83%d8%a9" }, { "label": "بوليسي", "value": "%d8%a8%d9%88%d9%84%d9%8a%d8%b3%d9%8a" }, { "label": "تاريخي", "value": "%d8%aa%d8%a7%d8%b1%d9%8a%d8%ae%d9%8a" }, { "label": "جوسي", "value": "%d8%ac%d9%88%d8%b3%d9%8a" }, { "label": "حريم", "value": "%d8%ad%d8%b1%d9%8a%d9%85" }, { "label": "حياة يومية", "value": "%d8%ad%d9%8a%d8%a7%d8%a9-%d9%8a%d9%88%d9%85%d9%8a%d8%a9" }, { "label": "خيال", "value": "%d8%ae%d9%8a%d8%a7%d9%84" }, { "label": "خيال علمي", "value": "%d8%ae%d9%8a%d8%a7%d9%84-%d8%b9%d9%84%d9%85%d9%8a" }, { "label": "دراما", "value": "%d8%af%d8%b1%d8%a7%d9%85%d8%a7" }, { "label": "رعب", "value": "%d8%b1%d8%b9%d8%a8" }, { "label": "رومانسية", "value": "%d8%b1%d9%88%d9%85%d8%a7%d9%86%d8%b3%d9%8a%d8%a9" }, { "label": "رياضي", "value": "%d8%b1%d9%8a%d8%a7%d8%b6%d9%8a" }, { "label": "زيانشيا", "value": "xianxia" }, { "label": "سنين", "value": "%d8%b3%d9%86%d9%8a%d9%86" }, { "label": "شريحة حياة", "value": "%d8%b4%d8%b1%d9%8a%d8%ad%d8%a9-%d8%ad%d9%8a%d8%a7%d8%a9" }, { "label": "شوانهوان", "value": "xuanhuan" }, { "label": "شوجو", "value": "%d8%b4%d9%88%d8%ac%d9%88" }, { "label": "شونين", "value": "%d8%b4%d9%88%d9%86%d9%8a%d9%86" }, { "label": "شيانشيا", "value": "%d8%b4%d9%8a%d8%a7%d9%86%d8%b4%d9%8a%d8%a7" }, { "label": "عسكري", "value": "%d8%b9%d8%b3%d9%83%d8%b1%d9%8a" }, { "label": "غموض", "value": "%d8%ba%d9%85%d9%88%d8%b6" }, { "label": "فانتازيا", "value": "%d9%81%d8%a7%d9%86%d8%aa%d8%a7%d8%b2%d9%8a%d8%a7" }, { "label": "فنون قتالية", "value": "%d9%81%d9%86%d9%88%d9%86-%d9%82%d8%aa%d8%a7%d9%84%d9%8a%d8%a9" }, { "label": "قوى خارقة", "value": "%d9%82%d9%88%d9%89-%d8%ae%d8%a7%d8%b1%d9%82%d8%a9" }, { "label": "كوميديا", "value": "%d9%83%d9%88%d9%85%d9%8a%d8%af%d9%8a%d8%a7" }, { "label": "كوميك", "value": "%d9%83%d9%88%d9%85%d9%8a%d9%83" }, { "label": "للكبار", "value": "%d9%84%d9%84%d9%83%d8%a8%d8%a7%d8%b1" }, { "label": "مأساة", "value": "%d9%85%d8%a3%d8%b3%d8%a7%d8%a9" }, { "label": "مانجا", "value": "%d9%85%d8%a7%d9%86%d8%ac%d8%a7" }, { "label": "مانها", "value": "%d9%85%d8%a7%d9%86%d9%87%d8%a7" }, { "label": "مانهوا", "value": "%d9%85%d8%a7%d9%86%d9%87%d9%88%d8%a7" }, { "label": "مدرسي", "value": "%d9%85%d8%af%d8%b1%d8%b3%d9%8a" }, { "label": "مصاصي دماء", "value": "%d9%85%d8%b5%d8%a7%d8%b5%d9%8a-%d8%af%d9%85%d8%a7%d8%a1" }, { "label": "مغامرة", "value": "%d9%85%d8%ba%d8%a7%d9%85%d8%b1%d8%a9" }, { "label": "مكتملة", "value": "%d9%85%d9%83%d8%aa%d9%85%d9%84%d8%a9" }, { "label": "نفسي", "value": "%d9%86%d9%81%d8%b3%d9%8a" }, { "label": "نهاية العالم", "value": "%d9%86%d9%87%d8%a7%d9%8a%d8%a9-%d8%a7%d9%84%d8%b9%d8%a7%d9%84%d9%85" }, { "label": "واب تون", "value": "%d9%88%d8%a7%d8%a8-%d8%aa%d9%88%d9%86" }, { "label": "وان شوت", "value": "%d9%88%d8%a7%d9%86-%d8%b4%d9%88%d8%aa" }], "inputType": filterInputs_1.FilterInputs.Picker }]; diff --git a/js/plugins/arabic/TeamXNovel[madara].js b/js/plugins/arabic/TeamXNovel[madara].js deleted file mode 100644 index 1f1a49d..0000000 --- a/js/plugins/arabic/TeamXNovel[madara].js +++ /dev/null @@ -1,178 +0,0 @@ -"use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.filters = exports.fetchImage = exports.searchNovels = exports.parseChapter = exports.parseNovelAndChapters = exports.popularNovels = exports.site = exports.version = exports.icon = exports.name = exports.id = void 0; -const cheerio_1 = require("cheerio"); -const fetch_1 = require("@libs/fetch"); -const defaultCover_1 = require("@libs/defaultCover"); -const novelStatus_1 = require("@libs/novelStatus"); -const parseMadaraDate_1 = require("@libs/parseMadaraDate"); -const dayjs_1 = __importDefault(require("dayjs")); -exports.id = "teamxnovel"; -exports.name = "TeamXNovel [madara]"; -exports.icon = "multisrc/madara/icons/teamxnovel.png"; -exports.version = "1.0.0"; -exports.site = "https://teamxnovel.com/"; -const baseUrl = exports.site; -const popularNovels = (pageNo, { filters, showLatestNovels }) => __awaiter(void 0, void 0, void 0, function* () { - const novels = []; - let url = exports.site; - if (filters === null || filters === void 0 ? void 0 : filters.genres) { - url += "novel-genre/" + filters.genres + '/'; - } - else { - url += "novel/"; - } - url += '/page/' + pageNo + '/' + - '?m_orderby=' + (showLatestNovels ? 'latest' : ((filters === null || filters === void 0 ? void 0 : filters.sort) || 'rating')); - const body = yield (0, fetch_1.fetchApi)(url).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.manga-title-badges').remove(); - loadedCheerio('.page-item-detail').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - let novelUrl = loadedCheerio(this).find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - }); - return novels; -}); -exports.popularNovels = popularNovels; -const parseNovelAndChapters = (novelUrl) => __awaiter(void 0, void 0, void 0, function* () { - const novel = { - url: novelUrl, - }; - const body = yield (0, fetch_1.fetchApi)(novelUrl).then(res => res.text()); - let loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.manga-title-badges').remove(); - novel.name = loadedCheerio('.post-title h1').text().trim(); - novel.cover = - loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || - loadedCheerio('.summary_image > a > img').attr('data-src') || - loadedCheerio('.summary_image > a > img').attr('src') || - defaultCover_1.defaultCover; - loadedCheerio('.post-content_item, .post-content').each(function () { - const detailName = loadedCheerio(this).find('h5').text().trim(); - const detail = loadedCheerio(this).find('.summary-content').text().trim(); - switch (detailName) { - case 'Genre(s)': - case 'التصنيفات': - novel.genres = detail.replace(/[\t\n]/g, ','); - break; - case 'Author(s)': - case 'المؤلف': - case 'المؤلف (ين)': - novel.author = detail; - break; - case 'Status': - case 'الحالة': - novel.status = - detail.includes('OnGoing') || detail.includes('مستمرة') - ? novelStatus_1.NovelStatus.Ongoing - : novelStatus_1.NovelStatus.Completed; - break; - } - }); - loadedCheerio('div.summary__content .code-block,script').remove(); - novel.summary = loadedCheerio('div.summary__content').text().trim(); - let html; - if (true) { - const novelId = loadedCheerio('.rating-post-id').attr('value') || - loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; - const body = { - action: "manga_get_chapters", - manga: novelId, - }; - html = yield (0, fetch_1.fetchApi)(baseUrl + 'wp-admin/admin-ajax.php', { - method: 'POST', - body: JSON.stringify(body), - }) - .then(res => res.text()); - } - else { - html = yield (0, fetch_1.fetchApi)(baseUrl + 'ajax/chapters/', { method: 'POST' }) - .then(res => res.text()); - } - if (html !== '0') { - loadedCheerio = (0, cheerio_1.load)(html); - } - const chapters = []; - loadedCheerio('.wp-manga-chapter').each(function () { - const chapterName = loadedCheerio(this).find('a').text().trim(); - let releaseDate = null; - releaseDate = loadedCheerio(this) - .find('span.chapter-release-date') - .text() - .trim(); - if (releaseDate) { - releaseDate = (0, parseMadaraDate_1.parseMadaraDate)(releaseDate); - } - else { - /** - * Insert current date - */ - releaseDate = (0, dayjs_1.default)().format('LL'); - } - let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; - chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); - }); - novel.chapters = chapters.reverse(); - return novel; -}); -exports.parseNovelAndChapters = parseNovelAndChapters; -const parseChapter = (chapterUrl) => __awaiter(void 0, void 0, void 0, function* () { - const url = baseUrl + "/" + "novel" + "/" + chapterUrl; - const body = yield (0, fetch_1.fetchApi)(chapterUrl).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - const chapterText = loadedCheerio('.text-left').html() || - loadedCheerio('.text-right').html() || - loadedCheerio('.entry-content').html(); - return chapterText; -}); -exports.parseChapter = parseChapter; -const searchNovels = (searchTerm) => __awaiter(void 0, void 0, void 0, function* () { - const novels = []; - const url = baseUrl + "?s=" + searchTerm + "&post_type=wp-manga"; - const body = yield (0, fetch_1.fetchApi)(url).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.c-tabs-item__content').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - let novelUrl = loadedCheerio(this) - .find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - }); - return novels; -}); -exports.searchNovels = searchNovels; -const fetchImage = (url) => __awaiter(void 0, void 0, void 0, function* () { - return yield (0, fetch_1.fetchFile)(url); -}); -exports.fetchImage = fetchImage; -exports.filters = []; diff --git a/js/plugins/arabic/kolnovel.js b/js/plugins/arabic/kolnovel.js deleted file mode 100644 index b5456f3..0000000 --- a/js/plugins/arabic/kolnovel.js +++ /dev/null @@ -1,244 +0,0 @@ -"use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.filters = exports.fetchImage = exports.searchNovels = exports.parseChapter = exports.parseNovelAndChapters = exports.popularNovels = exports.site = exports.icon = exports.version = exports.name = exports.id = void 0; -const cheerio_1 = require("cheerio"); -const fetch_1 = require("@libs/fetch"); -const filterInputs_1 = require("@libs/filterInputs"); -exports.id = "kolnovel"; -exports.name = "KolNovel"; -exports.version = "1.0.0"; -exports.icon = "multisrc/wpmangastream/icons/kolnovel.png"; -exports.site = "https://kolnovel.com/"; -const pluginId = exports.id; -const baseUrl = exports.site; -const popularNovels = function (page, { filters }) { - return __awaiter(this, void 0, void 0, function* () { - let link = `${baseUrl}series/?page=${page}`; - if (filters) { - if (Array.isArray(filters.genres) && filters.genres.length) { - link += filters.genres.map((i) => `&genre[]=${i}`).join(""); - } - if (Array.isArray(filters.type) && filters.type.length) - link += filters.type.map((i) => `&lang[]=${i}`).join(""); - } - link += "&status=" + ((filters === null || filters === void 0 ? void 0 : filters.status) ? filters.status : ""); - link += "&order=" + ((filters === null || filters === void 0 ? void 0 : filters.order) ? filters.order : "popular"); - const body = yield (0, fetch_1.fetchApi)(link, {}, pluginId).then((result) => result.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - const novels = []; - loadedCheerio("article.maindet").each(function () { - const novelName = loadedCheerio(this).find("h2").text(); - let image = loadedCheerio(this).find("img"); - const novelCover = image.attr("data-src") || image.attr("src"); - const novelUrl = loadedCheerio(this).find("h2 a").attr("href"); - if (!novelUrl) - return; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - }); - return novels; - }); -}; -exports.popularNovels = popularNovels; -const parseNovelAndChapters = function parseNovelAndChapters(novelUrl) { - return __awaiter(this, void 0, void 0, function* () { - const url = novelUrl; - const result = yield (0, fetch_1.fetchApi)(url, {}, pluginId); - const body = yield result.text(); - let loadedCheerio = (0, cheerio_1.load)(body); - const novel = { - url, - chapters: [], - }; - novel.name = loadedCheerio("h1.entry-title").text(); - novel.cover = - loadedCheerio("img.wp-post-image").attr("data-src") || - loadedCheerio("img.wp-post-image").attr("src"); - loadedCheerio("div.serl:nth-child(3) > span").each(function () { - const detailName = loadedCheerio(this).text().trim(); - const detail = loadedCheerio(this).next().text().trim(); - switch (detailName) { - case "الكاتب": - case "Author": - novel.author = detail; - break; - } - }); - novel.status = loadedCheerio("div.sertostat > span").attr("class"); - novel.genres = loadedCheerio(".sertogenre") - .children("a") - .map((i, el) => loadedCheerio(el).text()) - .toArray() - .join(","); - novel.summary = loadedCheerio(".sersys") - .find("br") - .replaceWith("\n") - .end() - .text(); - let chapter = []; - loadedCheerio(".eplister") - .find("li") - .each(function () { - const chapterName = loadedCheerio(this).find(".epl-num").text() + - " - " + - loadedCheerio(this).find(".epl-title").text(); - const releaseDate = loadedCheerio(this) - .find(".epl-date") - .text() - .trim(); - const chapterUrl = loadedCheerio(this).find("a").attr("href"); - if (!chapterUrl) - return; - chapter.push({ - name: chapterName, - releaseTime: releaseDate, - url: chapterUrl, - }); - }); - novel.chapters = chapter.reverse(); - return novel; - }); -}; -exports.parseNovelAndChapters = parseNovelAndChapters; -const parseChapter = function parseChapter(chapterUrl) { - return __awaiter(this, void 0, void 0, function* () { - const result = yield (0, fetch_1.fetchApi)(chapterUrl, {}, pluginId); - const body = yield result.text(); - const loadedCheerio = (0, cheerio_1.load)(body); - let ignore = loadedCheerio(".epcontent > p").next().attr("class"); - loadedCheerio(`p.${ignore}`).remove(); - let chapterText = loadedCheerio(".epcontent").html(); - return chapterText; - }); -}; -exports.parseChapter = parseChapter; -const searchNovels = function searchNovels(searchTerm) { - return __awaiter(this, void 0, void 0, function* () { - const url = `${baseUrl}?s=${searchTerm}`; - const result = yield (0, fetch_1.fetchApi)(url, {}, pluginId); - const body = yield result.text(); - const loadedCheerio = (0, cheerio_1.load)(body); - const novels = []; - loadedCheerio("article.maindet").each(function () { - const novelName = loadedCheerio(this).find("h2").text(); - let image = loadedCheerio(this).find("img"); - const novelCover = image.attr("data-src") || image.attr("src"); - const novelUrl = loadedCheerio(this).find("h2 a").attr("href"); - if (!novelUrl) - return; - novels.push({ - name: novelName, - url: novelUrl, - cover: novelCover, - }); - }); - return novels; - }); -}; -exports.searchNovels = searchNovels; -const fetchImage = function fetchImage(url) { - return __awaiter(this, void 0, void 0, function* () { - const headers = { - Referer: baseUrl, - }; - return yield (0, fetch_1.fetchFile)(url, { headers: headers }); - }); -}; -exports.fetchImage = fetchImage; -exports.filters = [ - { - key: "order", - label: "ترتيب حسب", - values: [ - { label: "الإعداد الأولي", value: "" }, - { label: "A-Z", value: "title" }, - { label: "Z-A", value: "titlereverse" }, - { label: "أخر التحديثات", value: "update" }, - { label: "أخر ما تم إضافته", value: "latest" }, - { label: "الرائجة", value: "popular" }, - ], - inputType: filterInputs_1.FilterInputs.Picker, - }, - { - key: "status", - label: "الحالة", - values: [ - { label: "All", value: "" }, - { label: "Ongoing", value: "ongoing" }, - { label: "Hiatus", value: "hiatus" }, - { label: "Completed", value: "completed" }, - ], - inputType: filterInputs_1.FilterInputs.Picker, - }, - { - key: "type", - label: "النوع", - values: [ - { label: "إنجليزية", value: "english" }, - { label: "روايةلايت", value: "light-novel" }, - { label: "روايةويب", value: "web-novel" }, - { label: "صينية", value: "chinese" }, - { label: "عربية", value: "arabic" }, - { label: "كورية", value: "korean" }, - { label: "يابانية", value: "japanese" }, - ], - inputType: filterInputs_1.FilterInputs.Checkbox, - }, - { - key: "genres", - label: "تصنيف", - values: [ - { label: "Wuxia", value: "wuxia" }, - { label: "Xianxia", value: "xianxia" }, - { label: "XUANHUAN", value: "xuanhuan" }, - { label: "أكشن", value: "action" }, - { label: "إثارة", value: "excitement" }, - { label: "إنتقالالىعالمأخر", value: "isekai" }, - { label: "إيتشي", value: "etchi" }, - { label: "الخيالالعلمي", value: "sci-fi" }, - { label: "بوليسي", value: "policy" }, - { label: "تاريخي", value: "historical" }, - { label: "تحقيقات", value: "%d8%aa%d8%ad%d9%82%d9%8a%d9%82" }, - { label: "تقمصشخصيات", value: "rpg" }, - { label: "جريمة", value: "crime" }, - { label: "جوسى", value: "josei" }, - { label: "حريم", value: "harem" }, - { label: "حياةمدرسية", value: "school-life" }, - { label: "خيالي(فانتازيا)", value: "fantasy" }, - { label: "دراما", value: "drama" }, - { label: "رعب", value: "horror" }, - { label: "رومانسي", value: "romantic" }, - { label: "سحر", value: "magic" }, - { label: "سينن", value: "senen" }, - { label: "شريحةمنالحياة", value: "slice-of-life" }, - { label: "شوجو", value: "shojo" }, - { label: "شونين", value: "shonen" }, - { label: "طبي", value: "medical" }, - { label: "ظواهرخارقةللطبيعة", value: "supernatural" }, - { label: "غموض", value: "mysteries" }, - { label: "فنونالقتال", value: "martial-arts" }, - { label: "قوىخارقة", value: "superpower" }, - { label: "كوميدي", value: "comedy" }, - { label: "مأساوي", value: "tragedy" }, - { label: "مابعدالكارثة", value: "after-the-disaster" }, - { label: "مغامرة", value: "adventure" }, - { label: "ميكا", value: "mechanical" }, - { label: "ناضج", value: "mature" }, - { label: "نفسي", value: "psychological" }, - ], - inputType: filterInputs_1.FilterInputs.Checkbox, - }, -]; diff --git a/js/plugins/english/BoxNovel[madara].js b/js/plugins/english/BoxNovel[madara].js deleted file mode 100644 index 257fad8..0000000 --- a/js/plugins/english/BoxNovel[madara].js +++ /dev/null @@ -1,179 +0,0 @@ -"use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.filters = exports.fetchImage = exports.searchNovels = exports.parseChapter = exports.parseNovelAndChapters = exports.popularNovels = exports.site = exports.version = exports.icon = exports.name = exports.id = void 0; -const cheerio_1 = require("cheerio"); -const fetch_1 = require("@libs/fetch"); -const filterInputs_1 = require("@libs/filterInputs"); -const defaultCover_1 = require("@libs/defaultCover"); -const novelStatus_1 = require("@libs/novelStatus"); -const parseMadaraDate_1 = require("@libs/parseMadaraDate"); -const dayjs_1 = __importDefault(require("dayjs")); -exports.id = "boxnovel"; -exports.name = "BoxNovel [madara]"; -exports.icon = "multisrc/madara/icons/boxnovel.png"; -exports.version = "1.0.0"; -exports.site = "https://boxnovel.com/"; -const baseUrl = exports.site; -const popularNovels = (pageNo, { filters, showLatestNovels }) => __awaiter(void 0, void 0, void 0, function* () { - const novels = []; - let url = exports.site; - if (filters === null || filters === void 0 ? void 0 : filters.genres) { - url += "manga-genre/" + filters.genres + '/'; - } - else { - url += "novel/"; - } - url += '/page/' + pageNo + '/' + - '?m_orderby=' + (showLatestNovels ? 'latest' : ((filters === null || filters === void 0 ? void 0 : filters.sort) || 'rating')); - const body = yield (0, fetch_1.fetchApi)(url).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.manga-title-badges').remove(); - loadedCheerio('.page-item-detail').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - let novelUrl = loadedCheerio(this).find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - }); - return novels; -}); -exports.popularNovels = popularNovels; -const parseNovelAndChapters = (novelUrl) => __awaiter(void 0, void 0, void 0, function* () { - const novel = { - url: novelUrl, - }; - const body = yield (0, fetch_1.fetchApi)(novelUrl).then(res => res.text()); - let loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.manga-title-badges').remove(); - novel.name = loadedCheerio('.post-title h1').text().trim(); - novel.cover = - loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || - loadedCheerio('.summary_image > a > img').attr('data-src') || - loadedCheerio('.summary_image > a > img').attr('src') || - defaultCover_1.defaultCover; - loadedCheerio('.post-content_item, .post-content').each(function () { - const detailName = loadedCheerio(this).find('h5').text().trim(); - const detail = loadedCheerio(this).find('.summary-content').text().trim(); - switch (detailName) { - case 'Genre(s)': - case 'التصنيفات': - novel.genres = detail.replace(/[\t\n]/g, ','); - break; - case 'Author(s)': - case 'المؤلف': - case 'المؤلف (ين)': - novel.author = detail; - break; - case 'Status': - case 'الحالة': - novel.status = - detail.includes('OnGoing') || detail.includes('مستمرة') - ? novelStatus_1.NovelStatus.Ongoing - : novelStatus_1.NovelStatus.Completed; - break; - } - }); - loadedCheerio('div.summary__content .code-block,script').remove(); - novel.summary = loadedCheerio('div.summary__content').text().trim(); - let html; - if (true) { - const novelId = loadedCheerio('.rating-post-id').attr('value') || - loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; - const body = { - action: "manga_get_chapters", - manga: novelId, - }; - html = yield (0, fetch_1.fetchApi)(baseUrl + 'wp-admin/admin-ajax.php', { - method: 'POST', - body: JSON.stringify(body), - }) - .then(res => res.text()); - } - else { - html = yield (0, fetch_1.fetchApi)(baseUrl + 'ajax/chapters/', { method: 'POST' }) - .then(res => res.text()); - } - if (html !== '0') { - loadedCheerio = (0, cheerio_1.load)(html); - } - const chapters = []; - loadedCheerio('.wp-manga-chapter').each(function () { - const chapterName = loadedCheerio(this).find('a').text().trim(); - let releaseDate = null; - releaseDate = loadedCheerio(this) - .find('span.chapter-release-date') - .text() - .trim(); - if (releaseDate) { - releaseDate = (0, parseMadaraDate_1.parseMadaraDate)(releaseDate); - } - else { - /** - * Insert current date - */ - releaseDate = (0, dayjs_1.default)().format('LL'); - } - let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; - chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); - }); - novel.chapters = chapters.reverse(); - return novel; -}); -exports.parseNovelAndChapters = parseNovelAndChapters; -const parseChapter = (chapterUrl) => __awaiter(void 0, void 0, void 0, function* () { - const url = baseUrl + "/" + "novel" + "/" + chapterUrl; - const body = yield (0, fetch_1.fetchApi)(chapterUrl).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - const chapterText = loadedCheerio('.text-left').html() || - loadedCheerio('.text-right').html() || - loadedCheerio('.entry-content').html(); - return chapterText; -}); -exports.parseChapter = parseChapter; -const searchNovels = (searchTerm) => __awaiter(void 0, void 0, void 0, function* () { - const novels = []; - const url = baseUrl + "?s=" + searchTerm + "&post_type=wp-manga"; - const body = yield (0, fetch_1.fetchApi)(url).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.c-tabs-item__content').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - let novelUrl = loadedCheerio(this) - .find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - }); - return novels; -}); -exports.searchNovels = searchNovels; -const fetchImage = (url) => __awaiter(void 0, void 0, void 0, function* () { - return yield (0, fetch_1.fetchFile)(url); -}); -exports.fetchImage = fetchImage; -exports.filters = [{ "key": "sort", "label": "Order by", "values": [{ "label": "Rating", "value": "rating" }, { "label": "A-Z", "value": "alphabet" }, { "label": "Latest", "value": "latest" }, { "label": "Most Views", "value": "views" }, { "label": "New", "value": "new-manga" }, { "label": "Trending", "value": "trending" }], "inputType": filterInputs_1.FilterInputs.Picker }, { "key": "genres", "label": "GENRES", "values": [{ "label": "Action", "value": "action" }, { "label": "Adventure", "value": "adventure" }, { "label": "Comedy", "value": "comedy" }, { "label": "Drama", "value": "drama" }, { "label": "Ecchi", "value": "ecchi" }, { "label": "Fantasy", "value": "fantasy" }, { "label": "Gender Bender", "value": "gender-bender" }, { "label": "Harem", "value": "harem" }, { "label": "Historical", "value": "historical" }, { "label": "Horror", "value": "horror" }, { "label": "Josei", "value": "josei" }, { "label": "Martial Arts", "value": "martial-arts" }, { "label": "Mature", "value": "mature" }, { "label": "Mecha", "value": "mecha" }, { "label": "Mystery", "value": "mystery" }, { "label": "Psychological", "value": "psychological" }, { "label": "Romance", "value": "romance" }, { "label": "School Life", "value": "school-life" }, { "label": "Sci-fi", "value": "sci-fi" }, { "label": "Seinen", "value": "seinen" }, { "label": "Shoujo", "value": "shoujo" }, { "label": "Shounen", "value": "shounen" }, { "label": "Slice of Life", "value": "slice-of-life" }, { "label": "Smut", "value": "smut" }, { "label": "Sports", "value": "sports" }, { "label": "Supernatural", "value": "supernatural" }, { "label": "Tragedy", "value": "tragedy" }, { "label": "Wuxia", "value": "wuxia" }, { "label": "Xianxia", "value": "xianxia" }, { "label": "Xuanhuan", "value": "xuanhuan" }, { "label": "Yaoi", "value": "yaoi" }], "inputType": filterInputs_1.FilterInputs.Picker }]; diff --git a/js/plugins/english/ClickNovel[madara].js b/js/plugins/english/ClickNovel[madara].js deleted file mode 100644 index c70ec04..0000000 --- a/js/plugins/english/ClickNovel[madara].js +++ /dev/null @@ -1,178 +0,0 @@ -"use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.filters = exports.fetchImage = exports.searchNovels = exports.parseChapter = exports.parseNovelAndChapters = exports.popularNovels = exports.site = exports.version = exports.icon = exports.name = exports.id = void 0; -const cheerio_1 = require("cheerio"); -const fetch_1 = require("@libs/fetch"); -const defaultCover_1 = require("@libs/defaultCover"); -const novelStatus_1 = require("@libs/novelStatus"); -const parseMadaraDate_1 = require("@libs/parseMadaraDate"); -const dayjs_1 = __importDefault(require("dayjs")); -exports.id = "clicknovel"; -exports.name = "ClickNovel [madara]"; -exports.icon = "multisrc/madara/icons/clicknovel.png"; -exports.version = "1.0.0"; -exports.site = "https://clicknovel.net/"; -const baseUrl = exports.site; -const popularNovels = (pageNo, { filters, showLatestNovels }) => __awaiter(void 0, void 0, void 0, function* () { - const novels = []; - let url = exports.site; - if (filters === null || filters === void 0 ? void 0 : filters.genres) { - url += "novel-genre/" + filters.genres + '/'; - } - else { - url += "novel/"; - } - url += '/page/' + pageNo + '/' + - '?m_orderby=' + (showLatestNovels ? 'latest' : ((filters === null || filters === void 0 ? void 0 : filters.sort) || 'rating')); - const body = yield (0, fetch_1.fetchApi)(url).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.manga-title-badges').remove(); - loadedCheerio('.page-item-detail').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - let novelUrl = loadedCheerio(this).find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - }); - return novels; -}); -exports.popularNovels = popularNovels; -const parseNovelAndChapters = (novelUrl) => __awaiter(void 0, void 0, void 0, function* () { - const novel = { - url: novelUrl, - }; - const body = yield (0, fetch_1.fetchApi)(novelUrl).then(res => res.text()); - let loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.manga-title-badges').remove(); - novel.name = loadedCheerio('.post-title h1').text().trim(); - novel.cover = - loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || - loadedCheerio('.summary_image > a > img').attr('data-src') || - loadedCheerio('.summary_image > a > img').attr('src') || - defaultCover_1.defaultCover; - loadedCheerio('.post-content_item, .post-content').each(function () { - const detailName = loadedCheerio(this).find('h5').text().trim(); - const detail = loadedCheerio(this).find('.summary-content').text().trim(); - switch (detailName) { - case 'Genre(s)': - case 'التصنيفات': - novel.genres = detail.replace(/[\t\n]/g, ','); - break; - case 'Author(s)': - case 'المؤلف': - case 'المؤلف (ين)': - novel.author = detail; - break; - case 'Status': - case 'الحالة': - novel.status = - detail.includes('OnGoing') || detail.includes('مستمرة') - ? novelStatus_1.NovelStatus.Ongoing - : novelStatus_1.NovelStatus.Completed; - break; - } - }); - loadedCheerio('div.summary__content .code-block,script').remove(); - novel.summary = loadedCheerio('div.summary__content').text().trim(); - let html; - if (false) { - const novelId = loadedCheerio('.rating-post-id').attr('value') || - loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; - const body = { - action: "manga_get_chapters", - manga: novelId, - }; - html = yield (0, fetch_1.fetchApi)(baseUrl + 'wp-admin/admin-ajax.php', { - method: 'POST', - body: JSON.stringify(body), - }) - .then(res => res.text()); - } - else { - html = yield (0, fetch_1.fetchApi)(baseUrl + 'ajax/chapters/', { method: 'POST' }) - .then(res => res.text()); - } - if (html !== '0') { - loadedCheerio = (0, cheerio_1.load)(html); - } - const chapters = []; - loadedCheerio('.wp-manga-chapter').each(function () { - const chapterName = loadedCheerio(this).find('a').text().trim(); - let releaseDate = null; - releaseDate = loadedCheerio(this) - .find('span.chapter-release-date') - .text() - .trim(); - if (releaseDate) { - releaseDate = (0, parseMadaraDate_1.parseMadaraDate)(releaseDate); - } - else { - /** - * Insert current date - */ - releaseDate = (0, dayjs_1.default)().format('LL'); - } - let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; - chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); - }); - novel.chapters = chapters.reverse(); - return novel; -}); -exports.parseNovelAndChapters = parseNovelAndChapters; -const parseChapter = (chapterUrl) => __awaiter(void 0, void 0, void 0, function* () { - const url = baseUrl + "/" + "novel" + "/" + chapterUrl; - const body = yield (0, fetch_1.fetchApi)(chapterUrl).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - const chapterText = loadedCheerio('.text-left').html() || - loadedCheerio('.text-right').html() || - loadedCheerio('.entry-content').html(); - return chapterText; -}); -exports.parseChapter = parseChapter; -const searchNovels = (searchTerm) => __awaiter(void 0, void 0, void 0, function* () { - const novels = []; - const url = baseUrl + "?s=" + searchTerm + "&post_type=wp-manga"; - const body = yield (0, fetch_1.fetchApi)(url).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.c-tabs-item__content').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - let novelUrl = loadedCheerio(this) - .find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - }); - return novels; -}); -exports.searchNovels = searchNovels; -const fetchImage = (url) => __awaiter(void 0, void 0, void 0, function* () { - return yield (0, fetch_1.fetchFile)(url); -}); -exports.fetchImage = fetchImage; -exports.filters = []; diff --git a/js/plugins/english/CrateNovel[madara].js b/js/plugins/english/CrateNovel[madara].js deleted file mode 100644 index 7e684fe..0000000 --- a/js/plugins/english/CrateNovel[madara].js +++ /dev/null @@ -1,178 +0,0 @@ -"use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.filters = exports.fetchImage = exports.searchNovels = exports.parseChapter = exports.parseNovelAndChapters = exports.popularNovels = exports.site = exports.version = exports.icon = exports.name = exports.id = void 0; -const cheerio_1 = require("cheerio"); -const fetch_1 = require("@libs/fetch"); -const defaultCover_1 = require("@libs/defaultCover"); -const novelStatus_1 = require("@libs/novelStatus"); -const parseMadaraDate_1 = require("@libs/parseMadaraDate"); -const dayjs_1 = __importDefault(require("dayjs")); -exports.id = "cratenovel"; -exports.name = "CrateNovel [madara]"; -exports.icon = "multisrc/madara/icons/cratenovel.png"; -exports.version = "1.0.0"; -exports.site = "https://cratenovel.com/"; -const baseUrl = exports.site; -const popularNovels = (pageNo, { filters, showLatestNovels }) => __awaiter(void 0, void 0, void 0, function* () { - const novels = []; - let url = exports.site; - if (filters === null || filters === void 0 ? void 0 : filters.genres) { - url += "novel-genre/" + filters.genres + '/'; - } - else { - url += "novel/"; - } - url += '/page/' + pageNo + '/' + - '?m_orderby=' + (showLatestNovels ? 'latest' : ((filters === null || filters === void 0 ? void 0 : filters.sort) || 'rating')); - const body = yield (0, fetch_1.fetchApi)(url).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.manga-title-badges').remove(); - loadedCheerio('.page-item-detail').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - let novelUrl = loadedCheerio(this).find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - }); - return novels; -}); -exports.popularNovels = popularNovels; -const parseNovelAndChapters = (novelUrl) => __awaiter(void 0, void 0, void 0, function* () { - const novel = { - url: novelUrl, - }; - const body = yield (0, fetch_1.fetchApi)(novelUrl).then(res => res.text()); - let loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.manga-title-badges').remove(); - novel.name = loadedCheerio('.post-title h1').text().trim(); - novel.cover = - loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || - loadedCheerio('.summary_image > a > img').attr('data-src') || - loadedCheerio('.summary_image > a > img').attr('src') || - defaultCover_1.defaultCover; - loadedCheerio('.post-content_item, .post-content').each(function () { - const detailName = loadedCheerio(this).find('h5').text().trim(); - const detail = loadedCheerio(this).find('.summary-content').text().trim(); - switch (detailName) { - case 'Genre(s)': - case 'التصنيفات': - novel.genres = detail.replace(/[\t\n]/g, ','); - break; - case 'Author(s)': - case 'المؤلف': - case 'المؤلف (ين)': - novel.author = detail; - break; - case 'Status': - case 'الحالة': - novel.status = - detail.includes('OnGoing') || detail.includes('مستمرة') - ? novelStatus_1.NovelStatus.Ongoing - : novelStatus_1.NovelStatus.Completed; - break; - } - }); - loadedCheerio('div.summary__content .code-block,script').remove(); - novel.summary = loadedCheerio('div.summary__content').text().trim(); - let html; - if (true) { - const novelId = loadedCheerio('.rating-post-id').attr('value') || - loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; - const body = { - action: "manga_get_chapters", - manga: novelId, - }; - html = yield (0, fetch_1.fetchApi)(baseUrl + 'wp-admin/admin-ajax.php', { - method: 'POST', - body: JSON.stringify(body), - }) - .then(res => res.text()); - } - else { - html = yield (0, fetch_1.fetchApi)(baseUrl + 'ajax/chapters/', { method: 'POST' }) - .then(res => res.text()); - } - if (html !== '0') { - loadedCheerio = (0, cheerio_1.load)(html); - } - const chapters = []; - loadedCheerio('.wp-manga-chapter').each(function () { - const chapterName = loadedCheerio(this).find('a').text().trim(); - let releaseDate = null; - releaseDate = loadedCheerio(this) - .find('span.chapter-release-date') - .text() - .trim(); - if (releaseDate) { - releaseDate = (0, parseMadaraDate_1.parseMadaraDate)(releaseDate); - } - else { - /** - * Insert current date - */ - releaseDate = (0, dayjs_1.default)().format('LL'); - } - let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; - chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); - }); - novel.chapters = chapters.reverse(); - return novel; -}); -exports.parseNovelAndChapters = parseNovelAndChapters; -const parseChapter = (chapterUrl) => __awaiter(void 0, void 0, void 0, function* () { - const url = baseUrl + "/" + "novel" + "/" + chapterUrl; - const body = yield (0, fetch_1.fetchApi)(chapterUrl).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - const chapterText = loadedCheerio('.text-left').html() || - loadedCheerio('.text-right').html() || - loadedCheerio('.entry-content').html(); - return chapterText; -}); -exports.parseChapter = parseChapter; -const searchNovels = (searchTerm) => __awaiter(void 0, void 0, void 0, function* () { - const novels = []; - const url = baseUrl + "?s=" + searchTerm + "&post_type=wp-manga"; - const body = yield (0, fetch_1.fetchApi)(url).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.c-tabs-item__content').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - let novelUrl = loadedCheerio(this) - .find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - }); - return novels; -}); -exports.searchNovels = searchNovels; -const fetchImage = (url) => __awaiter(void 0, void 0, void 0, function* () { - return yield (0, fetch_1.fetchFile)(url); -}); -exports.fetchImage = fetchImage; -exports.filters = []; diff --git a/js/plugins/english/DaoNovel[madara].js b/js/plugins/english/DaoNovel[madara].js deleted file mode 100644 index 9fe4fa1..0000000 --- a/js/plugins/english/DaoNovel[madara].js +++ /dev/null @@ -1,179 +0,0 @@ -"use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.filters = exports.fetchImage = exports.searchNovels = exports.parseChapter = exports.parseNovelAndChapters = exports.popularNovels = exports.site = exports.version = exports.icon = exports.name = exports.id = void 0; -const cheerio_1 = require("cheerio"); -const fetch_1 = require("@libs/fetch"); -const filterInputs_1 = require("@libs/filterInputs"); -const defaultCover_1 = require("@libs/defaultCover"); -const novelStatus_1 = require("@libs/novelStatus"); -const parseMadaraDate_1 = require("@libs/parseMadaraDate"); -const dayjs_1 = __importDefault(require("dayjs")); -exports.id = "daonovel"; -exports.name = "DaoNovel [madara]"; -exports.icon = "multisrc/madara/icons/daonovel.png"; -exports.version = "1.0.0"; -exports.site = "https://daonovel.com/"; -const baseUrl = exports.site; -const popularNovels = (pageNo, { filters, showLatestNovels }) => __awaiter(void 0, void 0, void 0, function* () { - const novels = []; - let url = exports.site; - if (filters === null || filters === void 0 ? void 0 : filters.genres) { - url += "novel-genre/" + filters.genres + '/'; - } - else { - url += "novels-list/"; - } - url += '/page/' + pageNo + '/' + - '?m_orderby=' + (showLatestNovels ? 'latest' : ((filters === null || filters === void 0 ? void 0 : filters.sort) || 'rating')); - const body = yield (0, fetch_1.fetchApi)(url).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.manga-title-badges').remove(); - loadedCheerio('.page-item-detail').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - let novelUrl = loadedCheerio(this).find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - }); - return novels; -}); -exports.popularNovels = popularNovels; -const parseNovelAndChapters = (novelUrl) => __awaiter(void 0, void 0, void 0, function* () { - const novel = { - url: novelUrl, - }; - const body = yield (0, fetch_1.fetchApi)(novelUrl).then(res => res.text()); - let loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.manga-title-badges').remove(); - novel.name = loadedCheerio('.post-title h1').text().trim(); - novel.cover = - loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || - loadedCheerio('.summary_image > a > img').attr('data-src') || - loadedCheerio('.summary_image > a > img').attr('src') || - defaultCover_1.defaultCover; - loadedCheerio('.post-content_item, .post-content').each(function () { - const detailName = loadedCheerio(this).find('h5').text().trim(); - const detail = loadedCheerio(this).find('.summary-content').text().trim(); - switch (detailName) { - case 'Genre(s)': - case 'التصنيفات': - novel.genres = detail.replace(/[\t\n]/g, ','); - break; - case 'Author(s)': - case 'المؤلف': - case 'المؤلف (ين)': - novel.author = detail; - break; - case 'Status': - case 'الحالة': - novel.status = - detail.includes('OnGoing') || detail.includes('مستمرة') - ? novelStatus_1.NovelStatus.Ongoing - : novelStatus_1.NovelStatus.Completed; - break; - } - }); - loadedCheerio('div.summary__content .code-block,script').remove(); - novel.summary = loadedCheerio('div.summary__content').text().trim(); - let html; - if (true) { - const novelId = loadedCheerio('.rating-post-id').attr('value') || - loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; - const body = { - action: "manga_get_chapters", - manga: novelId, - }; - html = yield (0, fetch_1.fetchApi)(baseUrl + 'wp-admin/admin-ajax.php', { - method: 'POST', - body: JSON.stringify(body), - }) - .then(res => res.text()); - } - else { - html = yield (0, fetch_1.fetchApi)(baseUrl + 'ajax/chapters/', { method: 'POST' }) - .then(res => res.text()); - } - if (html !== '0') { - loadedCheerio = (0, cheerio_1.load)(html); - } - const chapters = []; - loadedCheerio('.wp-manga-chapter').each(function () { - const chapterName = loadedCheerio(this).find('a').text().trim(); - let releaseDate = null; - releaseDate = loadedCheerio(this) - .find('span.chapter-release-date') - .text() - .trim(); - if (releaseDate) { - releaseDate = (0, parseMadaraDate_1.parseMadaraDate)(releaseDate); - } - else { - /** - * Insert current date - */ - releaseDate = (0, dayjs_1.default)().format('LL'); - } - let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; - chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); - }); - novel.chapters = chapters.reverse(); - return novel; -}); -exports.parseNovelAndChapters = parseNovelAndChapters; -const parseChapter = (chapterUrl) => __awaiter(void 0, void 0, void 0, function* () { - const url = baseUrl + "/" + "novels" + "/" + chapterUrl; - const body = yield (0, fetch_1.fetchApi)(chapterUrl).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - const chapterText = loadedCheerio('.text-left').html() || - loadedCheerio('.text-right').html() || - loadedCheerio('.entry-content').html(); - return chapterText; -}); -exports.parseChapter = parseChapter; -const searchNovels = (searchTerm) => __awaiter(void 0, void 0, void 0, function* () { - const novels = []; - const url = baseUrl + "?s=" + searchTerm + "&post_type=wp-manga"; - const body = yield (0, fetch_1.fetchApi)(url).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.c-tabs-item__content').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - let novelUrl = loadedCheerio(this) - .find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - }); - return novels; -}); -exports.searchNovels = searchNovels; -const fetchImage = (url) => __awaiter(void 0, void 0, void 0, function* () { - return yield (0, fetch_1.fetchFile)(url); -}); -exports.fetchImage = fetchImage; -exports.filters = [{ "key": "sort", "label": "Order by", "values": [{ "label": "Rating", "value": "rating" }, { "label": "A-Z", "value": "alphabet" }, { "label": "Latest", "value": "latest" }, { "label": "Most Views", "value": "views" }, { "label": "New", "value": "new-manga" }, { "label": "Trending", "value": "trending" }], "inputType": filterInputs_1.FilterInputs.Picker }]; diff --git a/js/plugins/english/FansTranslations[madara].js b/js/plugins/english/FansTranslations[madara].js deleted file mode 100644 index 80e7d3e..0000000 --- a/js/plugins/english/FansTranslations[madara].js +++ /dev/null @@ -1,179 +0,0 @@ -"use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.filters = exports.fetchImage = exports.searchNovels = exports.parseChapter = exports.parseNovelAndChapters = exports.popularNovels = exports.site = exports.version = exports.icon = exports.name = exports.id = void 0; -const cheerio_1 = require("cheerio"); -const fetch_1 = require("@libs/fetch"); -const filterInputs_1 = require("@libs/filterInputs"); -const defaultCover_1 = require("@libs/defaultCover"); -const novelStatus_1 = require("@libs/novelStatus"); -const parseMadaraDate_1 = require("@libs/parseMadaraDate"); -const dayjs_1 = __importDefault(require("dayjs")); -exports.id = "fanTLS"; -exports.name = "Fans Translations [madara]"; -exports.icon = "multisrc/madara/icons/fanstranslations.png"; -exports.version = "1.0.0"; -exports.site = "https://fanstranslations.com/"; -const baseUrl = exports.site; -const popularNovels = (pageNo, { filters, showLatestNovels }) => __awaiter(void 0, void 0, void 0, function* () { - const novels = []; - let url = exports.site; - if (filters === null || filters === void 0 ? void 0 : filters.genres) { - url += "novel-genre/" + filters.genres + '/'; - } - else { - url += "novel/"; - } - url += '/page/' + pageNo + '/' + - '?m_orderby=' + (showLatestNovels ? 'latest' : ((filters === null || filters === void 0 ? void 0 : filters.sort) || 'rating')); - const body = yield (0, fetch_1.fetchApi)(url).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.manga-title-badges').remove(); - loadedCheerio('.page-item-detail').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - let novelUrl = loadedCheerio(this).find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - }); - return novels; -}); -exports.popularNovels = popularNovels; -const parseNovelAndChapters = (novelUrl) => __awaiter(void 0, void 0, void 0, function* () { - const novel = { - url: novelUrl, - }; - const body = yield (0, fetch_1.fetchApi)(novelUrl).then(res => res.text()); - let loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.manga-title-badges').remove(); - novel.name = loadedCheerio('.post-title h1').text().trim(); - novel.cover = - loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || - loadedCheerio('.summary_image > a > img').attr('data-src') || - loadedCheerio('.summary_image > a > img').attr('src') || - defaultCover_1.defaultCover; - loadedCheerio('.post-content_item, .post-content').each(function () { - const detailName = loadedCheerio(this).find('h5').text().trim(); - const detail = loadedCheerio(this).find('.summary-content').text().trim(); - switch (detailName) { - case 'Genre(s)': - case 'التصنيفات': - novel.genres = detail.replace(/[\t\n]/g, ','); - break; - case 'Author(s)': - case 'المؤلف': - case 'المؤلف (ين)': - novel.author = detail; - break; - case 'Status': - case 'الحالة': - novel.status = - detail.includes('OnGoing') || detail.includes('مستمرة') - ? novelStatus_1.NovelStatus.Ongoing - : novelStatus_1.NovelStatus.Completed; - break; - } - }); - loadedCheerio('div.summary__content .code-block,script').remove(); - novel.summary = loadedCheerio('div.summary__content').text().trim(); - let html; - if (true) { - const novelId = loadedCheerio('.rating-post-id').attr('value') || - loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; - const body = { - action: "manga_get_chapters", - manga: novelId, - }; - html = yield (0, fetch_1.fetchApi)(baseUrl + 'wp-admin/admin-ajax.php', { - method: 'POST', - body: JSON.stringify(body), - }) - .then(res => res.text()); - } - else { - html = yield (0, fetch_1.fetchApi)(baseUrl + 'ajax/chapters/', { method: 'POST' }) - .then(res => res.text()); - } - if (html !== '0') { - loadedCheerio = (0, cheerio_1.load)(html); - } - const chapters = []; - loadedCheerio('.wp-manga-chapter').each(function () { - const chapterName = loadedCheerio(this).find('a').text().trim(); - let releaseDate = null; - releaseDate = loadedCheerio(this) - .find('span.chapter-release-date') - .text() - .trim(); - if (releaseDate) { - releaseDate = (0, parseMadaraDate_1.parseMadaraDate)(releaseDate); - } - else { - /** - * Insert current date - */ - releaseDate = (0, dayjs_1.default)().format('LL'); - } - let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; - chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); - }); - novel.chapters = chapters.reverse(); - return novel; -}); -exports.parseNovelAndChapters = parseNovelAndChapters; -const parseChapter = (chapterUrl) => __awaiter(void 0, void 0, void 0, function* () { - const url = baseUrl + "/" + "novel" + "/" + chapterUrl; - const body = yield (0, fetch_1.fetchApi)(chapterUrl).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - const chapterText = loadedCheerio('.text-left').html() || - loadedCheerio('.text-right').html() || - loadedCheerio('.entry-content').html(); - return chapterText; -}); -exports.parseChapter = parseChapter; -const searchNovels = (searchTerm) => __awaiter(void 0, void 0, void 0, function* () { - const novels = []; - const url = baseUrl + "?s=" + searchTerm + "&post_type=wp-manga"; - const body = yield (0, fetch_1.fetchApi)(url).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.c-tabs-item__content').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - let novelUrl = loadedCheerio(this) - .find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - }); - return novels; -}); -exports.searchNovels = searchNovels; -const fetchImage = (url) => __awaiter(void 0, void 0, void 0, function* () { - return yield (0, fetch_1.fetchFile)(url); -}); -exports.fetchImage = fetchImage; -exports.filters = [{ "key": "sort", "label": "Order by", "values": [{ "label": "Rating", "value": "rating" }, { "label": "A-Z", "value": "alphabet" }, { "label": "Latest", "value": "latest" }, { "label": "Most Views", "value": "views" }, { "label": "New", "value": "new-manga" }, { "label": "Trending", "value": "trending" }], "inputType": filterInputs_1.FilterInputs.Picker }]; diff --git a/js/plugins/english/FirstKissNovel[madara].js b/js/plugins/english/FirstKissNovel[madara].js deleted file mode 100644 index adac694..0000000 --- a/js/plugins/english/FirstKissNovel[madara].js +++ /dev/null @@ -1,179 +0,0 @@ -"use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.filters = exports.fetchImage = exports.searchNovels = exports.parseChapter = exports.parseNovelAndChapters = exports.popularNovels = exports.site = exports.version = exports.icon = exports.name = exports.id = void 0; -const cheerio_1 = require("cheerio"); -const fetch_1 = require("@libs/fetch"); -const filterInputs_1 = require("@libs/filterInputs"); -const defaultCover_1 = require("@libs/defaultCover"); -const novelStatus_1 = require("@libs/novelStatus"); -const parseMadaraDate_1 = require("@libs/parseMadaraDate"); -const dayjs_1 = __importDefault(require("dayjs")); -exports.id = "1stkissnovel"; -exports.name = "FirstKissNovel [madara]"; -exports.icon = "multisrc/madara/icons/firstkissnovel.png"; -exports.version = "1.0.0"; -exports.site = "https://1stkissnovel.org/"; -const baseUrl = exports.site; -const popularNovels = (pageNo, { filters, showLatestNovels }) => __awaiter(void 0, void 0, void 0, function* () { - const novels = []; - let url = exports.site; - if (filters === null || filters === void 0 ? void 0 : filters.genres) { - url += "novel-genre/" + filters.genres + '/'; - } - else { - url += "novel/"; - } - url += '/page/' + pageNo + '/' + - '?m_orderby=' + (showLatestNovels ? 'latest' : ((filters === null || filters === void 0 ? void 0 : filters.sort) || 'rating')); - const body = yield (0, fetch_1.fetchApi)(url).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.manga-title-badges').remove(); - loadedCheerio('.page-item-detail').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - let novelUrl = loadedCheerio(this).find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - }); - return novels; -}); -exports.popularNovels = popularNovels; -const parseNovelAndChapters = (novelUrl) => __awaiter(void 0, void 0, void 0, function* () { - const novel = { - url: novelUrl, - }; - const body = yield (0, fetch_1.fetchApi)(novelUrl).then(res => res.text()); - let loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.manga-title-badges').remove(); - novel.name = loadedCheerio('.post-title h1').text().trim(); - novel.cover = - loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || - loadedCheerio('.summary_image > a > img').attr('data-src') || - loadedCheerio('.summary_image > a > img').attr('src') || - defaultCover_1.defaultCover; - loadedCheerio('.post-content_item, .post-content').each(function () { - const detailName = loadedCheerio(this).find('h5').text().trim(); - const detail = loadedCheerio(this).find('.summary-content').text().trim(); - switch (detailName) { - case 'Genre(s)': - case 'التصنيفات': - novel.genres = detail.replace(/[\t\n]/g, ','); - break; - case 'Author(s)': - case 'المؤلف': - case 'المؤلف (ين)': - novel.author = detail; - break; - case 'Status': - case 'الحالة': - novel.status = - detail.includes('OnGoing') || detail.includes('مستمرة') - ? novelStatus_1.NovelStatus.Ongoing - : novelStatus_1.NovelStatus.Completed; - break; - } - }); - loadedCheerio('div.summary__content .code-block,script').remove(); - novel.summary = loadedCheerio('div.summary__content').text().trim(); - let html; - if (true) { - const novelId = loadedCheerio('.rating-post-id').attr('value') || - loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; - const body = { - action: "manga_get_chapters", - manga: novelId, - }; - html = yield (0, fetch_1.fetchApi)(baseUrl + 'wp-admin/admin-ajax.php', { - method: 'POST', - body: JSON.stringify(body), - }) - .then(res => res.text()); - } - else { - html = yield (0, fetch_1.fetchApi)(baseUrl + 'ajax/chapters/', { method: 'POST' }) - .then(res => res.text()); - } - if (html !== '0') { - loadedCheerio = (0, cheerio_1.load)(html); - } - const chapters = []; - loadedCheerio('.wp-manga-chapter').each(function () { - const chapterName = loadedCheerio(this).find('a').text().trim(); - let releaseDate = null; - releaseDate = loadedCheerio(this) - .find('span.chapter-release-date') - .text() - .trim(); - if (releaseDate) { - releaseDate = (0, parseMadaraDate_1.parseMadaraDate)(releaseDate); - } - else { - /** - * Insert current date - */ - releaseDate = (0, dayjs_1.default)().format('LL'); - } - let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; - chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); - }); - novel.chapters = chapters.reverse(); - return novel; -}); -exports.parseNovelAndChapters = parseNovelAndChapters; -const parseChapter = (chapterUrl) => __awaiter(void 0, void 0, void 0, function* () { - const url = baseUrl + "/" + "novel" + "/" + chapterUrl; - const body = yield (0, fetch_1.fetchApi)(chapterUrl).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - const chapterText = loadedCheerio('.text-left').html() || - loadedCheerio('.text-right').html() || - loadedCheerio('.entry-content').html(); - return chapterText; -}); -exports.parseChapter = parseChapter; -const searchNovels = (searchTerm) => __awaiter(void 0, void 0, void 0, function* () { - const novels = []; - const url = baseUrl + "?s=" + searchTerm + "&post_type=wp-manga"; - const body = yield (0, fetch_1.fetchApi)(url).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.c-tabs-item__content').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - let novelUrl = loadedCheerio(this) - .find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - }); - return novels; -}); -exports.searchNovels = searchNovels; -const fetchImage = (url) => __awaiter(void 0, void 0, void 0, function* () { - return yield (0, fetch_1.fetchFile)(url); -}); -exports.fetchImage = fetchImage; -exports.filters = [{ "key": "sort", "label": "Order by", "values": [{ "label": "Rating", "value": "rating" }, { "label": "A-Z", "value": "alphabet" }, { "label": "Latest", "value": "latest" }, { "label": "Most Views", "value": "views" }, { "label": "New", "value": "new-manga" }, { "label": "Trending", "value": "trending" }], "inputType": filterInputs_1.FilterInputs.Picker }, { "key": "genres", "label": "GENRES", "values": [{ "label": "Action", "value": "action" }, { "label": "Adult", "value": "adult" }, { "label": "Adventure", "value": "adventure" }, { "label": "Anime", "value": "anime" }, { "label": "Apocalypse", "value": "apocalypse" }, { "label": "Boy's Love", "value": "boys-love" }, { "label": "Comedy", "value": "comedy" }, { "label": "Completed", "value": "completed" }, { "label": "Cooking", "value": "cooking" }, { "label": "Demons", "value": "demons" }, { "label": "Detective", "value": "detective" }, { "label": "Drama", "value": "drama" }, { "label": "Ecchi", "value": "ecchi" }, { "label": "Fan-Fiction", "value": "fan-fiction" }, { "label": "Fantasy", "value": "fantasy" }, { "label": "Food", "value": "food" }, { "label": "Game", "value": "game" }, { "label": "Gender Bender", "value": "gender-bender" }, { "label": "Girls Love", "value": "girls-love" }, { "label": "Harem", "value": "harem" }, { "label": "Historical", "value": "historical" }, { "label": "Horror", "value": "horror" }, { "label": "Humor", "value": "humor" }, { "label": "Isekai", "value": "isekai" }, { "label": "Josei", "value": "josei" }, { "label": "Magic", "value": "magic" }, { "label": "Magical", "value": "magical" }, { "label": "Manhua", "value": "manhua" }, { "label": "Manhwa", "value": "manhwa" }, { "label": "Martial Arts", "value": "martial-arts" }, { "label": "Mature", "value": "mature" }, { "label": "Mecha", "value": "mecha" }, { "label": "Medical", "value": "medical" }, { "label": "Military", "value": "military" }, { "label": "Moder", "value": "moder" }, { "label": "Modern", "value": "modern" }, { "label": "Murim", "value": "murim" }, { "label": "Music", "value": "music" }, { "label": "Mystery", "value": "mystery" }, { "label": "Psychological", "value": "psychological" }, { "label": "Reverse", "value": "reverse" }, { "label": "Reverse harem", "value": "reverse-harem" }, { "label": "Romance", "value": "romance" }, { "label": "School Life", "value": "school-life" }, { "label": "Sci-fi", "value": "sci-fi" }, { "label": "Seinen", "value": "seinen" }, { "label": "Shoujo", "value": "shoujo" }, { "label": "Shoujo Ai", "value": "shoujo-ai" }, { "label": "Shounen", "value": "shounen" }, { "label": "Shounen Ai", "value": "shounen-ai" }, { "label": "Slice of Life", "value": "slice-of-life" }, { "label": "Smut", "value": "smut" }, { "label": "Sports", "value": "sports" }, { "label": "Super power", "value": "super-power" }, { "label": "Superhero", "value": "superhero" }, { "label": "Supernatural", "value": "supernatural" }, { "label": "Thriller", "value": "thriller" }, { "label": "Tragedy", "value": "tragedy" }, { "label": "Urban Life", "value": "urban-life" }, { "label": "Vampire", "value": "vampire" }, { "label": "Webtoons", "value": "webtoons" }, { "label": "Wuxia", "value": "wuxia" }, { "label": "Xianxia", "value": "xianxia" }, { "label": "Xuanhuan", "value": "xuanhuan" }, { "label": "Yaoi", "value": "yaoi" }, { "label": "Yuri", "value": "yuri" }], "inputType": filterInputs_1.FilterInputs.Picker }]; diff --git a/js/plugins/english/FreeNovelMe[madara].js b/js/plugins/english/FreeNovelMe[madara].js deleted file mode 100644 index 46a40d1..0000000 --- a/js/plugins/english/FreeNovelMe[madara].js +++ /dev/null @@ -1,179 +0,0 @@ -"use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.filters = exports.fetchImage = exports.searchNovels = exports.parseChapter = exports.parseNovelAndChapters = exports.popularNovels = exports.site = exports.version = exports.icon = exports.name = exports.id = void 0; -const cheerio_1 = require("cheerio"); -const fetch_1 = require("@libs/fetch"); -const filterInputs_1 = require("@libs/filterInputs"); -const defaultCover_1 = require("@libs/defaultCover"); -const novelStatus_1 = require("@libs/novelStatus"); -const parseMadaraDate_1 = require("@libs/parseMadaraDate"); -const dayjs_1 = __importDefault(require("dayjs")); -exports.id = "freenovel.me"; -exports.name = "FreeNovelMe [madara]"; -exports.icon = "multisrc/madara/icons/freenovelme.png"; -exports.version = "1.0.0"; -exports.site = "https://freenovel.me/"; -const baseUrl = exports.site; -const popularNovels = (pageNo, { filters, showLatestNovels }) => __awaiter(void 0, void 0, void 0, function* () { - const novels = []; - let url = exports.site; - if (filters === null || filters === void 0 ? void 0 : filters.genres) { - url += "novel-genre/" + filters.genres + '/'; - } - else { - url += "novel/"; - } - url += '/page/' + pageNo + '/' + - '?m_orderby=' + (showLatestNovels ? 'latest' : ((filters === null || filters === void 0 ? void 0 : filters.sort) || 'rating')); - const body = yield (0, fetch_1.fetchApi)(url).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.manga-title-badges').remove(); - loadedCheerio('.page-item-detail').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - let novelUrl = loadedCheerio(this).find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - }); - return novels; -}); -exports.popularNovels = popularNovels; -const parseNovelAndChapters = (novelUrl) => __awaiter(void 0, void 0, void 0, function* () { - const novel = { - url: novelUrl, - }; - const body = yield (0, fetch_1.fetchApi)(novelUrl).then(res => res.text()); - let loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.manga-title-badges').remove(); - novel.name = loadedCheerio('.post-title h1').text().trim(); - novel.cover = - loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || - loadedCheerio('.summary_image > a > img').attr('data-src') || - loadedCheerio('.summary_image > a > img').attr('src') || - defaultCover_1.defaultCover; - loadedCheerio('.post-content_item, .post-content').each(function () { - const detailName = loadedCheerio(this).find('h5').text().trim(); - const detail = loadedCheerio(this).find('.summary-content').text().trim(); - switch (detailName) { - case 'Genre(s)': - case 'التصنيفات': - novel.genres = detail.replace(/[\t\n]/g, ','); - break; - case 'Author(s)': - case 'المؤلف': - case 'المؤلف (ين)': - novel.author = detail; - break; - case 'Status': - case 'الحالة': - novel.status = - detail.includes('OnGoing') || detail.includes('مستمرة') - ? novelStatus_1.NovelStatus.Ongoing - : novelStatus_1.NovelStatus.Completed; - break; - } - }); - loadedCheerio('div.summary__content .code-block,script').remove(); - novel.summary = loadedCheerio('div.summary__content').text().trim(); - let html; - if (false) { - const novelId = loadedCheerio('.rating-post-id').attr('value') || - loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; - const body = { - action: "manga_get_chapters", - manga: novelId, - }; - html = yield (0, fetch_1.fetchApi)(baseUrl + 'wp-admin/admin-ajax.php', { - method: 'POST', - body: JSON.stringify(body), - }) - .then(res => res.text()); - } - else { - html = yield (0, fetch_1.fetchApi)(baseUrl + 'ajax/chapters/', { method: 'POST' }) - .then(res => res.text()); - } - if (html !== '0') { - loadedCheerio = (0, cheerio_1.load)(html); - } - const chapters = []; - loadedCheerio('.wp-manga-chapter').each(function () { - const chapterName = loadedCheerio(this).find('a').text().trim(); - let releaseDate = null; - releaseDate = loadedCheerio(this) - .find('span.chapter-release-date') - .text() - .trim(); - if (releaseDate) { - releaseDate = (0, parseMadaraDate_1.parseMadaraDate)(releaseDate); - } - else { - /** - * Insert current date - */ - releaseDate = (0, dayjs_1.default)().format('LL'); - } - let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; - chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); - }); - novel.chapters = chapters.reverse(); - return novel; -}); -exports.parseNovelAndChapters = parseNovelAndChapters; -const parseChapter = (chapterUrl) => __awaiter(void 0, void 0, void 0, function* () { - const url = baseUrl + "/" + "novel" + "/" + chapterUrl; - const body = yield (0, fetch_1.fetchApi)(chapterUrl).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - const chapterText = loadedCheerio('.text-left').html() || - loadedCheerio('.text-right').html() || - loadedCheerio('.entry-content').html(); - return chapterText; -}); -exports.parseChapter = parseChapter; -const searchNovels = (searchTerm) => __awaiter(void 0, void 0, void 0, function* () { - const novels = []; - const url = baseUrl + "?s=" + searchTerm + "&post_type=wp-manga"; - const body = yield (0, fetch_1.fetchApi)(url).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.c-tabs-item__content').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - let novelUrl = loadedCheerio(this) - .find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - }); - return novels; -}); -exports.searchNovels = searchNovels; -const fetchImage = (url) => __awaiter(void 0, void 0, void 0, function* () { - return yield (0, fetch_1.fetchFile)(url); -}); -exports.fetchImage = fetchImage; -exports.filters = [{ "key": "sort", "label": "Order by", "values": [{ "label": "Rating", "value": "rating" }, { "label": "A-Z", "value": "alphabet" }, { "label": "Latest", "value": "latest" }, { "label": "Most Views", "value": "views" }, { "label": "New", "value": "new-manga" }, { "label": "Trending", "value": "trending" }], "inputType": filterInputs_1.FilterInputs.Picker }, { "key": "genres", "label": "GENRES", "values": [{ "label": "Action", "value": "action" }, { "label": "Adult", "value": "adult" }, { "label": "Adventure", "value": "adventure" }, { "label": "Cartoon", "value": "cartoon" }, { "label": "Comedy", "value": "comedy" }, { "label": "Cooking", "value": "cooking" }, { "label": "Detective", "value": "detective" }, { "label": "Drama", "value": "drama" }, { "label": "Fantasy", "value": "fantasy" }, { "label": "Game", "value": "game" }, { "label": "Gender Bender", "value": "gender-bender" }, { "label": "Historical", "value": "historical" }, { "label": "History", "value": "history" }, { "label": "Horror", "value": "horror" }, { "label": "Josei", "value": "josei" }, { "label": "Live action", "value": "live-action" }, { "label": "Martial", "value": "martial" }, { "label": "Martial Arts", "value": "martial-arts" }, { "label": "Mature", "value": "mature" }, { "label": "Mecha", "value": "mecha" }, { "label": "Mystery", "value": "mystery" }, { "label": "One shot", "value": "one-shot" }, { "label": "Premium", "value": "premium" }, { "label": "Psychological", "value": "psychological" }, { "label": "Reincarnation", "value": "reincarnation" }, { "label": "Romance", "value": "romance" }, { "label": "School Life", "value": "school-life" }, { "label": "Sci-fi", "value": "sci-fi" }, { "label": "Slice of Life", "value": "slice-of-life" }, { "label": "Smut", "value": "smut" }, { "label": "Sports", "value": "sports" }, { "label": "Supernatural", "value": "supernatural" }, { "label": "Tragedy", "value": "tragedy" }, { "label": "Wuxia", "value": "wuxia" }, { "label": "Xianxia", "value": "xianxia" }, { "label": "Xuanhuan", "value": "xuanhuan" }], "inputType": filterInputs_1.FilterInputs.Picker }]; diff --git a/js/plugins/english/Guavaread[madara].js b/js/plugins/english/Guavaread[madara].js deleted file mode 100644 index 17b2363..0000000 --- a/js/plugins/english/Guavaread[madara].js +++ /dev/null @@ -1,179 +0,0 @@ -"use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.filters = exports.fetchImage = exports.searchNovels = exports.parseChapter = exports.parseNovelAndChapters = exports.popularNovels = exports.site = exports.version = exports.icon = exports.name = exports.id = void 0; -const cheerio_1 = require("cheerio"); -const fetch_1 = require("@libs/fetch"); -const filterInputs_1 = require("@libs/filterInputs"); -const defaultCover_1 = require("@libs/defaultCover"); -const novelStatus_1 = require("@libs/novelStatus"); -const parseMadaraDate_1 = require("@libs/parseMadaraDate"); -const dayjs_1 = __importDefault(require("dayjs")); -exports.id = "guavaread"; -exports.name = "Guavaread [madara]"; -exports.icon = "multisrc/madara/icons/guavaread.png"; -exports.version = "1.0.0"; -exports.site = "https://guavaread.com/"; -const baseUrl = exports.site; -const popularNovels = (pageNo, { filters, showLatestNovels }) => __awaiter(void 0, void 0, void 0, function* () { - const novels = []; - let url = exports.site; - if (filters === null || filters === void 0 ? void 0 : filters.genres) { - url += "novel-genre/" + filters.genres + '/'; - } - else { - url += "novel/"; - } - url += '/page/' + pageNo + '/' + - '?m_orderby=' + (showLatestNovels ? 'latest' : ((filters === null || filters === void 0 ? void 0 : filters.sort) || 'rating')); - const body = yield (0, fetch_1.fetchApi)(url).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.manga-title-badges').remove(); - loadedCheerio('.page-item-detail').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - let novelUrl = loadedCheerio(this).find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - }); - return novels; -}); -exports.popularNovels = popularNovels; -const parseNovelAndChapters = (novelUrl) => __awaiter(void 0, void 0, void 0, function* () { - const novel = { - url: novelUrl, - }; - const body = yield (0, fetch_1.fetchApi)(novelUrl).then(res => res.text()); - let loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.manga-title-badges').remove(); - novel.name = loadedCheerio('.post-title h1').text().trim(); - novel.cover = - loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || - loadedCheerio('.summary_image > a > img').attr('data-src') || - loadedCheerio('.summary_image > a > img').attr('src') || - defaultCover_1.defaultCover; - loadedCheerio('.post-content_item, .post-content').each(function () { - const detailName = loadedCheerio(this).find('h5').text().trim(); - const detail = loadedCheerio(this).find('.summary-content').text().trim(); - switch (detailName) { - case 'Genre(s)': - case 'التصنيفات': - novel.genres = detail.replace(/[\t\n]/g, ','); - break; - case 'Author(s)': - case 'المؤلف': - case 'المؤلف (ين)': - novel.author = detail; - break; - case 'Status': - case 'الحالة': - novel.status = - detail.includes('OnGoing') || detail.includes('مستمرة') - ? novelStatus_1.NovelStatus.Ongoing - : novelStatus_1.NovelStatus.Completed; - break; - } - }); - loadedCheerio('div.summary__content .code-block,script').remove(); - novel.summary = loadedCheerio('div.summary__content').text().trim(); - let html; - if (true) { - const novelId = loadedCheerio('.rating-post-id').attr('value') || - loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; - const body = { - action: "manga_get_chapters", - manga: novelId, - }; - html = yield (0, fetch_1.fetchApi)(baseUrl + 'wp-admin/admin-ajax.php', { - method: 'POST', - body: JSON.stringify(body), - }) - .then(res => res.text()); - } - else { - html = yield (0, fetch_1.fetchApi)(baseUrl + 'ajax/chapters/', { method: 'POST' }) - .then(res => res.text()); - } - if (html !== '0') { - loadedCheerio = (0, cheerio_1.load)(html); - } - const chapters = []; - loadedCheerio('.wp-manga-chapter').each(function () { - const chapterName = loadedCheerio(this).find('a').text().trim(); - let releaseDate = null; - releaseDate = loadedCheerio(this) - .find('span.chapter-release-date') - .text() - .trim(); - if (releaseDate) { - releaseDate = (0, parseMadaraDate_1.parseMadaraDate)(releaseDate); - } - else { - /** - * Insert current date - */ - releaseDate = (0, dayjs_1.default)().format('LL'); - } - let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; - chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); - }); - novel.chapters = chapters.reverse(); - return novel; -}); -exports.parseNovelAndChapters = parseNovelAndChapters; -const parseChapter = (chapterUrl) => __awaiter(void 0, void 0, void 0, function* () { - const url = baseUrl + "/" + "novel" + "/" + chapterUrl; - const body = yield (0, fetch_1.fetchApi)(chapterUrl).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - const chapterText = loadedCheerio('.text-left').html() || - loadedCheerio('.text-right').html() || - loadedCheerio('.entry-content').html(); - return chapterText; -}); -exports.parseChapter = parseChapter; -const searchNovels = (searchTerm) => __awaiter(void 0, void 0, void 0, function* () { - const novels = []; - const url = baseUrl + "?s=" + searchTerm + "&post_type=wp-manga"; - const body = yield (0, fetch_1.fetchApi)(url).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.c-tabs-item__content').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - let novelUrl = loadedCheerio(this) - .find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - }); - return novels; -}); -exports.searchNovels = searchNovels; -const fetchImage = (url) => __awaiter(void 0, void 0, void 0, function* () { - return yield (0, fetch_1.fetchFile)(url); -}); -exports.fetchImage = fetchImage; -exports.filters = [{ "key": "sort", "label": "Order by", "values": [{ "label": "Rating", "value": "rating" }, { "label": "A-Z", "value": "alphabet" }, { "label": "Latest", "value": "latest" }, { "label": "Most Views", "value": "views" }, { "label": "New", "value": "new-manga" }, { "label": "Trending", "value": "trending" }], "inputType": filterInputs_1.FilterInputs.Picker }, { "key": "genres", "label": "GENRES", "values": [{ "label": "Action", "value": "action" }, { "label": "Adult", "value": "adult" }, { "label": "Adventure", "value": "adventure" }, { "label": "Comedy", "value": "comedy" }, { "label": "Complete", "value": "complete" }, { "label": "Cooking", "value": "cooking" }, { "label": "Detective", "value": "detective" }, { "label": "Drama", "value": "drama" }, { "label": "Dropped", "value": "dropped" }, { "label": "Ecchi", "value": "ecchi" }, { "label": "Fantasy", "value": "fantasy" }, { "label": "Gender Bender", "value": "gender-bender" }, { "label": "Historical", "value": "historical" }, { "label": "Horror", "value": "horror" }, { "label": "Josei", "value": "josei" }, { "label": "Mature", "value": "mature" }, { "label": "Mystery", "value": "mystery" }, { "label": "Original Story", "value": "original-story" }, { "label": "Pilot", "value": "pilot" }, { "label": "Psychological", "value": "psychological" }, { "label": "R-15", "value": "r-15" }, { "label": "R-19", "value": "r-19" }, { "label": "Reverse Harem", "value": "reverse-harem" }, { "label": "Romance", "value": "romance" }, { "label": "School Life", "value": "school-life" }, { "label": "Sci-fi", "value": "sci-fi" }, { "label": "Shoujo", "value": "shoujo" }, { "label": "Slice of Life", "value": "slice-of-life" }, { "label": "Smut", "value": "smut" }, { "label": "Supernatural", "value": "supernatural" }, { "label": "Tragedy", "value": "tragedy" }], "inputType": filterInputs_1.FilterInputs.Picker }]; diff --git a/js/plugins/english/LightNovelHeaven[madara].js b/js/plugins/english/LightNovelHeaven[madara].js deleted file mode 100644 index ea176fb..0000000 --- a/js/plugins/english/LightNovelHeaven[madara].js +++ /dev/null @@ -1,179 +0,0 @@ -"use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.filters = exports.fetchImage = exports.searchNovels = exports.parseChapter = exports.parseNovelAndChapters = exports.popularNovels = exports.site = exports.version = exports.icon = exports.name = exports.id = void 0; -const cheerio_1 = require("cheerio"); -const fetch_1 = require("@libs/fetch"); -const filterInputs_1 = require("@libs/filterInputs"); -const defaultCover_1 = require("@libs/defaultCover"); -const novelStatus_1 = require("@libs/novelStatus"); -const parseMadaraDate_1 = require("@libs/parseMadaraDate"); -const dayjs_1 = __importDefault(require("dayjs")); -exports.id = "lnheaven"; -exports.name = "LightNovelHeaven [madara]"; -exports.icon = "multisrc/madara/icons/lightnovelheaven.png"; -exports.version = "1.0.0"; -exports.site = "https://lightnovelheaven.com/"; -const baseUrl = exports.site; -const popularNovels = (pageNo, { filters, showLatestNovels }) => __awaiter(void 0, void 0, void 0, function* () { - const novels = []; - let url = exports.site; - if (filters === null || filters === void 0 ? void 0 : filters.genres) { - url += "novel-genre/" + filters.genres + '/'; - } - else { - url += "series/"; - } - url += '/page/' + pageNo + '/' + - '?m_orderby=' + (showLatestNovels ? 'latest' : ((filters === null || filters === void 0 ? void 0 : filters.sort) || 'rating')); - const body = yield (0, fetch_1.fetchApi)(url).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.manga-title-badges').remove(); - loadedCheerio('.page-item-detail').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - let novelUrl = loadedCheerio(this).find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - }); - return novels; -}); -exports.popularNovels = popularNovels; -const parseNovelAndChapters = (novelUrl) => __awaiter(void 0, void 0, void 0, function* () { - const novel = { - url: novelUrl, - }; - const body = yield (0, fetch_1.fetchApi)(novelUrl).then(res => res.text()); - let loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.manga-title-badges').remove(); - novel.name = loadedCheerio('.post-title h1').text().trim(); - novel.cover = - loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || - loadedCheerio('.summary_image > a > img').attr('data-src') || - loadedCheerio('.summary_image > a > img').attr('src') || - defaultCover_1.defaultCover; - loadedCheerio('.post-content_item, .post-content').each(function () { - const detailName = loadedCheerio(this).find('h5').text().trim(); - const detail = loadedCheerio(this).find('.summary-content').text().trim(); - switch (detailName) { - case 'Genre(s)': - case 'التصنيفات': - novel.genres = detail.replace(/[\t\n]/g, ','); - break; - case 'Author(s)': - case 'المؤلف': - case 'المؤلف (ين)': - novel.author = detail; - break; - case 'Status': - case 'الحالة': - novel.status = - detail.includes('OnGoing') || detail.includes('مستمرة') - ? novelStatus_1.NovelStatus.Ongoing - : novelStatus_1.NovelStatus.Completed; - break; - } - }); - loadedCheerio('div.summary__content .code-block,script').remove(); - novel.summary = loadedCheerio('div.summary__content').text().trim(); - let html; - if (true) { - const novelId = loadedCheerio('.rating-post-id').attr('value') || - loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; - const body = { - action: "manga_get_chapters", - manga: novelId, - }; - html = yield (0, fetch_1.fetchApi)(baseUrl + 'wp-admin/admin-ajax.php', { - method: 'POST', - body: JSON.stringify(body), - }) - .then(res => res.text()); - } - else { - html = yield (0, fetch_1.fetchApi)(baseUrl + 'ajax/chapters/', { method: 'POST' }) - .then(res => res.text()); - } - if (html !== '0') { - loadedCheerio = (0, cheerio_1.load)(html); - } - const chapters = []; - loadedCheerio('.wp-manga-chapter').each(function () { - const chapterName = loadedCheerio(this).find('a').text().trim(); - let releaseDate = null; - releaseDate = loadedCheerio(this) - .find('span.chapter-release-date') - .text() - .trim(); - if (releaseDate) { - releaseDate = (0, parseMadaraDate_1.parseMadaraDate)(releaseDate); - } - else { - /** - * Insert current date - */ - releaseDate = (0, dayjs_1.default)().format('LL'); - } - let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; - chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); - }); - novel.chapters = chapters.reverse(); - return novel; -}); -exports.parseNovelAndChapters = parseNovelAndChapters; -const parseChapter = (chapterUrl) => __awaiter(void 0, void 0, void 0, function* () { - const url = baseUrl + "/" + "series" + "/" + chapterUrl; - const body = yield (0, fetch_1.fetchApi)(chapterUrl).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - const chapterText = loadedCheerio('.text-left').html() || - loadedCheerio('.text-right').html() || - loadedCheerio('.entry-content').html(); - return chapterText; -}); -exports.parseChapter = parseChapter; -const searchNovels = (searchTerm) => __awaiter(void 0, void 0, void 0, function* () { - const novels = []; - const url = baseUrl + "?s=" + searchTerm + "&post_type=wp-manga"; - const body = yield (0, fetch_1.fetchApi)(url).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.c-tabs-item__content').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - let novelUrl = loadedCheerio(this) - .find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - }); - return novels; -}); -exports.searchNovels = searchNovels; -const fetchImage = (url) => __awaiter(void 0, void 0, void 0, function* () { - return yield (0, fetch_1.fetchFile)(url); -}); -exports.fetchImage = fetchImage; -exports.filters = [{ "key": "sort", "label": "Order by", "values": [{ "label": "Rating", "value": "rating" }, { "label": "A-Z", "value": "alphabet" }, { "label": "Latest", "value": "latest" }, { "label": "Most Views", "value": "views" }, { "label": "New", "value": "new-manga" }, { "label": "Trending", "value": "trending" }], "inputType": filterInputs_1.FilterInputs.Picker }]; diff --git a/js/plugins/english/LightNovelReader.js b/js/plugins/english/LightNovelReader.js deleted file mode 100644 index dfba272..0000000 --- a/js/plugins/english/LightNovelReader.js +++ /dev/null @@ -1,138 +0,0 @@ -"use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.fetchImage = exports.searchNovels = exports.parseChapter = exports.parseNovelAndChapters = exports.popularNovels = exports.site = exports.version = exports.icon = exports.name = exports.id = void 0; -const cheerio_1 = require("cheerio"); -const isAbsoluteUrl_1 = require("@libs/isAbsoluteUrl"); -const fetch_1 = require("@libs/fetch"); -exports.id = "LNR.org"; -exports.name = "LightNovelReader"; -exports.icon = "src/en/lightnovelreader/icon.png"; -exports.version = "1.0.0"; -exports.site = "https://lightnovelreader.org"; -const baseUrl = exports.site; -const popularNovels = function (page) { - return __awaiter(this, void 0, void 0, function* () { - const url = baseUrl + "/ranking/top-rated/" + page; - const result = yield (0, fetch_1.fetchApi)(url); - const body = yield result.text(); - const loadedCheerio = (0, cheerio_1.load)(body); - const novels = []; - loadedCheerio(".category-items.ranking-category.cm-list > ul > li").each(function () { - let novelUrl = loadedCheerio(this).find("a").attr("href"); - if (novelUrl && !(0, isAbsoluteUrl_1.isUrlAbsolute)(novelUrl)) { - novelUrl = baseUrl + novelUrl; - } - if (novelUrl) { - const novelName = loadedCheerio(this) - .find(".category-name a") - .text() - .trim(); - let novelCover = loadedCheerio(this) - .find(".category-img img") - .attr("src"); - if (novelCover && !(0, isAbsoluteUrl_1.isUrlAbsolute)(novelCover)) { - novelCover = baseUrl + novelCover; - } - const novel = { - url: novelUrl, - name: novelName, - cover: novelCover, - }; - novels.push(novel); - } - }); - return novels; - }); -}; -exports.popularNovels = popularNovels; -const parseNovelAndChapters = function (novelUrl) { - return __awaiter(this, void 0, void 0, function* () { - const url = novelUrl; - const result = yield (0, fetch_1.fetchApi)(url); - const body = yield result.text(); - let loadedCheerio = (0, cheerio_1.load)(body); - const novel = { - url: novelUrl, - chapters: [], - }; - novel.name = loadedCheerio(".section-header-title > h2").text(); - let novelCover = loadedCheerio(".novels-detail img").attr("src"); - novel.cover = novelCover - ? (0, isAbsoluteUrl_1.isUrlAbsolute)(novelCover) - ? novelCover - : baseUrl + novelCover - : undefined; - novel.summary = loadedCheerio("div.container > div > div.col-12.col-xl-9 > div > div:nth-child(5) > div") - .text() - .trim(); - novel.author = loadedCheerio("div.novels-detail-right > ul > li:nth-child(6) > .novels-detail-right-in-right > a") - .text() - .trim(); - novel.genres = loadedCheerio("body > section:nth-child(4) > div > div > div.col-12.col-xl-9 > div > div:nth-child(2) > div > div.novels-detail-right > ul > li:nth-child(3) > div.novels-detail-right-in-right") - .text() - .trim(); - novel.status = loadedCheerio("div.novels-detail-right > ul > li:nth-child(2) > .novels-detail-right-in-right") - .text() - .trim(); - loadedCheerio(".cm-tabs-content > ul > li").each(function () { - var _a; - let chapterUrl = loadedCheerio(this).find("a").attr("href"); - if (chapterUrl && !(0, isAbsoluteUrl_1.isUrlAbsolute)(chapterUrl)) { - chapterUrl = baseUrl + chapterUrl; - } - if (chapterUrl) { - const chapterName = loadedCheerio(this).find("a").text().trim(); - const releaseDate = null; - const chapter = { - name: chapterName, - releaseTime: releaseDate, - url: chapterUrl, - }; - (_a = novel.chapters) === null || _a === void 0 ? void 0 : _a.push(chapter); - } - }); - return novel; - }); -}; -exports.parseNovelAndChapters = parseNovelAndChapters; -const parseChapter = function (chapterUrl) { - return __awaiter(this, void 0, void 0, function* () { - const url = chapterUrl; - const result = yield (0, fetch_1.fetchApi)(url); - const body = yield result.text(); - const loadedCheerio = (0, cheerio_1.load)(body); - const chapterText = loadedCheerio("#chapterText").html() || ""; - return chapterText; - }); -}; -exports.parseChapter = parseChapter; -const searchNovels = function (searchTerm) { - return __awaiter(this, void 0, void 0, function* () { - const url = baseUrl + `/search/autocomplete?dataType=json&query=${searchTerm}`; - const result = yield (0, fetch_1.fetchApi)(url); - const body = yield result.json(); - const novels = []; - body.results.forEach((item) => novels.push({ - url: item.link, - name: item.original_title, - cover: item.image, - })); - return novels; - }); -}; -exports.searchNovels = searchNovels; -const fetchImage = function (url) { - return __awaiter(this, void 0, void 0, function* () { - return yield (0, fetch_1.fetchFile)(url, {}); - }); -}; -exports.fetchImage = fetchImage; diff --git a/js/plugins/english/Ltnovelcom[readwn].js b/js/plugins/english/Ltnovelcom[readwn].js deleted file mode 100644 index a77c065..0000000 --- a/js/plugins/english/Ltnovelcom[readwn].js +++ /dev/null @@ -1,163 +0,0 @@ -"use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.filters = exports.fetchImage = exports.searchNovels = exports.parseChapter = exports.parseNovelAndChapters = exports.popularNovels = exports.site = exports.version = exports.icon = exports.name = exports.id = void 0; -const cheerio_1 = require("cheerio"); -// import dayjs from 'dayjs'; -const fetch_1 = require("@libs/fetch"); -const parseMadaraDate_1 = require("@libs/parseMadaraDate"); -// import { isUrlAbsolute } from '@libs/isAbsoluteUrl'; -// import { showToast } from "@libs/showToast"; -const filterInputs_1 = require("@libs/filterInputs"); -// import { NovelStatus } from '@libs/novelStatus'; -// import { defaultCover } from "@libs/defaultCover"; -exports.id = "Ltnovel.com"; -exports.name = "Ltnovel.com"; -exports.icon = "multisrc/readwn/icons/ltnovel.png"; -exports.version = "1.0.0"; -exports.site = "https://www.ltnovel.com/"; -const popularNovels = function (page, { filters, showLatestNovels }) { - return __awaiter(this, void 0, void 0, function* () { - const novels = []; - const pageNo = page - 1; - let url = exports.site + 'list/'; - url += ((filters === null || filters === void 0 ? void 0 : filters.genres) || 'all') + '/'; - url += ((filters === null || filters === void 0 ? void 0 : filters.status) || 'all') + '-'; - url += (showLatestNovels ? 'lastdotime' : (filters === null || filters === void 0 ? void 0 : filters.sort) || 'newstime') + '-'; - url += pageNo + '.html'; - const result = yield (0, fetch_1.fetchApi)(url); - const body = yield result.text(); - const loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('li.novel-item').each(function () { - const novelName = loadedCheerio(this).find('h4').text(); - const novelUrl = exports.site + loadedCheerio(this).find('a').attr('href'); - const coverUri = loadedCheerio(this) - .find('.novel-cover > img') - .attr('data-src'); - const novelCover = exports.site + coverUri; - const novel = { name: novelName, cover: novelCover, url: novelUrl }; - novels.push(novel); - }); - return novels; - }); -}; -exports.popularNovels = popularNovels; -const parseNovelAndChapters = function (novelUrl) { - return __awaiter(this, void 0, void 0, function* () { - const result = yield (0, fetch_1.fetchApi)(novelUrl); - const body = yield result.text(); - let loadedCheerio = (0, cheerio_1.load)(body); - const novel = { - url: novelUrl, - chapters: [], - }; - novel.name = loadedCheerio('h1.novel-title').text(); - const coverUri = loadedCheerio('figure.cover > img').attr('data-src'); - novel.cover = exports.site + coverUri; - novel.summary = loadedCheerio('.summary') - .text() - .replace('Summary', '') - .trim(); - novel.genres = ''; - loadedCheerio('div.categories > ul > li').each(function () { - novel.genres += loadedCheerio(this).text().trim() + ','; - }); - loadedCheerio('div.header-stats > span').each(function () { - if (loadedCheerio(this).find('small').text() === 'Status') { - novel.status = loadedCheerio(this).find('strong').text(); - } - }); - novel.genres = novel.genres.slice(0, -1); - novel.author = loadedCheerio('span[itemprop=author]').text(); - let novelChapters = []; - const novelId = novelUrl.replace('.html', '').replace(exports.site, ''); - const latestChapterNo = parseInt(loadedCheerio('.header-stats') - .find('span > strong') - .first() - .text() - .trim()); - let lastChapterNo = 1; - loadedCheerio('.chapter-list li').each(function () { - var _a; - const chapterName = loadedCheerio(this) - .find('a .chapter-title') - .text() - .trim(); - const chapterUrl = exports.site + ((_a = loadedCheerio(this).find('a').attr('href')) === null || _a === void 0 ? void 0 : _a.trim()); - const releaseDate = loadedCheerio(this) - .find('a .chapter-update') - .text() - .trim(); - lastChapterNo = parseInt(loadedCheerio(this).find('a .chapter-no').text().trim()); - const chapter = { name: chapterName, releaseTime: (0, parseMadaraDate_1.parseMadaraDate)(releaseDate), url: chapterUrl }; - novelChapters.push(chapter); - }); - // Itterate once more before loop to finish off - lastChapterNo++; - for (let i = lastChapterNo; i <= latestChapterNo; i++) { - const chapterName = 'Chapter ' + i; - const chapterUrl = exports.site + novelId + '_' + i + '.html'; - const releaseDate = null; - const chapter = { name: chapterName, releaseTime: releaseDate, url: chapterUrl }; - novelChapters.push(chapter); - } - novel.chapters = novelChapters; - return novel; - }); -}; -exports.parseNovelAndChapters = parseNovelAndChapters; -const parseChapter = function (chapterUrl) { - return __awaiter(this, void 0, void 0, function* () { - const result = yield (0, fetch_1.fetchApi)(chapterUrl); - const body = yield result.text(); - const loadedCheerio = (0, cheerio_1.load)(body); - const chapterText = loadedCheerio('.chapter-content').html(); - return chapterText; - }); -}; -exports.parseChapter = parseChapter; -const searchNovels = (searchTerm) => __awaiter(void 0, void 0, void 0, function* () { - const novels = []; - const searchUrl = exports.site + 'e/search/index.php'; - const result = yield (0, fetch_1.fetchApi)(searchUrl, { - headers: { - 'Content-Type': 'application/x-www-form-urlencoded', - Referer: exports.site + 'search.html', - Origin: exports.site, - 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36', - }, - method: 'POST', - body: JSON.stringify({ - show: 'title', - tempid: 1, - tbname: 'news', - keyboard: searchTerm, - }), - }); - const body = yield result.text(); - const loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('li.novel-item').each(function () { - const novelName = loadedCheerio(this).find('h4').text(); - const novelUrl = exports.site + loadedCheerio(this).find('a').attr('href'); - const coverUri = exports.site + loadedCheerio(this).find('img').attr('data-src'); - const novelCover = exports.site + coverUri; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - }); - return novels; -}); -exports.searchNovels = searchNovels; -exports.fetchImage = fetch_1.fetchFile; -exports.filters = [{ "key": "sort", "label": "Sort By", "values": [{ "label": "New", "value": "newstime" }, { "label": "Popular", "value": "onclick" }, { "label": "Updates", "value": "lastdotime" }], "inputType": filterInputs_1.FilterInputs.Picker }, { "key": "status", "label": "Status", "values": [{ "label": "All", "value": "all" }, { "label": "Completed", "value": "Completed" }, { "label": "Ongoing", "value": "Ongoing" }], "inputType": filterInputs_1.FilterInputs.Picker }, { "key": "genres", "label": "Genre / Category", "values": [{ "label": "All", "value": "all" }, { "label": "Action", "value": "action" }, { "label": "Adult", "value": "adult" }, { "label": "Adventure", "value": "adventure" }, { "label": "Comedy", "value": "comedy" }, { "label": "Contemporary Romance", "value": "contemporary-romance" }, { "label": "Drama", "value": "drama" }, { "label": "Eastern Fantasy", "value": "eastern-fantasy" }, { "label": "Ecchi", "value": "ecchi" }, { "label": "Fantasy", "value": "fantasy" }, { "label": "Fantasy Romance", "value": "fantasy-romance" }, { "label": "Game", "value": "game" }, { "label": "Gender Bender", "value": "gender-bender" }, { "label": "Harem", "value": "harem" }, { "label": "Historical", "value": "historical" }, { "label": "Horror", "value": "horror" }, { "label": "Josei", "value": "josei" }, { "label": "Lolicon", "value": "lolicon" }, { "label": "Magical Realism", "value": "magical-realism" }, { "label": "Martial Arts", "value": "martial-arts" }, { "label": "Mature", "value": "mature" }, { "label": "Mecha", "value": "mecha" }, { "label": "Mystery", "value": "mystery" }, { "label": "Psychological", "value": "psychological" }, { "label": "Romance", "value": "romance" }, { "label": "School Life", "value": "school-life" }, { "label": "Sci-fi", "value": "sci-fi" }, { "label": "Seinen", "value": "seinen" }, { "label": "Shoujo", "value": "shoujo" }, { "label": "Shounen", "value": "shounen" }, { "label": "Shounen Ai", "value": "shounen-ai" }, { "label": "Slice of Life", "value": "slice-of-life" }, { "label": "Smut", "value": "smut" }, { "label": "Sports", "value": "sports" }, { "label": "Supernatural", "value": "supernatural" }, { "label": "Tragedy", "value": "tragedy" }, { "label": "Video Games", "value": "video-games" }, { "label": "Wuxia", "value": "wuxia" }, { "label": "Xianxia", "value": "xianxia" }, { "label": "Xuanhuan", "value": "xuanhuan" }, { "label": "Yaoi", "value": "yaoi" }], "inputType": filterInputs_1.FilterInputs.Picker }]; diff --git a/js/plugins/english/LunarLetters[madara].js b/js/plugins/english/LunarLetters[madara].js deleted file mode 100644 index cced74e..0000000 --- a/js/plugins/english/LunarLetters[madara].js +++ /dev/null @@ -1,179 +0,0 @@ -"use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.filters = exports.fetchImage = exports.searchNovels = exports.parseChapter = exports.parseNovelAndChapters = exports.popularNovels = exports.site = exports.version = exports.icon = exports.name = exports.id = void 0; -const cheerio_1 = require("cheerio"); -const fetch_1 = require("@libs/fetch"); -const filterInputs_1 = require("@libs/filterInputs"); -const defaultCover_1 = require("@libs/defaultCover"); -const novelStatus_1 = require("@libs/novelStatus"); -const parseMadaraDate_1 = require("@libs/parseMadaraDate"); -const dayjs_1 = __importDefault(require("dayjs")); -exports.id = "lunarletters"; -exports.name = "LunarLetters [madara]"; -exports.icon = "multisrc/madara/icons/lunarletters.png"; -exports.version = "1.0.0"; -exports.site = "https://www.lunarletters.com/"; -const baseUrl = exports.site; -const popularNovels = (pageNo, { filters, showLatestNovels }) => __awaiter(void 0, void 0, void 0, function* () { - const novels = []; - let url = exports.site; - if (filters === null || filters === void 0 ? void 0 : filters.genres) { - url += "novel-genre/" + filters.genres + '/'; - } - else { - url += "series/"; - } - url += '/page/' + pageNo + '/' + - '?m_orderby=' + (showLatestNovels ? 'latest' : ((filters === null || filters === void 0 ? void 0 : filters.sort) || 'rating')); - const body = yield (0, fetch_1.fetchApi)(url).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.manga-title-badges').remove(); - loadedCheerio('.page-item-detail').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - let novelUrl = loadedCheerio(this).find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - }); - return novels; -}); -exports.popularNovels = popularNovels; -const parseNovelAndChapters = (novelUrl) => __awaiter(void 0, void 0, void 0, function* () { - const novel = { - url: novelUrl, - }; - const body = yield (0, fetch_1.fetchApi)(novelUrl).then(res => res.text()); - let loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.manga-title-badges').remove(); - novel.name = loadedCheerio('.post-title h1').text().trim(); - novel.cover = - loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || - loadedCheerio('.summary_image > a > img').attr('data-src') || - loadedCheerio('.summary_image > a > img').attr('src') || - defaultCover_1.defaultCover; - loadedCheerio('.post-content_item, .post-content').each(function () { - const detailName = loadedCheerio(this).find('h5').text().trim(); - const detail = loadedCheerio(this).find('.summary-content').text().trim(); - switch (detailName) { - case 'Genre(s)': - case 'التصنيفات': - novel.genres = detail.replace(/[\t\n]/g, ','); - break; - case 'Author(s)': - case 'المؤلف': - case 'المؤلف (ين)': - novel.author = detail; - break; - case 'Status': - case 'الحالة': - novel.status = - detail.includes('OnGoing') || detail.includes('مستمرة') - ? novelStatus_1.NovelStatus.Ongoing - : novelStatus_1.NovelStatus.Completed; - break; - } - }); - loadedCheerio('div.summary__content .code-block,script').remove(); - novel.summary = loadedCheerio('div.summary__content').text().trim(); - let html; - if (true) { - const novelId = loadedCheerio('.rating-post-id').attr('value') || - loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; - const body = { - action: "manga_get_chapters", - manga: novelId, - }; - html = yield (0, fetch_1.fetchApi)(baseUrl + 'wp-admin/admin-ajax.php', { - method: 'POST', - body: JSON.stringify(body), - }) - .then(res => res.text()); - } - else { - html = yield (0, fetch_1.fetchApi)(baseUrl + 'ajax/chapters/', { method: 'POST' }) - .then(res => res.text()); - } - if (html !== '0') { - loadedCheerio = (0, cheerio_1.load)(html); - } - const chapters = []; - loadedCheerio('.wp-manga-chapter').each(function () { - const chapterName = loadedCheerio(this).find('a').text().trim(); - let releaseDate = null; - releaseDate = loadedCheerio(this) - .find('span.chapter-release-date') - .text() - .trim(); - if (releaseDate) { - releaseDate = (0, parseMadaraDate_1.parseMadaraDate)(releaseDate); - } - else { - /** - * Insert current date - */ - releaseDate = (0, dayjs_1.default)().format('LL'); - } - let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; - chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); - }); - novel.chapters = chapters.reverse(); - return novel; -}); -exports.parseNovelAndChapters = parseNovelAndChapters; -const parseChapter = (chapterUrl) => __awaiter(void 0, void 0, void 0, function* () { - const url = baseUrl + "/" + "series" + "/" + chapterUrl; - const body = yield (0, fetch_1.fetchApi)(chapterUrl).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - const chapterText = loadedCheerio('.text-left').html() || - loadedCheerio('.text-right').html() || - loadedCheerio('.entry-content').html(); - return chapterText; -}); -exports.parseChapter = parseChapter; -const searchNovels = (searchTerm) => __awaiter(void 0, void 0, void 0, function* () { - const novels = []; - const url = baseUrl + "?s=" + searchTerm + "&post_type=wp-manga"; - const body = yield (0, fetch_1.fetchApi)(url).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.c-tabs-item__content').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - let novelUrl = loadedCheerio(this) - .find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - }); - return novels; -}); -exports.searchNovels = searchNovels; -const fetchImage = (url) => __awaiter(void 0, void 0, void 0, function* () { - return yield (0, fetch_1.fetchFile)(url); -}); -exports.fetchImage = fetchImage; -exports.filters = [{ "key": "sort", "label": "Order by", "values": [{ "label": "Rating", "value": "rating" }, { "label": "A-Z", "value": "alphabet" }, { "label": "Latest", "value": "latest" }, { "label": "Most Views", "value": "views" }, { "label": "New", "value": "new-manga" }, { "label": "Trending", "value": "trending" }], "inputType": filterInputs_1.FilterInputs.Picker }]; diff --git a/js/plugins/english/MTLNovelClub[madara].js b/js/plugins/english/MTLNovelClub[madara].js deleted file mode 100644 index a4def16..0000000 --- a/js/plugins/english/MTLNovelClub[madara].js +++ /dev/null @@ -1,178 +0,0 @@ -"use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.filters = exports.fetchImage = exports.searchNovels = exports.parseChapter = exports.parseNovelAndChapters = exports.popularNovels = exports.site = exports.version = exports.icon = exports.name = exports.id = void 0; -const cheerio_1 = require("cheerio"); -const fetch_1 = require("@libs/fetch"); -const defaultCover_1 = require("@libs/defaultCover"); -const novelStatus_1 = require("@libs/novelStatus"); -const parseMadaraDate_1 = require("@libs/parseMadaraDate"); -const dayjs_1 = __importDefault(require("dayjs")); -exports.id = "mtlnovel.club"; -exports.name = "MTLNovel.Club [madara]"; -exports.icon = "multisrc/madara/icons/mtlnovel.club.png"; -exports.version = "1.0.0"; -exports.site = "https://mtlnovel.club/"; -const baseUrl = exports.site; -const popularNovels = (pageNo, { filters, showLatestNovels }) => __awaiter(void 0, void 0, void 0, function* () { - const novels = []; - let url = exports.site; - if (filters === null || filters === void 0 ? void 0 : filters.genres) { - url += "novel-genre/" + filters.genres + '/'; - } - else { - url += "novel/"; - } - url += '/page/' + pageNo + '/' + - '?m_orderby=' + (showLatestNovels ? 'latest' : ((filters === null || filters === void 0 ? void 0 : filters.sort) || 'rating')); - const body = yield (0, fetch_1.fetchApi)(url).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.manga-title-badges').remove(); - loadedCheerio('.page-item-detail').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - let novelUrl = loadedCheerio(this).find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - }); - return novels; -}); -exports.popularNovels = popularNovels; -const parseNovelAndChapters = (novelUrl) => __awaiter(void 0, void 0, void 0, function* () { - const novel = { - url: novelUrl, - }; - const body = yield (0, fetch_1.fetchApi)(novelUrl).then(res => res.text()); - let loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.manga-title-badges').remove(); - novel.name = loadedCheerio('.post-title h1').text().trim(); - novel.cover = - loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || - loadedCheerio('.summary_image > a > img').attr('data-src') || - loadedCheerio('.summary_image > a > img').attr('src') || - defaultCover_1.defaultCover; - loadedCheerio('.post-content_item, .post-content').each(function () { - const detailName = loadedCheerio(this).find('h5').text().trim(); - const detail = loadedCheerio(this).find('.summary-content').text().trim(); - switch (detailName) { - case 'Genre(s)': - case 'التصنيفات': - novel.genres = detail.replace(/[\t\n]/g, ','); - break; - case 'Author(s)': - case 'المؤلف': - case 'المؤلف (ين)': - novel.author = detail; - break; - case 'Status': - case 'الحالة': - novel.status = - detail.includes('OnGoing') || detail.includes('مستمرة') - ? novelStatus_1.NovelStatus.Ongoing - : novelStatus_1.NovelStatus.Completed; - break; - } - }); - loadedCheerio('div.summary__content .code-block,script').remove(); - novel.summary = loadedCheerio('div.summary__content').text().trim(); - let html; - if (true) { - const novelId = loadedCheerio('.rating-post-id').attr('value') || - loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; - const body = { - action: "manga_get_chapters", - manga: novelId, - }; - html = yield (0, fetch_1.fetchApi)(baseUrl + 'wp-admin/admin-ajax.php', { - method: 'POST', - body: JSON.stringify(body), - }) - .then(res => res.text()); - } - else { - html = yield (0, fetch_1.fetchApi)(baseUrl + 'ajax/chapters/', { method: 'POST' }) - .then(res => res.text()); - } - if (html !== '0') { - loadedCheerio = (0, cheerio_1.load)(html); - } - const chapters = []; - loadedCheerio('.wp-manga-chapter').each(function () { - const chapterName = loadedCheerio(this).find('a').text().trim(); - let releaseDate = null; - releaseDate = loadedCheerio(this) - .find('span.chapter-release-date') - .text() - .trim(); - if (releaseDate) { - releaseDate = (0, parseMadaraDate_1.parseMadaraDate)(releaseDate); - } - else { - /** - * Insert current date - */ - releaseDate = (0, dayjs_1.default)().format('LL'); - } - let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; - chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); - }); - novel.chapters = chapters.reverse(); - return novel; -}); -exports.parseNovelAndChapters = parseNovelAndChapters; -const parseChapter = (chapterUrl) => __awaiter(void 0, void 0, void 0, function* () { - const url = baseUrl + "/" + "novel" + "/" + chapterUrl; - const body = yield (0, fetch_1.fetchApi)(chapterUrl).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - const chapterText = loadedCheerio('.text-left').html() || - loadedCheerio('.text-right').html() || - loadedCheerio('.entry-content').html(); - return chapterText; -}); -exports.parseChapter = parseChapter; -const searchNovels = (searchTerm) => __awaiter(void 0, void 0, void 0, function* () { - const novels = []; - const url = baseUrl + "?s=" + searchTerm + "&post_type=wp-manga"; - const body = yield (0, fetch_1.fetchApi)(url).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.c-tabs-item__content').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - let novelUrl = loadedCheerio(this) - .find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - }); - return novels; -}); -exports.searchNovels = searchNovels; -const fetchImage = (url) => __awaiter(void 0, void 0, void 0, function* () { - return yield (0, fetch_1.fetchFile)(url); -}); -exports.fetchImage = fetchImage; -exports.filters = []; diff --git a/js/plugins/english/MTLNovel[madara].js b/js/plugins/english/MTLNovel[madara].js deleted file mode 100644 index 06cf5f5..0000000 --- a/js/plugins/english/MTLNovel[madara].js +++ /dev/null @@ -1,179 +0,0 @@ -"use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.filters = exports.fetchImage = exports.searchNovels = exports.parseChapter = exports.parseNovelAndChapters = exports.popularNovels = exports.site = exports.version = exports.icon = exports.name = exports.id = void 0; -const cheerio_1 = require("cheerio"); -const fetch_1 = require("@libs/fetch"); -const filterInputs_1 = require("@libs/filterInputs"); -const defaultCover_1 = require("@libs/defaultCover"); -const novelStatus_1 = require("@libs/novelStatus"); -const parseMadaraDate_1 = require("@libs/parseMadaraDate"); -const dayjs_1 = __importDefault(require("dayjs")); -exports.id = "mtl-novel"; -exports.name = "MTL-Novel [madara]"; -exports.icon = "multisrc/madara/icons/mtl-novel.png"; -exports.version = "1.0.0"; -exports.site = "https://mtl-novel.com/"; -const baseUrl = exports.site; -const popularNovels = (pageNo, { filters, showLatestNovels }) => __awaiter(void 0, void 0, void 0, function* () { - const novels = []; - let url = exports.site; - if (filters === null || filters === void 0 ? void 0 : filters.genres) { - url += "manga-genre/" + filters.genres + '/'; - } - else { - url += "novel/"; - } - url += '/page/' + pageNo + '/' + - '?m_orderby=' + (showLatestNovels ? 'latest' : ((filters === null || filters === void 0 ? void 0 : filters.sort) || 'rating')); - const body = yield (0, fetch_1.fetchApi)(url).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.manga-title-badges').remove(); - loadedCheerio('.page-item-detail').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - let novelUrl = loadedCheerio(this).find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - }); - return novels; -}); -exports.popularNovels = popularNovels; -const parseNovelAndChapters = (novelUrl) => __awaiter(void 0, void 0, void 0, function* () { - const novel = { - url: novelUrl, - }; - const body = yield (0, fetch_1.fetchApi)(novelUrl).then(res => res.text()); - let loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.manga-title-badges').remove(); - novel.name = loadedCheerio('.post-title h1').text().trim(); - novel.cover = - loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || - loadedCheerio('.summary_image > a > img').attr('data-src') || - loadedCheerio('.summary_image > a > img').attr('src') || - defaultCover_1.defaultCover; - loadedCheerio('.post-content_item, .post-content').each(function () { - const detailName = loadedCheerio(this).find('h5').text().trim(); - const detail = loadedCheerio(this).find('.summary-content').text().trim(); - switch (detailName) { - case 'Genre(s)': - case 'التصنيفات': - novel.genres = detail.replace(/[\t\n]/g, ','); - break; - case 'Author(s)': - case 'المؤلف': - case 'المؤلف (ين)': - novel.author = detail; - break; - case 'Status': - case 'الحالة': - novel.status = - detail.includes('OnGoing') || detail.includes('مستمرة') - ? novelStatus_1.NovelStatus.Ongoing - : novelStatus_1.NovelStatus.Completed; - break; - } - }); - loadedCheerio('div.summary__content .code-block,script').remove(); - novel.summary = loadedCheerio('div.summary__content').text().trim(); - let html; - if (true) { - const novelId = loadedCheerio('.rating-post-id').attr('value') || - loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; - const body = { - action: "manga_get_chapters", - manga: novelId, - }; - html = yield (0, fetch_1.fetchApi)(baseUrl + 'wp-admin/admin-ajax.php', { - method: 'POST', - body: JSON.stringify(body), - }) - .then(res => res.text()); - } - else { - html = yield (0, fetch_1.fetchApi)(baseUrl + 'ajax/chapters/', { method: 'POST' }) - .then(res => res.text()); - } - if (html !== '0') { - loadedCheerio = (0, cheerio_1.load)(html); - } - const chapters = []; - loadedCheerio('.wp-manga-chapter').each(function () { - const chapterName = loadedCheerio(this).find('a').text().trim(); - let releaseDate = null; - releaseDate = loadedCheerio(this) - .find('span.chapter-release-date') - .text() - .trim(); - if (releaseDate) { - releaseDate = (0, parseMadaraDate_1.parseMadaraDate)(releaseDate); - } - else { - /** - * Insert current date - */ - releaseDate = (0, dayjs_1.default)().format('LL'); - } - let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; - chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); - }); - novel.chapters = chapters.reverse(); - return novel; -}); -exports.parseNovelAndChapters = parseNovelAndChapters; -const parseChapter = (chapterUrl) => __awaiter(void 0, void 0, void 0, function* () { - const url = baseUrl + "/" + "novel" + "/" + chapterUrl; - const body = yield (0, fetch_1.fetchApi)(chapterUrl).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - const chapterText = loadedCheerio('.text-left').html() || - loadedCheerio('.text-right').html() || - loadedCheerio('.entry-content').html(); - return chapterText; -}); -exports.parseChapter = parseChapter; -const searchNovels = (searchTerm) => __awaiter(void 0, void 0, void 0, function* () { - const novels = []; - const url = baseUrl + "?s=" + searchTerm + "&post_type=wp-manga"; - const body = yield (0, fetch_1.fetchApi)(url).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.c-tabs-item__content').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - let novelUrl = loadedCheerio(this) - .find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - }); - return novels; -}); -exports.searchNovels = searchNovels; -const fetchImage = (url) => __awaiter(void 0, void 0, void 0, function* () { - return yield (0, fetch_1.fetchFile)(url); -}); -exports.fetchImage = fetchImage; -exports.filters = [{ "key": "sort", "label": "Order by", "values": [{ "label": "Rating", "value": "rating" }, { "label": "A-Z", "value": "alphabet" }, { "label": "Latest", "value": "latest" }, { "label": "Most Views", "value": "views" }, { "label": "New", "value": "new-manga" }, { "label": "Trending", "value": "trending" }], "inputType": filterInputs_1.FilterInputs.Picker }, { "key": "genres", "label": "GENRES", "values": [{ "label": "Action", "value": "action" }, { "label": "Adult", "value": "adult" }, { "label": "Adventure", "value": "adventure" }, { "label": "Chinese", "value": "chinese" }, { "label": "Comedy", "value": "comedy" }, { "label": "Conan", "value": "conan" }, { "label": "Drama", "value": "drama" }, { "label": "Erciyuan", "value": "erciyuan" }, { "label": "Fairy Tail", "value": "fairy-tail" }, { "label": "Faloo", "value": "faloo" }, { "label": "Fan-Fiction", "value": "fan-fiction" }, { "label": "Fantasy", "value": "fantasy" }, { "label": "FoodWars!", "value": "foodwars" }, { "label": "Game", "value": "game" }, { "label": "Gender Bender", "value": "gender-bender" }, { "label": "Harem", "value": "harem" }, { "label": "Historical", "value": "historical" }, { "label": "Horror", "value": "horror" }, { "label": "Hunter x Hunter", "value": "hunter-x-hunter" }, { "label": "Japanese", "value": "japanese" }, { "label": "Jojo", "value": "jojo" }, { "label": "Josei", "value": "josei" }, { "label": "Korean", "value": "korean" }, { "label": "Martial Arts", "value": "martial-arts" }, { "label": "Marvel", "value": "marvel" }, { "label": "Mature", "value": "mature" }, { "label": "Mecha", "value": "mecha" }, { "label": "Military", "value": "military" }, { "label": "Mystery", "value": "mystery" }, { "label": "Naruto", "value": "naruto" }, { "label": "One piece", "value": "one-piece" }, { "label": "Pokemon", "value": "pokemon" }, { "label": "Psychological", "value": "psychological" }, { "label": "Romance", "value": "romance" }, { "label": "School Life", "value": "school-life" }, { "label": "Sci-fi", "value": "sci-fi" }, { "label": "Seinen", "value": "seinen" }, { "label": "Shoujo", "value": "shoujo" }, { "label": "Shoujo Ai", "value": "shoujo-ai" }, { "label": "Shounen Ai", "value": "shounen-ai" }, { "label": "Slice of Life", "value": "slice-of-life" }, { "label": "Smut", "value": "smut" }, { "label": "Sport", "value": "sport" }, { "label": "Sports", "value": "sports" }, { "label": "Supernatural", "value": "supernatural" }, { "label": "System", "value": "system" }, { "label": "Tragedy", "value": "tragedy" }, { "label": "Urban", "value": "urban" }, { "label": "Urban Life", "value": "urban-life" }, { "label": "Wuxia", "value": "wuxia" }, { "label": "Xianxia", "value": "xianxia" }, { "label": "Xuanhuan", "value": "xuanhuan" }, { "label": "Yaoi", "value": "yaoi" }, { "label": "Yuri", "value": "yuri" }], "inputType": filterInputs_1.FilterInputs.Picker }]; diff --git a/js/plugins/english/MostNovel[madara].js b/js/plugins/english/MostNovel[madara].js deleted file mode 100644 index 01e2c17..0000000 --- a/js/plugins/english/MostNovel[madara].js +++ /dev/null @@ -1,179 +0,0 @@ -"use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.filters = exports.fetchImage = exports.searchNovels = exports.parseChapter = exports.parseNovelAndChapters = exports.popularNovels = exports.site = exports.version = exports.icon = exports.name = exports.id = void 0; -const cheerio_1 = require("cheerio"); -const fetch_1 = require("@libs/fetch"); -const filterInputs_1 = require("@libs/filterInputs"); -const defaultCover_1 = require("@libs/defaultCover"); -const novelStatus_1 = require("@libs/novelStatus"); -const parseMadaraDate_1 = require("@libs/parseMadaraDate"); -const dayjs_1 = __importDefault(require("dayjs")); -exports.id = "mostnovel"; -exports.name = "MostNovel [madara]"; -exports.icon = "multisrc/madara/icons/mostnovel.png"; -exports.version = "1.0.0"; -exports.site = "https://mostnovel.com/"; -const baseUrl = exports.site; -const popularNovels = (pageNo, { filters, showLatestNovels }) => __awaiter(void 0, void 0, void 0, function* () { - const novels = []; - let url = exports.site; - if (filters === null || filters === void 0 ? void 0 : filters.genres) { - url += "manga-genre/" + filters.genres + '/'; - } - else { - url += "manga/"; - } - url += '/page/' + pageNo + '/' + - '?m_orderby=' + (showLatestNovels ? 'latest' : ((filters === null || filters === void 0 ? void 0 : filters.sort) || 'rating')); - const body = yield (0, fetch_1.fetchApi)(url).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.manga-title-badges').remove(); - loadedCheerio('.page-item-detail').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - let novelUrl = loadedCheerio(this).find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - }); - return novels; -}); -exports.popularNovels = popularNovels; -const parseNovelAndChapters = (novelUrl) => __awaiter(void 0, void 0, void 0, function* () { - const novel = { - url: novelUrl, - }; - const body = yield (0, fetch_1.fetchApi)(novelUrl).then(res => res.text()); - let loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.manga-title-badges').remove(); - novel.name = loadedCheerio('.post-title h1').text().trim(); - novel.cover = - loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || - loadedCheerio('.summary_image > a > img').attr('data-src') || - loadedCheerio('.summary_image > a > img').attr('src') || - defaultCover_1.defaultCover; - loadedCheerio('.post-content_item, .post-content').each(function () { - const detailName = loadedCheerio(this).find('h5').text().trim(); - const detail = loadedCheerio(this).find('.summary-content').text().trim(); - switch (detailName) { - case 'Genre(s)': - case 'التصنيفات': - novel.genres = detail.replace(/[\t\n]/g, ','); - break; - case 'Author(s)': - case 'المؤلف': - case 'المؤلف (ين)': - novel.author = detail; - break; - case 'Status': - case 'الحالة': - novel.status = - detail.includes('OnGoing') || detail.includes('مستمرة') - ? novelStatus_1.NovelStatus.Ongoing - : novelStatus_1.NovelStatus.Completed; - break; - } - }); - loadedCheerio('div.summary__content .code-block,script').remove(); - novel.summary = loadedCheerio('div.summary__content').text().trim(); - let html; - if (false) { - const novelId = loadedCheerio('.rating-post-id').attr('value') || - loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; - const body = { - action: "manga_get_chapters", - manga: novelId, - }; - html = yield (0, fetch_1.fetchApi)(baseUrl + 'wp-admin/admin-ajax.php', { - method: 'POST', - body: JSON.stringify(body), - }) - .then(res => res.text()); - } - else { - html = yield (0, fetch_1.fetchApi)(baseUrl + 'ajax/chapters/', { method: 'POST' }) - .then(res => res.text()); - } - if (html !== '0') { - loadedCheerio = (0, cheerio_1.load)(html); - } - const chapters = []; - loadedCheerio('.wp-manga-chapter').each(function () { - const chapterName = loadedCheerio(this).find('a').text().trim(); - let releaseDate = null; - releaseDate = loadedCheerio(this) - .find('span.chapter-release-date') - .text() - .trim(); - if (releaseDate) { - releaseDate = (0, parseMadaraDate_1.parseMadaraDate)(releaseDate); - } - else { - /** - * Insert current date - */ - releaseDate = (0, dayjs_1.default)().format('LL'); - } - let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; - chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); - }); - novel.chapters = chapters.reverse(); - return novel; -}); -exports.parseNovelAndChapters = parseNovelAndChapters; -const parseChapter = (chapterUrl) => __awaiter(void 0, void 0, void 0, function* () { - const url = baseUrl + "/" + "manga" + "/" + chapterUrl; - const body = yield (0, fetch_1.fetchApi)(chapterUrl).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - const chapterText = loadedCheerio('.text-left').html() || - loadedCheerio('.text-right').html() || - loadedCheerio('.entry-content').html(); - return chapterText; -}); -exports.parseChapter = parseChapter; -const searchNovels = (searchTerm) => __awaiter(void 0, void 0, void 0, function* () { - const novels = []; - const url = baseUrl + "?s=" + searchTerm + "&post_type=wp-manga"; - const body = yield (0, fetch_1.fetchApi)(url).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.c-tabs-item__content').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - let novelUrl = loadedCheerio(this) - .find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - }); - return novels; -}); -exports.searchNovels = searchNovels; -const fetchImage = (url) => __awaiter(void 0, void 0, void 0, function* () { - return yield (0, fetch_1.fetchFile)(url); -}); -exports.fetchImage = fetchImage; -exports.filters = [{ "key": "sort", "label": "Order by", "values": [{ "label": "Rating", "value": "rating" }, { "label": "A-Z", "value": "alphabet" }, { "label": "Latest", "value": "latest" }, { "label": "Most Views", "value": "views" }, { "label": "New", "value": "new-manga" }, { "label": "Trending", "value": "trending" }], "inputType": filterInputs_1.FilterInputs.Picker }, { "key": "genres", "label": "GENRES", "values": [{ "label": "ACG", "value": "acg" }, { "label": "Action", "value": "action" }, { "label": "Adult", "value": "adult" }, { "label": "Adventure", "value": "adventure" }, { "label": "AGA", "value": "aga" }, { "label": "Anime", "value": "anime" }, { "label": "Anime & Comics", "value": "anime-comics" }, { "label": "Bender", "value": "bender" }, { "label": "BL", "value": "bl" }, { "label": "Cartoon", "value": "cartoon" }, { "label": "Comedy", "value": "comedy" }, { "label": "Comic", "value": "comic" }, { "label": "Contemporary Romance", "value": "contemporary-romance" }, { "label": "Cooking", "value": "cooking" }, { "label": "Cultivation", "value": "cultivation" }, { "label": "Detective", "value": "detective" }, { "label": "Doujinshi", "value": "doujinshi" }, { "label": "Drama", "value": "drama" }, { "label": "Eastern Fantasy", "value": "eastern-fantasy" }, { "label": "Ecchi", "value": "ecchi" }, { "label": "Fantasy", "value": "fantasy" }, { "label": "Gender Bender", "value": "gender-bender" }, { "label": "Harem", "value": "harem" }, { "label": "Historical", "value": "historical" }, { "label": "Horror", "value": "horror" }, { "label": "Horror&Thriller", "value": "horrorthriller" }, { "label": "Josei", "value": "josei" }, { "label": "Live action", "value": "live-action" }, { "label": "Magical Realism", "value": "magical-realism" }, { "label": "Manga", "value": "manga" }, { "label": "Manhua", "value": "manhua" }, { "label": "Manhwa", "value": "manhwa" }, { "label": "Martial Arts", "value": "martial-arts" }, { "label": "Mature", "value": "mature" }, { "label": "Mecha", "value": "mecha" }, { "label": "Modern", "value": "modern" }, { "label": "Movies", "value": "movies" }, { "label": "Mystery", "value": "mystery" }, { "label": "One shot", "value": "one-shot" }, { "label": "Psychological", "value": "psychological" }, { "label": "Romance", "value": "romance" }, { "label": "School Life", "value": "school-life" }, { "label": "Sci-fi", "value": "sci-fi" }, { "label": "Seinen", "value": "seinen" }, { "label": "Shoujo", "value": "shoujo" }, { "label": "Shoujo Ai", "value": "shoujo-ai" }, { "label": "Shounen", "value": "shounen" }, { "label": "Shounen Ai", "value": "shounen-ai" }, { "label": "Slice of Life", "value": "slice-of-life" }, { "label": "Smart MC", "value": "smart-mc" }, { "label": "Smut", "value": "smut" }, { "label": "Soft Yaoi", "value": "soft-yaoi" }, { "label": "Soft Yuri", "value": "soft-yuri" }, { "label": "Sports", "value": "sports" }, { "label": "Supernatural", "value": "supernatural" }, { "label": "Tragedy", "value": "tragedy" }, { "label": "Urban Life", "value": "urban-life" }, { "label": "Video Games", "value": "video-games" }, { "label": "Webtoon", "value": "webtoon" }, { "label": "Wuxia", "value": "wuxia" }, { "label": "Xianxia", "value": "xianxia" }, { "label": "Xuanhuan", "value": "xuanhuan" }, { "label": "Yaoi", "value": "yaoi" }, { "label": "Yuri", "value": "yuri" }], "inputType": filterInputs_1.FilterInputs.Picker }]; diff --git a/js/plugins/english/MysticalSeries[madara].js b/js/plugins/english/MysticalSeries[madara].js deleted file mode 100644 index 7d41355..0000000 --- a/js/plugins/english/MysticalSeries[madara].js +++ /dev/null @@ -1,179 +0,0 @@ -"use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.filters = exports.fetchImage = exports.searchNovels = exports.parseChapter = exports.parseNovelAndChapters = exports.popularNovels = exports.site = exports.version = exports.icon = exports.name = exports.id = void 0; -const cheerio_1 = require("cheerio"); -const fetch_1 = require("@libs/fetch"); -const filterInputs_1 = require("@libs/filterInputs"); -const defaultCover_1 = require("@libs/defaultCover"); -const novelStatus_1 = require("@libs/novelStatus"); -const parseMadaraDate_1 = require("@libs/parseMadaraDate"); -const dayjs_1 = __importDefault(require("dayjs")); -exports.id = "mysticalmerries"; -exports.name = "MysticalSeries [madara]"; -exports.icon = "multisrc/madara/icons/mysticalseries.png"; -exports.version = "1.0.0"; -exports.site = "https://mysticalmerries.com/"; -const baseUrl = exports.site; -const popularNovels = (pageNo, { filters, showLatestNovels }) => __awaiter(void 0, void 0, void 0, function* () { - const novels = []; - let url = exports.site; - if (filters === null || filters === void 0 ? void 0 : filters.genres) { - url += "genre/" + filters.genres + '/'; - } - else { - url += "series/"; - } - url += '/page/' + pageNo + '/' + - '?m_orderby=' + (showLatestNovels ? 'latest' : ((filters === null || filters === void 0 ? void 0 : filters.sort) || 'rating')); - const body = yield (0, fetch_1.fetchApi)(url).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.manga-title-badges').remove(); - loadedCheerio('.page-item-detail').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - let novelUrl = loadedCheerio(this).find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - }); - return novels; -}); -exports.popularNovels = popularNovels; -const parseNovelAndChapters = (novelUrl) => __awaiter(void 0, void 0, void 0, function* () { - const novel = { - url: novelUrl, - }; - const body = yield (0, fetch_1.fetchApi)(novelUrl).then(res => res.text()); - let loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.manga-title-badges').remove(); - novel.name = loadedCheerio('.post-title h1').text().trim(); - novel.cover = - loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || - loadedCheerio('.summary_image > a > img').attr('data-src') || - loadedCheerio('.summary_image > a > img').attr('src') || - defaultCover_1.defaultCover; - loadedCheerio('.post-content_item, .post-content').each(function () { - const detailName = loadedCheerio(this).find('h5').text().trim(); - const detail = loadedCheerio(this).find('.summary-content').text().trim(); - switch (detailName) { - case 'Genre(s)': - case 'التصنيفات': - novel.genres = detail.replace(/[\t\n]/g, ','); - break; - case 'Author(s)': - case 'المؤلف': - case 'المؤلف (ين)': - novel.author = detail; - break; - case 'Status': - case 'الحالة': - novel.status = - detail.includes('OnGoing') || detail.includes('مستمرة') - ? novelStatus_1.NovelStatus.Ongoing - : novelStatus_1.NovelStatus.Completed; - break; - } - }); - loadedCheerio('div.summary__content .code-block,script').remove(); - novel.summary = loadedCheerio('div.summary__content').text().trim(); - let html; - if (true) { - const novelId = loadedCheerio('.rating-post-id').attr('value') || - loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; - const body = { - action: "manga_get_chapters", - manga: novelId, - }; - html = yield (0, fetch_1.fetchApi)(baseUrl + 'wp-admin/admin-ajax.php', { - method: 'POST', - body: JSON.stringify(body), - }) - .then(res => res.text()); - } - else { - html = yield (0, fetch_1.fetchApi)(baseUrl + 'ajax/chapters/', { method: 'POST' }) - .then(res => res.text()); - } - if (html !== '0') { - loadedCheerio = (0, cheerio_1.load)(html); - } - const chapters = []; - loadedCheerio('.wp-manga-chapter').each(function () { - const chapterName = loadedCheerio(this).find('a').text().trim(); - let releaseDate = null; - releaseDate = loadedCheerio(this) - .find('span.chapter-release-date') - .text() - .trim(); - if (releaseDate) { - releaseDate = (0, parseMadaraDate_1.parseMadaraDate)(releaseDate); - } - else { - /** - * Insert current date - */ - releaseDate = (0, dayjs_1.default)().format('LL'); - } - let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; - chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); - }); - novel.chapters = chapters.reverse(); - return novel; -}); -exports.parseNovelAndChapters = parseNovelAndChapters; -const parseChapter = (chapterUrl) => __awaiter(void 0, void 0, void 0, function* () { - const url = baseUrl + "/" + "series" + "/" + chapterUrl; - const body = yield (0, fetch_1.fetchApi)(chapterUrl).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - const chapterText = loadedCheerio('.text-left').html() || - loadedCheerio('.text-right').html() || - loadedCheerio('.entry-content').html(); - return chapterText; -}); -exports.parseChapter = parseChapter; -const searchNovels = (searchTerm) => __awaiter(void 0, void 0, void 0, function* () { - const novels = []; - const url = baseUrl + "?s=" + searchTerm + "&post_type=wp-manga"; - const body = yield (0, fetch_1.fetchApi)(url).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.c-tabs-item__content').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - let novelUrl = loadedCheerio(this) - .find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - }); - return novels; -}); -exports.searchNovels = searchNovels; -const fetchImage = (url) => __awaiter(void 0, void 0, void 0, function* () { - return yield (0, fetch_1.fetchFile)(url); -}); -exports.fetchImage = fetchImage; -exports.filters = [{ "key": "sort", "label": "Order by", "values": [{ "label": "Rating", "value": "rating" }, { "label": "A-Z", "value": "alphabet" }, { "label": "Latest", "value": "latest" }, { "label": "Most Views", "value": "views" }, { "label": "New", "value": "new-manga" }, { "label": "Trending", "value": "trending" }], "inputType": filterInputs_1.FilterInputs.Picker }, { "key": "genres", "label": "GENRES", "values": [{ "label": "Action", "value": "action" }, { "label": "Adaptation", "value": "adaptation" }, { "label": "Adventure", "value": "adventure" }, { "label": "bilibili", "value": "bilibili" }, { "label": "Chinese Novel", "value": "chinese-novel" }, { "label": "Comedy", "value": "comedy" }, { "label": "Crossdressing", "value": "crossdressing" }, { "label": "Drama", "value": "drama" }, { "label": "Dropped", "value": "dropped" }, { "label": "Family", "value": "family" }, { "label": "Fantasy", "value": "fantasy" }, { "label": "Gender Bender", "value": "gender-bender" }, { "label": "Historical", "value": "historical" }, { "label": "Horror", "value": "horror" }, { "label": "Isekai", "value": "isekai" }, { "label": "Korean Novel", "value": "korean-novell" }, { "label": "Manga", "value": "manga" }, { "label": "Manhua", "value": "manhua" }, { "label": "Manhwa", "value": "manhwa" }, { "label": "Modern Romance", "value": "modern-romance" }, { "label": "Mystery", "value": "mystery" }, { "label": "Office Workers", "value": "office-workers" }, { "label": "One shot", "value": "one-shot" }, { "label": "Pilot Novel", "value": "pilot-novel" }, { "label": "R15", "value": "r15" }, { "label": "R19", "value": "r19" }, { "label": "Regression", "value": "regression" }, { "label": "Reincarnation", "value": "reincarnation" }, { "label": "Reverse Harem", "value": "reverse-harem" }, { "label": "Romance Fantasy", "value": "romance-fantasy" }, { "label": "School Life", "value": "school-life" }, { "label": "Sci-fi", "value": "sci-fi" }, { "label": "Slice of Life", "value": "slice-of-life" }, { "label": "Smut", "value": "smut" }, { "label": "Supernatural", "value": "supernatural" }, { "label": "Violence", "value": "violence" }], "inputType": filterInputs_1.FilterInputs.Picker }]; diff --git a/js/plugins/english/NeoSekaiTranslations[madara].js b/js/plugins/english/NeoSekaiTranslations[madara].js deleted file mode 100644 index fd273cd..0000000 --- a/js/plugins/english/NeoSekaiTranslations[madara].js +++ /dev/null @@ -1,179 +0,0 @@ -"use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.filters = exports.fetchImage = exports.searchNovels = exports.parseChapter = exports.parseNovelAndChapters = exports.popularNovels = exports.site = exports.version = exports.icon = exports.name = exports.id = void 0; -const cheerio_1 = require("cheerio"); -const fetch_1 = require("@libs/fetch"); -const filterInputs_1 = require("@libs/filterInputs"); -const defaultCover_1 = require("@libs/defaultCover"); -const novelStatus_1 = require("@libs/novelStatus"); -const parseMadaraDate_1 = require("@libs/parseMadaraDate"); -const dayjs_1 = __importDefault(require("dayjs")); -exports.id = "neosekaiTLS"; -exports.name = "NeoSekai Translations [madara]"; -exports.icon = "multisrc/madara/icons/neosekaitranslations.png"; -exports.version = "1.0.0"; -exports.site = "https://www.neosekaitranslations.com/"; -const baseUrl = exports.site; -const popularNovels = (pageNo, { filters, showLatestNovels }) => __awaiter(void 0, void 0, void 0, function* () { - const novels = []; - let url = exports.site; - if (filters === null || filters === void 0 ? void 0 : filters.genres) { - url += "novel-genre/" + filters.genres + '/'; - } - else { - url += "novel/"; - } - url += '/page/' + pageNo + '/' + - '?m_orderby=' + (showLatestNovels ? 'latest' : ((filters === null || filters === void 0 ? void 0 : filters.sort) || 'rating')); - const body = yield (0, fetch_1.fetchApi)(url).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.manga-title-badges').remove(); - loadedCheerio('.page-item-detail').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - let novelUrl = loadedCheerio(this).find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - }); - return novels; -}); -exports.popularNovels = popularNovels; -const parseNovelAndChapters = (novelUrl) => __awaiter(void 0, void 0, void 0, function* () { - const novel = { - url: novelUrl, - }; - const body = yield (0, fetch_1.fetchApi)(novelUrl).then(res => res.text()); - let loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.manga-title-badges').remove(); - novel.name = loadedCheerio('.post-title h1').text().trim(); - novel.cover = - loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || - loadedCheerio('.summary_image > a > img').attr('data-src') || - loadedCheerio('.summary_image > a > img').attr('src') || - defaultCover_1.defaultCover; - loadedCheerio('.post-content_item, .post-content').each(function () { - const detailName = loadedCheerio(this).find('h5').text().trim(); - const detail = loadedCheerio(this).find('.summary-content').text().trim(); - switch (detailName) { - case 'Genre(s)': - case 'التصنيفات': - novel.genres = detail.replace(/[\t\n]/g, ','); - break; - case 'Author(s)': - case 'المؤلف': - case 'المؤلف (ين)': - novel.author = detail; - break; - case 'Status': - case 'الحالة': - novel.status = - detail.includes('OnGoing') || detail.includes('مستمرة') - ? novelStatus_1.NovelStatus.Ongoing - : novelStatus_1.NovelStatus.Completed; - break; - } - }); - loadedCheerio('div.summary__content .code-block,script').remove(); - novel.summary = loadedCheerio('div.summary__content').text().trim(); - let html; - if (false) { - const novelId = loadedCheerio('.rating-post-id').attr('value') || - loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; - const body = { - action: "manga_get_chapters", - manga: novelId, - }; - html = yield (0, fetch_1.fetchApi)(baseUrl + 'wp-admin/admin-ajax.php', { - method: 'POST', - body: JSON.stringify(body), - }) - .then(res => res.text()); - } - else { - html = yield (0, fetch_1.fetchApi)(baseUrl + 'ajax/chapters/', { method: 'POST' }) - .then(res => res.text()); - } - if (html !== '0') { - loadedCheerio = (0, cheerio_1.load)(html); - } - const chapters = []; - loadedCheerio('.wp-manga-chapter').each(function () { - const chapterName = loadedCheerio(this).find('a').text().trim(); - let releaseDate = null; - releaseDate = loadedCheerio(this) - .find('span.chapter-release-date') - .text() - .trim(); - if (releaseDate) { - releaseDate = (0, parseMadaraDate_1.parseMadaraDate)(releaseDate); - } - else { - /** - * Insert current date - */ - releaseDate = (0, dayjs_1.default)().format('LL'); - } - let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; - chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); - }); - novel.chapters = chapters.reverse(); - return novel; -}); -exports.parseNovelAndChapters = parseNovelAndChapters; -const parseChapter = (chapterUrl) => __awaiter(void 0, void 0, void 0, function* () { - const url = baseUrl + "/" + "novel" + "/" + chapterUrl; - const body = yield (0, fetch_1.fetchApi)(chapterUrl).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - const chapterText = loadedCheerio('.text-left').html() || - loadedCheerio('.text-right').html() || - loadedCheerio('.entry-content').html(); - return chapterText; -}); -exports.parseChapter = parseChapter; -const searchNovels = (searchTerm) => __awaiter(void 0, void 0, void 0, function* () { - const novels = []; - const url = baseUrl + "?s=" + searchTerm + "&post_type=wp-manga"; - const body = yield (0, fetch_1.fetchApi)(url).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.c-tabs-item__content').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - let novelUrl = loadedCheerio(this) - .find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - }); - return novels; -}); -exports.searchNovels = searchNovels; -const fetchImage = (url) => __awaiter(void 0, void 0, void 0, function* () { - return yield (0, fetch_1.fetchFile)(url); -}); -exports.fetchImage = fetchImage; -exports.filters = [{ "key": "sort", "label": "Order by", "values": [{ "label": "Rating", "value": "rating" }, { "label": "A-Z", "value": "alphabet" }, { "label": "Latest", "value": "latest" }, { "label": "Most Views", "value": "views" }, { "label": "New", "value": "new-manga" }, { "label": "Trending", "value": "trending" }], "inputType": filterInputs_1.FilterInputs.Picker }, { "key": "genres", "label": "GENRES", "values": [{ "label": "Action", "value": "action" }, { "label": "Adventure", "value": "adventure" }, { "label": "Comedy", "value": "comedy" }, { "label": "Drama", "value": "drama" }, { "label": "Fantasy", "value": "fantasy" }, { "label": "Harem", "value": "harem" }, { "label": "Horror", "value": "horror" }, { "label": "Mature", "value": "mature" }, { "label": "Mecha", "value": "mecha" }, { "label": "Mystery", "value": "mystery" }, { "label": "Psychological", "value": "psychological" }, { "label": "Romance", "value": "romance" }, { "label": "School Life", "value": "school-life" }, { "label": "Sci-Fi", "value": "sci-fi" }, { "label": "Slice of Life", "value": "slice-of-life" }], "inputType": filterInputs_1.FilterInputs.Picker }]; diff --git a/js/plugins/english/NocturneTranslations[madara].js b/js/plugins/english/NocturneTranslations[madara].js deleted file mode 100644 index 5c1d516..0000000 --- a/js/plugins/english/NocturneTranslations[madara].js +++ /dev/null @@ -1,179 +0,0 @@ -"use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.filters = exports.fetchImage = exports.searchNovels = exports.parseChapter = exports.parseNovelAndChapters = exports.popularNovels = exports.site = exports.version = exports.icon = exports.name = exports.id = void 0; -const cheerio_1 = require("cheerio"); -const fetch_1 = require("@libs/fetch"); -const filterInputs_1 = require("@libs/filterInputs"); -const defaultCover_1 = require("@libs/defaultCover"); -const novelStatus_1 = require("@libs/novelStatus"); -const parseMadaraDate_1 = require("@libs/parseMadaraDate"); -const dayjs_1 = __importDefault(require("dayjs")); -exports.id = "nocturneTLS"; -exports.name = "Nocturne Translations [madara]"; -exports.icon = "multisrc/madara/icons/nocturnetranslations.png"; -exports.version = "1.0.0"; -exports.site = "https://nocturnetls.net/"; -const baseUrl = exports.site; -const popularNovels = (pageNo, { filters, showLatestNovels }) => __awaiter(void 0, void 0, void 0, function* () { - const novels = []; - let url = exports.site; - if (filters === null || filters === void 0 ? void 0 : filters.genres) { - url += "manga-genre/" + filters.genres + '/'; - } - else { - url += "novels/"; - } - url += '/page/' + pageNo + '/' + - '?m_orderby=' + (showLatestNovels ? 'latest' : ((filters === null || filters === void 0 ? void 0 : filters.sort) || 'rating')); - const body = yield (0, fetch_1.fetchApi)(url).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.manga-title-badges').remove(); - loadedCheerio('.page-item-detail').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - let novelUrl = loadedCheerio(this).find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - }); - return novels; -}); -exports.popularNovels = popularNovels; -const parseNovelAndChapters = (novelUrl) => __awaiter(void 0, void 0, void 0, function* () { - const novel = { - url: novelUrl, - }; - const body = yield (0, fetch_1.fetchApi)(novelUrl).then(res => res.text()); - let loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.manga-title-badges').remove(); - novel.name = loadedCheerio('.post-title h1').text().trim(); - novel.cover = - loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || - loadedCheerio('.summary_image > a > img').attr('data-src') || - loadedCheerio('.summary_image > a > img').attr('src') || - defaultCover_1.defaultCover; - loadedCheerio('.post-content_item, .post-content').each(function () { - const detailName = loadedCheerio(this).find('h5').text().trim(); - const detail = loadedCheerio(this).find('.summary-content').text().trim(); - switch (detailName) { - case 'Genre(s)': - case 'التصنيفات': - novel.genres = detail.replace(/[\t\n]/g, ','); - break; - case 'Author(s)': - case 'المؤلف': - case 'المؤلف (ين)': - novel.author = detail; - break; - case 'Status': - case 'الحالة': - novel.status = - detail.includes('OnGoing') || detail.includes('مستمرة') - ? novelStatus_1.NovelStatus.Ongoing - : novelStatus_1.NovelStatus.Completed; - break; - } - }); - loadedCheerio('div.summary__content .code-block,script').remove(); - novel.summary = loadedCheerio('div.summary__content').text().trim(); - let html; - if (false) { - const novelId = loadedCheerio('.rating-post-id').attr('value') || - loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; - const body = { - action: "manga_get_chapters", - manga: novelId, - }; - html = yield (0, fetch_1.fetchApi)(baseUrl + 'wp-admin/admin-ajax.php', { - method: 'POST', - body: JSON.stringify(body), - }) - .then(res => res.text()); - } - else { - html = yield (0, fetch_1.fetchApi)(baseUrl + 'ajax/chapters/', { method: 'POST' }) - .then(res => res.text()); - } - if (html !== '0') { - loadedCheerio = (0, cheerio_1.load)(html); - } - const chapters = []; - loadedCheerio('.wp-manga-chapter').each(function () { - const chapterName = loadedCheerio(this).find('a').text().trim(); - let releaseDate = null; - releaseDate = loadedCheerio(this) - .find('span.chapter-release-date') - .text() - .trim(); - if (releaseDate) { - releaseDate = (0, parseMadaraDate_1.parseMadaraDate)(releaseDate); - } - else { - /** - * Insert current date - */ - releaseDate = (0, dayjs_1.default)().format('LL'); - } - let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; - chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); - }); - novel.chapters = chapters.reverse(); - return novel; -}); -exports.parseNovelAndChapters = parseNovelAndChapters; -const parseChapter = (chapterUrl) => __awaiter(void 0, void 0, void 0, function* () { - const url = baseUrl + "/" + "novels" + "/" + chapterUrl; - const body = yield (0, fetch_1.fetchApi)(chapterUrl).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - const chapterText = loadedCheerio('.text-left').html() || - loadedCheerio('.text-right').html() || - loadedCheerio('.entry-content').html(); - return chapterText; -}); -exports.parseChapter = parseChapter; -const searchNovels = (searchTerm) => __awaiter(void 0, void 0, void 0, function* () { - const novels = []; - const url = baseUrl + "?s=" + searchTerm + "&post_type=wp-manga"; - const body = yield (0, fetch_1.fetchApi)(url).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.c-tabs-item__content').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - let novelUrl = loadedCheerio(this) - .find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - }); - return novels; -}); -exports.searchNovels = searchNovels; -const fetchImage = (url) => __awaiter(void 0, void 0, void 0, function* () { - return yield (0, fetch_1.fetchFile)(url); -}); -exports.fetchImage = fetchImage; -exports.filters = [{ "key": "sort", "label": "Order by", "values": [{ "label": "Rating", "value": "rating" }, { "label": "A-Z", "value": "alphabet" }, { "label": "Latest", "value": "latest" }, { "label": "Most Views", "value": "views" }, { "label": "New", "value": "new-manga" }, { "label": "Trending", "value": "trending" }], "inputType": filterInputs_1.FilterInputs.Picker }, { "key": "genres", "label": "GENRES", "values": [{ "label": "Action", "value": "action" }, { "label": "Adult", "value": "adult" }, { "label": "Adventure", "value": "adventure" }, { "label": "Anime", "value": "anime" }, { "label": "Cartoon", "value": "cartoon" }, { "label": "Comedy", "value": "comedy" }, { "label": "Comic", "value": "comic" }, { "label": "Cooking", "value": "cooking" }, { "label": "Detective", "value": "detective" }, { "label": "Doujinshi", "value": "doujinshi" }, { "label": "Drama", "value": "drama" }, { "label": "Ecchi", "value": "ecchi" }, { "label": "Fantasy", "value": "fantasy" }, { "label": "Gender Bender", "value": "gender-bender" }, { "label": "Harem", "value": "harem" }, { "label": "Historical", "value": "historical" }, { "label": "Horror", "value": "horror" }, { "label": "Josei", "value": "josei" }, { "label": "Live action", "value": "live-action" }, { "label": "Manga", "value": "manga" }, { "label": "Manhua", "value": "manhua" }, { "label": "Manhwa", "value": "manhwa" }, { "label": "Martial Arts", "value": "martial-arts" }, { "label": "Mature", "value": "mature" }, { "label": "Mecha", "value": "mecha" }, { "label": "Mystery", "value": "mystery" }, { "label": "One shot", "value": "one-shot" }, { "label": "Psychological", "value": "psychological" }, { "label": "Romance", "value": "romance" }, { "label": "School Life", "value": "school-life" }, { "label": "Sci-fi", "value": "sci-fi" }, { "label": "Seinen", "value": "seinen" }, { "label": "Shoujo", "value": "shoujo" }, { "label": "Shoujo Ai", "value": "shoujo-ai" }, { "label": "Shounen", "value": "shounen" }, { "label": "Shounen Ai", "value": "shounen-ai" }, { "label": "Slice of Life", "value": "slice-of-life" }, { "label": "Smut", "value": "smut" }, { "label": "Soft Yaoi", "value": "soft-yaoi" }, { "label": "Soft Yuri", "value": "soft-yuri" }, { "label": "Sports", "value": "sports" }, { "label": "Supernatural", "value": "supernatural" }, { "label": "Tragedy", "value": "tragedy" }, { "label": "Webtoon", "value": "webtoon" }, { "label": "Yaoi", "value": "yaoi" }, { "label": "Yuri", "value": "yuri" }], "inputType": filterInputs_1.FilterInputs.Picker }]; diff --git a/js/plugins/english/NoobchanTranslation[madara].js b/js/plugins/english/NoobchanTranslation[madara].js deleted file mode 100644 index 1e1ced7..0000000 --- a/js/plugins/english/NoobchanTranslation[madara].js +++ /dev/null @@ -1,178 +0,0 @@ -"use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.filters = exports.fetchImage = exports.searchNovels = exports.parseChapter = exports.parseNovelAndChapters = exports.popularNovels = exports.site = exports.version = exports.icon = exports.name = exports.id = void 0; -const cheerio_1 = require("cheerio"); -const fetch_1 = require("@libs/fetch"); -const defaultCover_1 = require("@libs/defaultCover"); -const novelStatus_1 = require("@libs/novelStatus"); -const parseMadaraDate_1 = require("@libs/parseMadaraDate"); -const dayjs_1 = __importDefault(require("dayjs")); -exports.id = "noobchanTL"; -exports.name = "Noobchan Translation [madara]"; -exports.icon = "multisrc/madara/icons/noobchantranslation.png"; -exports.version = "1.0.0"; -exports.site = "https://noobchan.xyz/"; -const baseUrl = exports.site; -const popularNovels = (pageNo, { filters, showLatestNovels }) => __awaiter(void 0, void 0, void 0, function* () { - const novels = []; - let url = exports.site; - if (filters === null || filters === void 0 ? void 0 : filters.genres) { - url += "novel-genre/" + filters.genres + '/'; - } - else { - url += "novel/"; - } - url += '/page/' + pageNo + '/' + - '?m_orderby=' + (showLatestNovels ? 'latest' : ((filters === null || filters === void 0 ? void 0 : filters.sort) || 'rating')); - const body = yield (0, fetch_1.fetchApi)(url).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.manga-title-badges').remove(); - loadedCheerio('.page-item-detail').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - let novelUrl = loadedCheerio(this).find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - }); - return novels; -}); -exports.popularNovels = popularNovels; -const parseNovelAndChapters = (novelUrl) => __awaiter(void 0, void 0, void 0, function* () { - const novel = { - url: novelUrl, - }; - const body = yield (0, fetch_1.fetchApi)(novelUrl).then(res => res.text()); - let loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.manga-title-badges').remove(); - novel.name = loadedCheerio('.post-title h1').text().trim(); - novel.cover = - loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || - loadedCheerio('.summary_image > a > img').attr('data-src') || - loadedCheerio('.summary_image > a > img').attr('src') || - defaultCover_1.defaultCover; - loadedCheerio('.post-content_item, .post-content').each(function () { - const detailName = loadedCheerio(this).find('h5').text().trim(); - const detail = loadedCheerio(this).find('.summary-content').text().trim(); - switch (detailName) { - case 'Genre(s)': - case 'التصنيفات': - novel.genres = detail.replace(/[\t\n]/g, ','); - break; - case 'Author(s)': - case 'المؤلف': - case 'المؤلف (ين)': - novel.author = detail; - break; - case 'Status': - case 'الحالة': - novel.status = - detail.includes('OnGoing') || detail.includes('مستمرة') - ? novelStatus_1.NovelStatus.Ongoing - : novelStatus_1.NovelStatus.Completed; - break; - } - }); - loadedCheerio('div.summary__content .code-block,script').remove(); - novel.summary = loadedCheerio('div.summary__content').text().trim(); - let html; - if (true) { - const novelId = loadedCheerio('.rating-post-id').attr('value') || - loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; - const body = { - action: "manga_get_chapters", - manga: novelId, - }; - html = yield (0, fetch_1.fetchApi)(baseUrl + 'wp-admin/admin-ajax.php', { - method: 'POST', - body: JSON.stringify(body), - }) - .then(res => res.text()); - } - else { - html = yield (0, fetch_1.fetchApi)(baseUrl + 'ajax/chapters/', { method: 'POST' }) - .then(res => res.text()); - } - if (html !== '0') { - loadedCheerio = (0, cheerio_1.load)(html); - } - const chapters = []; - loadedCheerio('.wp-manga-chapter').each(function () { - const chapterName = loadedCheerio(this).find('a').text().trim(); - let releaseDate = null; - releaseDate = loadedCheerio(this) - .find('span.chapter-release-date') - .text() - .trim(); - if (releaseDate) { - releaseDate = (0, parseMadaraDate_1.parseMadaraDate)(releaseDate); - } - else { - /** - * Insert current date - */ - releaseDate = (0, dayjs_1.default)().format('LL'); - } - let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; - chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); - }); - novel.chapters = chapters.reverse(); - return novel; -}); -exports.parseNovelAndChapters = parseNovelAndChapters; -const parseChapter = (chapterUrl) => __awaiter(void 0, void 0, void 0, function* () { - const url = baseUrl + "/" + "novel" + "/" + chapterUrl; - const body = yield (0, fetch_1.fetchApi)(chapterUrl).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - const chapterText = loadedCheerio('.text-left').html() || - loadedCheerio('.text-right').html() || - loadedCheerio('.entry-content').html(); - return chapterText; -}); -exports.parseChapter = parseChapter; -const searchNovels = (searchTerm) => __awaiter(void 0, void 0, void 0, function* () { - const novels = []; - const url = baseUrl + "?s=" + searchTerm + "&post_type=wp-manga"; - const body = yield (0, fetch_1.fetchApi)(url).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.c-tabs-item__content').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - let novelUrl = loadedCheerio(this) - .find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - }); - return novels; -}); -exports.searchNovels = searchNovels; -const fetchImage = (url) => __awaiter(void 0, void 0, void 0, function* () { - return yield (0, fetch_1.fetchFile)(url); -}); -exports.fetchImage = fetchImage; -exports.filters = []; diff --git a/js/plugins/english/NovelFullMe.js b/js/plugins/english/NovelFullMe.js deleted file mode 100644 index 5c2345a..0000000 --- a/js/plugins/english/NovelFullMe.js +++ /dev/null @@ -1,131 +0,0 @@ -"use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.fetchImage = exports.searchNovels = exports.parseChapter = exports.parseNovelAndChapters = exports.popularNovels = exports.icon = exports.version = exports.site = exports.name = exports.id = void 0; -const cheerio_1 = require("cheerio"); -const fetch_1 = require("@libs/fetch"); -exports.id = "NF.me"; -exports.name = "NovelFull.me"; -exports.site = "https://novelfull.me/"; -exports.version = "1.0.0"; -exports.icon = "src/en/novelfullme/icon.png"; -const baseUrl = exports.site; -const popularNovels = function (page) { - return __awaiter(this, void 0, void 0, function* () { - const url = `${baseUrl}popular?page=${page}`; - const result = yield (0, fetch_1.fetchApi)(url); - const body = yield result.text(); - const loadedCheerio = (0, cheerio_1.load)(body); - let novels = []; - loadedCheerio(".book-item").each(function () { - var _a; - const novelName = loadedCheerio(this).find(".title").text(); - const novelCover = "https:" + loadedCheerio(this).find("img").attr("data-src"); - const novelUrl = baseUrl + - ((_a = loadedCheerio(this).find(".title a").attr("href")) === null || _a === void 0 ? void 0 : _a.substring(1)); - const novel = { name: novelName, cover: novelCover, url: novelUrl }; - novels.push(novel); - }); - return novels; - }); -}; -exports.popularNovels = popularNovels; -const parseNovelAndChapters = function (novelUrl) { - var _a, _b; - return __awaiter(this, void 0, void 0, function* () { - const url = novelUrl; - const result = yield (0, fetch_1.fetchApi)(url); - const body = yield result.text(); - let loadedCheerio = (0, cheerio_1.load)(body); - let novel = { - url, - name: "", - cover: "", - author: "", - status: "", - genres: "", - summary: "", - chapters: [], - }; - novel.name = loadedCheerio(".name h1").text().trim(); - novel.cover = - "https:" + loadedCheerio(".img-cover img").attr("data-src"); - novel.summary = loadedCheerio("body > div.layout > div.main-container.book-details > div > div.row.no-gutters > div.col-lg-8 > div.mt-1 > div.section.box.mt-1.summary > div.section-body > p.content") - .text() - .trim(); - novel.author = "Unknown"; - novel.status = (_a = loadedCheerio("body > div.layout > div.main-container.book-details > div > div.row.no-gutters > div.col-lg-8 > div.book-info > div.detail > div.meta.box.mt-1.p-10 > p:nth-child(1) > a > span") - .text()) === null || _a === void 0 ? void 0 : _a.trim(); - novel.genres = (_b = loadedCheerio("body > div.layout > div.main-container.book-details > div > div.row.no-gutters > div.col-lg-8 > div.book-info > div.detail > div.meta.box.mt-1.p-10 > p:nth-child(2)") - .text()) === null || _b === void 0 ? void 0 : _b.replace("Genres :", "").replace(/[\s\n]+/g, " ").trim(); - let chapters = []; - const chaptersUrl = novelUrl.replace(baseUrl, "https://novelfull.me/api/novels/") + - "/chapters?source=detail"; - const chaptersRequest = yield (0, fetch_1.fetchApi)(chaptersUrl); - const chaptersHtml = yield chaptersRequest.text(); - loadedCheerio = (0, cheerio_1.load)(chaptersHtml); - loadedCheerio("li").each(function () { - const chapterName = loadedCheerio(this) - .find(".chapter-title") - .text() - .trim(); - const releaseDate = loadedCheerio(this) - .find(".chapter-update") - .text() - .trim(); - const chapterUrl = loadedCheerio(this).find("a").attr("href"); - if (!chapterUrl) - return; - chapters.push({ - name: chapterName, - releaseTime: releaseDate, - url: chapterUrl, - }); - }); - novel.chapters = chapters.reverse(); - return novel; - }); -}; -exports.parseNovelAndChapters = parseNovelAndChapters; -const parseChapter = function (chapterUrl) { - return __awaiter(this, void 0, void 0, function* () { - const url = chapterUrl; - const result = yield (0, fetch_1.fetchApi)(url); - const body = yield result.text(); - let loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio("#listen-chapter").remove(); - loadedCheerio("#google_translate_element").remove(); - const chapterText = loadedCheerio(".chapter__content").html(); - return chapterText; - }); -}; -exports.parseChapter = parseChapter; -const searchNovels = function (searchTerm) { - return __awaiter(this, void 0, void 0, function* () { - const url = `${baseUrl}search?status=all&sort=views&q=${searchTerm}`; - const result = yield (0, fetch_1.fetchApi)(url); - const body = yield result.text(); - let loadedCheerio = (0, cheerio_1.load)(body); - let novels = []; - loadedCheerio(".book-item").each(function () { - var _a; - const novelName = loadedCheerio(this).find(".title").text(); - const novelCover = "https:" + loadedCheerio(this).find("img").attr("data-src"); - const novelUrl = baseUrl + - ((_a = loadedCheerio(this).find(".title a").attr("href")) === null || _a === void 0 ? void 0 : _a.substring(1)); - const novel = { name: novelName, cover: novelCover, url: novelUrl }; - novels.push(novel); - }); - return novels; - }); -}; -exports.searchNovels = searchNovels; -exports.fetchImage = fetch_1.fetchFile; diff --git a/js/plugins/english/NovelMultiverse[madara].js b/js/plugins/english/NovelMultiverse[madara].js deleted file mode 100644 index 47c6c3c..0000000 --- a/js/plugins/english/NovelMultiverse[madara].js +++ /dev/null @@ -1,179 +0,0 @@ -"use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.filters = exports.fetchImage = exports.searchNovels = exports.parseChapter = exports.parseNovelAndChapters = exports.popularNovels = exports.site = exports.version = exports.icon = exports.name = exports.id = void 0; -const cheerio_1 = require("cheerio"); -const fetch_1 = require("@libs/fetch"); -const filterInputs_1 = require("@libs/filterInputs"); -const defaultCover_1 = require("@libs/defaultCover"); -const novelStatus_1 = require("@libs/novelStatus"); -const parseMadaraDate_1 = require("@libs/parseMadaraDate"); -const dayjs_1 = __importDefault(require("dayjs")); -exports.id = "novelmultiverse"; -exports.name = "NovelMultiverse [madara]"; -exports.icon = "multisrc/madara/icons/novelmultiverse.png"; -exports.version = "1.0.0"; -exports.site = "https://www.novelmultiverse.com/"; -const baseUrl = exports.site; -const popularNovels = (pageNo, { filters, showLatestNovels }) => __awaiter(void 0, void 0, void 0, function* () { - const novels = []; - let url = exports.site; - if (filters === null || filters === void 0 ? void 0 : filters.genres) { - url += "novel-genre/" + filters.genres + '/'; - } - else { - url += "novel/"; - } - url += '/page/' + pageNo + '/' + - '?m_orderby=' + (showLatestNovels ? 'latest' : ((filters === null || filters === void 0 ? void 0 : filters.sort) || 'rating')); - const body = yield (0, fetch_1.fetchApi)(url).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.manga-title-badges').remove(); - loadedCheerio('.page-item-detail').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - let novelUrl = loadedCheerio(this).find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - }); - return novels; -}); -exports.popularNovels = popularNovels; -const parseNovelAndChapters = (novelUrl) => __awaiter(void 0, void 0, void 0, function* () { - const novel = { - url: novelUrl, - }; - const body = yield (0, fetch_1.fetchApi)(novelUrl).then(res => res.text()); - let loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.manga-title-badges').remove(); - novel.name = loadedCheerio('.post-title h1').text().trim(); - novel.cover = - loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || - loadedCheerio('.summary_image > a > img').attr('data-src') || - loadedCheerio('.summary_image > a > img').attr('src') || - defaultCover_1.defaultCover; - loadedCheerio('.post-content_item, .post-content').each(function () { - const detailName = loadedCheerio(this).find('h5').text().trim(); - const detail = loadedCheerio(this).find('.summary-content').text().trim(); - switch (detailName) { - case 'Genre(s)': - case 'التصنيفات': - novel.genres = detail.replace(/[\t\n]/g, ','); - break; - case 'Author(s)': - case 'المؤلف': - case 'المؤلف (ين)': - novel.author = detail; - break; - case 'Status': - case 'الحالة': - novel.status = - detail.includes('OnGoing') || detail.includes('مستمرة') - ? novelStatus_1.NovelStatus.Ongoing - : novelStatus_1.NovelStatus.Completed; - break; - } - }); - loadedCheerio('div.summary__content .code-block,script').remove(); - novel.summary = loadedCheerio('div.summary__content').text().trim(); - let html; - if (false) { - const novelId = loadedCheerio('.rating-post-id').attr('value') || - loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; - const body = { - action: "manga_get_chapters", - manga: novelId, - }; - html = yield (0, fetch_1.fetchApi)(baseUrl + 'wp-admin/admin-ajax.php', { - method: 'POST', - body: JSON.stringify(body), - }) - .then(res => res.text()); - } - else { - html = yield (0, fetch_1.fetchApi)(baseUrl + 'ajax/chapters/', { method: 'POST' }) - .then(res => res.text()); - } - if (html !== '0') { - loadedCheerio = (0, cheerio_1.load)(html); - } - const chapters = []; - loadedCheerio('.wp-manga-chapter').each(function () { - const chapterName = loadedCheerio(this).find('a').text().trim(); - let releaseDate = null; - releaseDate = loadedCheerio(this) - .find('span.chapter-release-date') - .text() - .trim(); - if (releaseDate) { - releaseDate = (0, parseMadaraDate_1.parseMadaraDate)(releaseDate); - } - else { - /** - * Insert current date - */ - releaseDate = (0, dayjs_1.default)().format('LL'); - } - let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; - chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); - }); - novel.chapters = chapters.reverse(); - return novel; -}); -exports.parseNovelAndChapters = parseNovelAndChapters; -const parseChapter = (chapterUrl) => __awaiter(void 0, void 0, void 0, function* () { - const url = baseUrl + "/" + "novel" + "/" + chapterUrl; - const body = yield (0, fetch_1.fetchApi)(chapterUrl).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - const chapterText = loadedCheerio('.text-left').html() || - loadedCheerio('.text-right').html() || - loadedCheerio('.entry-content').html(); - return chapterText; -}); -exports.parseChapter = parseChapter; -const searchNovels = (searchTerm) => __awaiter(void 0, void 0, void 0, function* () { - const novels = []; - const url = baseUrl + "?s=" + searchTerm + "&post_type=wp-manga"; - const body = yield (0, fetch_1.fetchApi)(url).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.c-tabs-item__content').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - let novelUrl = loadedCheerio(this) - .find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - }); - return novels; -}); -exports.searchNovels = searchNovels; -const fetchImage = (url) => __awaiter(void 0, void 0, void 0, function* () { - return yield (0, fetch_1.fetchFile)(url); -}); -exports.fetchImage = fetchImage; -exports.filters = [{ "key": "sort", "label": "Order by", "values": [{ "label": "Rating", "value": "rating" }, { "label": "A-Z", "value": "alphabet" }, { "label": "Latest", "value": "latest" }, { "label": "Most Views", "value": "views" }, { "label": "New", "value": "new-manga" }, { "label": "Trending", "value": "trending" }], "inputType": filterInputs_1.FilterInputs.Picker }, { "key": "genres", "label": "GENRES", "values": [{ "label": "Action", "value": "action" }, { "label": "Adult", "value": "adult" }, { "label": "Adventure", "value": "adventure" }, { "label": "Anime", "value": "anime" }, { "label": "Cartoon", "value": "cartoon" }, { "label": "Comedy", "value": "comedy" }, { "label": "Comic", "value": "comic" }, { "label": "Cooking", "value": "cooking" }, { "label": "Detective", "value": "detective" }, { "label": "Doujinshi", "value": "doujinshi" }, { "label": "Drama", "value": "drama" }, { "label": "Ecchi", "value": "ecchi" }, { "label": "Fantasy", "value": "fantasy" }, { "label": "Gender Bender", "value": "gender-bender" }, { "label": "Harem", "value": "harem" }, { "label": "Historical", "value": "historical" }, { "label": "Horror", "value": "horror" }, { "label": "Josei", "value": "josei" }, { "label": "Live action", "value": "live-action" }, { "label": "Manga", "value": "manga" }, { "label": "Manhua", "value": "manhua" }, { "label": "Manhwa", "value": "manhwa" }, { "label": "Martial Arts", "value": "martial-arts" }, { "label": "Mature", "value": "mature" }, { "label": "Mecha", "value": "mecha" }, { "label": "Mystery", "value": "mystery" }, { "label": "One shot", "value": "one-shot" }, { "label": "Original", "value": "original" }, { "label": "Psychological", "value": "psychological" }, { "label": "Romance", "value": "romance" }, { "label": "School Life", "value": "school-life" }, { "label": "Sci-fi", "value": "sci-fi" }, { "label": "Seinen", "value": "seinen" }, { "label": "Shoujo", "value": "shoujo" }, { "label": "Shoujo Ai", "value": "shoujo-ai" }, { "label": "Shounen", "value": "shounen" }, { "label": "Shounen Ai", "value": "shounen-ai" }, { "label": "Slice of Life", "value": "slice-of-life" }, { "label": "Smut", "value": "smut" }, { "label": "Soft Yaoi", "value": "soft-yaoi" }, { "label": "Soft Yuri", "value": "soft-yuri" }, { "label": "Sports", "value": "sports" }, { "label": "Supernatural", "value": "supernatural" }, { "label": "Tragedy", "value": "tragedy" }, { "label": "Translation", "value": "translation" }, { "label": "Webtoon", "value": "webtoon" }, { "label": "Wuxia", "value": "wuxia" }, { "label": "Xianxia", "value": "xianxia" }, { "label": "Xuanhuan", "value": "xuanhuan" }, { "label": "Yaoi", "value": "yaoi" }, { "label": "Yuri", "value": "yuri" }], "inputType": filterInputs_1.FilterInputs.Picker }]; diff --git a/js/plugins/english/NovelOnline.js b/js/plugins/english/NovelOnline.js deleted file mode 100644 index dc2d8e1..0000000 --- a/js/plugins/english/NovelOnline.js +++ /dev/null @@ -1,104 +0,0 @@ -"use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.fetchImage = exports.parseChapter = exports.popularNovels = exports.parseNovelAndChapters = exports.searchNovels = exports.version = exports.icon = exports.site = exports.name = exports.id = void 0; -const cheerio_1 = require("cheerio"); -const fetch_1 = require("@libs/fetch"); -exports.id = "NO.net"; -exports.name = "novelsOnline"; -exports.site = "https://novelsonline.net"; -exports.icon = "src/coverNotAvailable.jpg"; -exports.version = "1.0.0"; -const pluginId = exports.id; -const searchNovels = function (searchTerm) { - return __awaiter(this, void 0, void 0, function* () { - const result = yield (0, fetch_1.fetchApi)("https://novelsonline.net/sResults.php", { - headers: { - Accept: "*/*", - "Accept-Language": "pl,en-US;q=0.7,en;q=0.3", - "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8", - }, - method: "POST", - body: "q=" + encodeURIComponent(searchTerm), - }, pluginId).then((res) => res.text()); - let $ = (0, cheerio_1.load)(result); - const headers = $("li"); - return headers - .map((i, h) => { - const novelName = $(h).text(); - const novelUrl = $(h).find("a").attr("href"); - const novelCover = $(h).find("img").attr("src"); - if (!novelUrl) { - return null; - } - return { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - }) - .get() - .filter((sr) => sr !== null); - }); -}; -exports.searchNovels = searchNovels; -const parseNovelAndChapters = function (novelUrl) { - return __awaiter(this, void 0, void 0, function* () { - let novel = { - url: novelUrl, - chapters: [], - }; - const result = yield (0, fetch_1.fetchApi)(novelUrl).then((res) => res.text()); - let $ = (0, cheerio_1.load)(result); - novel.name = $("h1").text(); - novel.cover = $(".novel-cover").find("a > img").attr("src"); - novel.author = $("div.novel-details > div:nth-child(5) > div.novel-detail-body") - .find("li") - .map((_, el) => $(el).text()) - .get() - .join(", "); - novel.genres = $("div.novel-details > div:nth-child(2) > div.novel-detail-body") - .find("li") - .map((_, el) => $(el).text()) - .get() - .join(","); - novel.summary = $("div.novel-right > div > div:nth-child(1) > div.novel-detail-body").text(); - novel.chapters = $("ul.chapter-chs > li > a") - .map((_, el) => { - const chapterUrl = $(el).attr("href"); - const chapterName = $(el).text(); - return { - name: chapterName, - releaseTime: "", - url: chapterUrl, - }; - }) - .get(); - return novel; - }); -}; -exports.parseNovelAndChapters = parseNovelAndChapters; -const popularNovels = function (page) { - return __awaiter(this, void 0, void 0, function* () { - return []; /** TO DO */ - }); -}; -exports.popularNovels = popularNovels; -const parseChapter = function (chapterUrl) { - return __awaiter(this, void 0, void 0, function* () { - const result = yield (0, fetch_1.fetchApi)(chapterUrl).then((res) => res.text()); - let loadedCheerio = (0, cheerio_1.load)(result); - const chapterText = loadedCheerio("#contentall").html() || ""; - return chapterText; - }); -}; -exports.parseChapter = parseChapter; -exports.fetchImage = fetch_1.fetchFile; diff --git a/js/plugins/english/NovelR18[madara].js b/js/plugins/english/NovelR18[madara].js deleted file mode 100644 index 0f5fa7c..0000000 --- a/js/plugins/english/NovelR18[madara].js +++ /dev/null @@ -1,179 +0,0 @@ -"use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.filters = exports.fetchImage = exports.searchNovels = exports.parseChapter = exports.parseNovelAndChapters = exports.popularNovels = exports.site = exports.version = exports.icon = exports.name = exports.id = void 0; -const cheerio_1 = require("cheerio"); -const fetch_1 = require("@libs/fetch"); -const filterInputs_1 = require("@libs/filterInputs"); -const defaultCover_1 = require("@libs/defaultCover"); -const novelStatus_1 = require("@libs/novelStatus"); -const parseMadaraDate_1 = require("@libs/parseMadaraDate"); -const dayjs_1 = __importDefault(require("dayjs")); -exports.id = "novelr18"; -exports.name = "NovelR18 [madara]"; -exports.icon = "multisrc/madara/icons/novelr18.png"; -exports.version = "1.0.0"; -exports.site = "https://novelr18.com/"; -const baseUrl = exports.site; -const popularNovels = (pageNo, { filters, showLatestNovels }) => __awaiter(void 0, void 0, void 0, function* () { - const novels = []; - let url = exports.site; - if (filters === null || filters === void 0 ? void 0 : filters.genres) { - url += "novel-genre/" + filters.genres + '/'; - } - else { - url += "novel/"; - } - url += '/page/' + pageNo + '/' + - '?m_orderby=' + (showLatestNovels ? 'latest' : ((filters === null || filters === void 0 ? void 0 : filters.sort) || 'rating')); - const body = yield (0, fetch_1.fetchApi)(url).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.manga-title-badges').remove(); - loadedCheerio('.page-item-detail').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - let novelUrl = loadedCheerio(this).find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - }); - return novels; -}); -exports.popularNovels = popularNovels; -const parseNovelAndChapters = (novelUrl) => __awaiter(void 0, void 0, void 0, function* () { - const novel = { - url: novelUrl, - }; - const body = yield (0, fetch_1.fetchApi)(novelUrl).then(res => res.text()); - let loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.manga-title-badges').remove(); - novel.name = loadedCheerio('.post-title h1').text().trim(); - novel.cover = - loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || - loadedCheerio('.summary_image > a > img').attr('data-src') || - loadedCheerio('.summary_image > a > img').attr('src') || - defaultCover_1.defaultCover; - loadedCheerio('.post-content_item, .post-content').each(function () { - const detailName = loadedCheerio(this).find('h5').text().trim(); - const detail = loadedCheerio(this).find('.summary-content').text().trim(); - switch (detailName) { - case 'Genre(s)': - case 'التصنيفات': - novel.genres = detail.replace(/[\t\n]/g, ','); - break; - case 'Author(s)': - case 'المؤلف': - case 'المؤلف (ين)': - novel.author = detail; - break; - case 'Status': - case 'الحالة': - novel.status = - detail.includes('OnGoing') || detail.includes('مستمرة') - ? novelStatus_1.NovelStatus.Ongoing - : novelStatus_1.NovelStatus.Completed; - break; - } - }); - loadedCheerio('div.summary__content .code-block,script').remove(); - novel.summary = loadedCheerio('div.summary__content').text().trim(); - let html; - if (true) { - const novelId = loadedCheerio('.rating-post-id').attr('value') || - loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; - const body = { - action: "manga_get_chapters", - manga: novelId, - }; - html = yield (0, fetch_1.fetchApi)(baseUrl + 'wp-admin/admin-ajax.php', { - method: 'POST', - body: JSON.stringify(body), - }) - .then(res => res.text()); - } - else { - html = yield (0, fetch_1.fetchApi)(baseUrl + 'ajax/chapters/', { method: 'POST' }) - .then(res => res.text()); - } - if (html !== '0') { - loadedCheerio = (0, cheerio_1.load)(html); - } - const chapters = []; - loadedCheerio('.wp-manga-chapter').each(function () { - const chapterName = loadedCheerio(this).find('a').text().trim(); - let releaseDate = null; - releaseDate = loadedCheerio(this) - .find('span.chapter-release-date') - .text() - .trim(); - if (releaseDate) { - releaseDate = (0, parseMadaraDate_1.parseMadaraDate)(releaseDate); - } - else { - /** - * Insert current date - */ - releaseDate = (0, dayjs_1.default)().format('LL'); - } - let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; - chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); - }); - novel.chapters = chapters.reverse(); - return novel; -}); -exports.parseNovelAndChapters = parseNovelAndChapters; -const parseChapter = (chapterUrl) => __awaiter(void 0, void 0, void 0, function* () { - const url = baseUrl + "/" + "manga" + "/" + chapterUrl; - const body = yield (0, fetch_1.fetchApi)(chapterUrl).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - const chapterText = loadedCheerio('.text-left').html() || - loadedCheerio('.text-right').html() || - loadedCheerio('.entry-content').html(); - return chapterText; -}); -exports.parseChapter = parseChapter; -const searchNovels = (searchTerm) => __awaiter(void 0, void 0, void 0, function* () { - const novels = []; - const url = baseUrl + "?s=" + searchTerm + "&post_type=wp-manga"; - const body = yield (0, fetch_1.fetchApi)(url).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.c-tabs-item__content').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - let novelUrl = loadedCheerio(this) - .find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - }); - return novels; -}); -exports.searchNovels = searchNovels; -const fetchImage = (url) => __awaiter(void 0, void 0, void 0, function* () { - return yield (0, fetch_1.fetchFile)(url); -}); -exports.fetchImage = fetchImage; -exports.filters = [{ "key": "sort", "label": "Sort by :", "values": [{ "label": "Rating", "value": "rating" }, { "label": "A-Z", "value": "alphabet" }, { "label": "Latest Update", "value": "latest" }, { "label": "Most Views", "value": "views" }, { "label": "Newly Added Novels", "value": "new-manga" }, { "label": "Trending", "value": "trending" }], "inputType": filterInputs_1.FilterInputs.Picker }]; diff --git a/js/plugins/english/NovelTranslate[madara].js b/js/plugins/english/NovelTranslate[madara].js deleted file mode 100644 index ce55467..0000000 --- a/js/plugins/english/NovelTranslate[madara].js +++ /dev/null @@ -1,179 +0,0 @@ -"use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.filters = exports.fetchImage = exports.searchNovels = exports.parseChapter = exports.parseNovelAndChapters = exports.popularNovels = exports.site = exports.version = exports.icon = exports.name = exports.id = void 0; -const cheerio_1 = require("cheerio"); -const fetch_1 = require("@libs/fetch"); -const filterInputs_1 = require("@libs/filterInputs"); -const defaultCover_1 = require("@libs/defaultCover"); -const novelStatus_1 = require("@libs/novelStatus"); -const parseMadaraDate_1 = require("@libs/parseMadaraDate"); -const dayjs_1 = __importDefault(require("dayjs")); -exports.id = "novelTL"; -exports.name = "NovelTranslate [madara]"; -exports.icon = "multisrc/madara/icons/noveltranslate.png"; -exports.version = "1.0.0"; -exports.site = "https://noveltranslate.com/"; -const baseUrl = exports.site; -const popularNovels = (pageNo, { filters, showLatestNovels }) => __awaiter(void 0, void 0, void 0, function* () { - const novels = []; - let url = exports.site; - if (filters === null || filters === void 0 ? void 0 : filters.genres) { - url += "manga-genre/" + filters.genres + '/'; - } - else { - url += "all-novels/"; - } - url += '/page/' + pageNo + '/' + - '?m_orderby=' + (showLatestNovels ? 'latest' : ((filters === null || filters === void 0 ? void 0 : filters.sort) || 'rating')); - const body = yield (0, fetch_1.fetchApi)(url).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.manga-title-badges').remove(); - loadedCheerio('.page-item-detail').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - let novelUrl = loadedCheerio(this).find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - }); - return novels; -}); -exports.popularNovels = popularNovels; -const parseNovelAndChapters = (novelUrl) => __awaiter(void 0, void 0, void 0, function* () { - const novel = { - url: novelUrl, - }; - const body = yield (0, fetch_1.fetchApi)(novelUrl).then(res => res.text()); - let loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.manga-title-badges').remove(); - novel.name = loadedCheerio('.post-title h1').text().trim(); - novel.cover = - loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || - loadedCheerio('.summary_image > a > img').attr('data-src') || - loadedCheerio('.summary_image > a > img').attr('src') || - defaultCover_1.defaultCover; - loadedCheerio('.post-content_item, .post-content').each(function () { - const detailName = loadedCheerio(this).find('h5').text().trim(); - const detail = loadedCheerio(this).find('.summary-content').text().trim(); - switch (detailName) { - case 'Genre(s)': - case 'التصنيفات': - novel.genres = detail.replace(/[\t\n]/g, ','); - break; - case 'Author(s)': - case 'المؤلف': - case 'المؤلف (ين)': - novel.author = detail; - break; - case 'Status': - case 'الحالة': - novel.status = - detail.includes('OnGoing') || detail.includes('مستمرة') - ? novelStatus_1.NovelStatus.Ongoing - : novelStatus_1.NovelStatus.Completed; - break; - } - }); - loadedCheerio('div.summary__content .code-block,script').remove(); - novel.summary = loadedCheerio('div.summary__content').text().trim(); - let html; - if (false) { - const novelId = loadedCheerio('.rating-post-id').attr('value') || - loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; - const body = { - action: "manga_get_chapters", - manga: novelId, - }; - html = yield (0, fetch_1.fetchApi)(baseUrl + 'wp-admin/admin-ajax.php', { - method: 'POST', - body: JSON.stringify(body), - }) - .then(res => res.text()); - } - else { - html = yield (0, fetch_1.fetchApi)(baseUrl + 'ajax/chapters/', { method: 'POST' }) - .then(res => res.text()); - } - if (html !== '0') { - loadedCheerio = (0, cheerio_1.load)(html); - } - const chapters = []; - loadedCheerio('.wp-manga-chapter').each(function () { - const chapterName = loadedCheerio(this).find('a').text().trim(); - let releaseDate = null; - releaseDate = loadedCheerio(this) - .find('span.chapter-release-date') - .text() - .trim(); - if (releaseDate) { - releaseDate = (0, parseMadaraDate_1.parseMadaraDate)(releaseDate); - } - else { - /** - * Insert current date - */ - releaseDate = (0, dayjs_1.default)().format('LL'); - } - let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; - chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); - }); - novel.chapters = chapters.reverse(); - return novel; -}); -exports.parseNovelAndChapters = parseNovelAndChapters; -const parseChapter = (chapterUrl) => __awaiter(void 0, void 0, void 0, function* () { - const url = baseUrl + "/" + "manga" + "/" + chapterUrl; - const body = yield (0, fetch_1.fetchApi)(chapterUrl).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - const chapterText = loadedCheerio('.text-left').html() || - loadedCheerio('.text-right').html() || - loadedCheerio('.entry-content').html(); - return chapterText; -}); -exports.parseChapter = parseChapter; -const searchNovels = (searchTerm) => __awaiter(void 0, void 0, void 0, function* () { - const novels = []; - const url = baseUrl + "?s=" + searchTerm + "&post_type=wp-manga"; - const body = yield (0, fetch_1.fetchApi)(url).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.c-tabs-item__content').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - let novelUrl = loadedCheerio(this) - .find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - }); - return novels; -}); -exports.searchNovels = searchNovels; -const fetchImage = (url) => __awaiter(void 0, void 0, void 0, function* () { - return yield (0, fetch_1.fetchFile)(url); -}); -exports.fetchImage = fetchImage; -exports.filters = [{ "key": "sort", "label": "Order by", "values": [{ "label": "Rating", "value": "rating" }, { "label": "A-Z", "value": "alphabet" }, { "label": "Latest", "value": "latest" }, { "label": "Most Views", "value": "views" }, { "label": "New", "value": "new-manga" }, { "label": "Trending", "value": "trending" }], "inputType": filterInputs_1.FilterInputs.Picker }, { "key": "genres", "label": "GENRES", "values": [{ "label": "Action", "value": "action" }, { "label": "Adult", "value": "adult" }, { "label": "Adventure", "value": "adventure" }, { "label": "Bleach", "value": "bleach" }, { "label": "Chinese", "value": "chinese" }, { "label": "Comedy", "value": "comedy" }, { "label": "Conan", "value": "conan" }, { "label": "cooking", "value": "cooking" }, { "label": "Dragon Ball", "value": "dragon-ball" }, { "label": "Drama", "value": "drama" }, { "label": "Ecchi", "value": "ecchi" }, { "label": "Erciyuan", "value": "erciyuan" }, { "label": "Fairy Tail", "value": "fairy-tail" }, { "label": "Faloo", "value": "faloo" }, { "label": "Fan-Fiction", "value": "fan-fiction" }, { "label": "Fantasy", "value": "fantasy" }, { "label": "FoodWars!", "value": "foodwars" }, { "label": "Game", "value": "game" }, { "label": "Gender Bender", "value": "gender-bender" }, { "label": "Harem", "value": "harem" }, { "label": "Historical", "value": "historical" }, { "label": "Horror", "value": "horror" }, { "label": "Hunter x Hunter", "value": "hunter-x-hunter" }, { "label": "Isekai", "value": "isekai" }, { "label": "Japanese", "value": "japanese" }, { "label": "Jojo", "value": "jojo" }, { "label": "Josei", "value": "josei" }, { "label": "Korean", "value": "korean" }, { "label": "Martial Arts", "value": "martial-arts" }, { "label": "Marvel", "value": "marvel" }, { "label": "Mature", "value": "mature" }, { "label": "Mecha", "value": "mecha" }, { "label": "Military", "value": "military" }, { "label": "Mystery", "value": "mystery" }, { "label": "Naruto", "value": "naruto" }, { "label": "One piece", "value": "one-piece" }, { "label": "Pokemon", "value": "pokemon" }, { "label": "Political", "value": "political" }, { "label": "Psychological", "value": "psychological" }, { "label": "Romance", "value": "romance" }, { "label": "School Life", "value": "school-life" }, { "label": "Sci-fi", "value": "sci-fi" }, { "label": "Seinen", "value": "seinen" }, { "label": "Shoujo", "value": "shoujo" }, { "label": "Shoujo Ai", "value": "shoujo-ai" }, { "label": "Shounen", "value": "shounen" }, { "label": "Shounen Ai", "value": "shounen-ai" }, { "label": "Slice of Life", "value": "slice-of-life" }, { "label": "Smut", "value": "smut" }, { "label": "Sport", "value": "sport" }, { "label": "Sports", "value": "sports" }, { "label": "Supernatural", "value": "supernatural" }, { "label": "System", "value": "system" }, { "label": "Toriko", "value": "toriko" }, { "label": "Tragedy", "value": "tragedy" }, { "label": "Urban", "value": "urban" }, { "label": "Urban Life", "value": "urban-life" }, { "label": "Wuxia", "value": "wuxia" }, { "label": "Xianxia", "value": "xianxia" }, { "label": "Xuanhuan", "value": "xuanhuan" }, { "label": "Yaoi", "value": "yaoi" }, { "label": "Yuri", "value": "yuri" }], "inputType": filterInputs_1.FilterInputs.Picker }]; diff --git a/js/plugins/english/Novelmtcom[readwn].js b/js/plugins/english/Novelmtcom[readwn].js deleted file mode 100644 index 5b369c6..0000000 --- a/js/plugins/english/Novelmtcom[readwn].js +++ /dev/null @@ -1,163 +0,0 @@ -"use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.filters = exports.fetchImage = exports.searchNovels = exports.parseChapter = exports.parseNovelAndChapters = exports.popularNovels = exports.site = exports.version = exports.icon = exports.name = exports.id = void 0; -const cheerio_1 = require("cheerio"); -// import dayjs from 'dayjs'; -const fetch_1 = require("@libs/fetch"); -const parseMadaraDate_1 = require("@libs/parseMadaraDate"); -// import { isUrlAbsolute } from '@libs/isAbsoluteUrl'; -// import { showToast } from "@libs/showToast"; -const filterInputs_1 = require("@libs/filterInputs"); -// import { NovelStatus } from '@libs/novelStatus'; -// import { defaultCover } from "@libs/defaultCover"; -exports.id = "Novelmt.com"; -exports.name = "Novelmt.com"; -exports.icon = "multisrc/readwn/icons/novelmt.png"; -exports.version = "1.0.0"; -exports.site = "https://www.novelmt.com/"; -const popularNovels = function (page, { filters, showLatestNovels }) { - return __awaiter(this, void 0, void 0, function* () { - const novels = []; - const pageNo = page - 1; - let url = exports.site + 'list/'; - url += ((filters === null || filters === void 0 ? void 0 : filters.genres) || 'all') + '/'; - url += ((filters === null || filters === void 0 ? void 0 : filters.status) || 'all') + '-'; - url += (showLatestNovels ? 'lastdotime' : (filters === null || filters === void 0 ? void 0 : filters.sort) || 'newstime') + '-'; - url += pageNo + '.html'; - const result = yield (0, fetch_1.fetchApi)(url); - const body = yield result.text(); - const loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('li.novel-item').each(function () { - const novelName = loadedCheerio(this).find('h4').text(); - const novelUrl = exports.site + loadedCheerio(this).find('a').attr('href'); - const coverUri = loadedCheerio(this) - .find('.novel-cover > img') - .attr('data-src'); - const novelCover = exports.site + coverUri; - const novel = { name: novelName, cover: novelCover, url: novelUrl }; - novels.push(novel); - }); - return novels; - }); -}; -exports.popularNovels = popularNovels; -const parseNovelAndChapters = function (novelUrl) { - return __awaiter(this, void 0, void 0, function* () { - const result = yield (0, fetch_1.fetchApi)(novelUrl); - const body = yield result.text(); - let loadedCheerio = (0, cheerio_1.load)(body); - const novel = { - url: novelUrl, - chapters: [], - }; - novel.name = loadedCheerio('h1.novel-title').text(); - const coverUri = loadedCheerio('figure.cover > img').attr('data-src'); - novel.cover = exports.site + coverUri; - novel.summary = loadedCheerio('.summary') - .text() - .replace('Summary', '') - .trim(); - novel.genres = ''; - loadedCheerio('div.categories > ul > li').each(function () { - novel.genres += loadedCheerio(this).text().trim() + ','; - }); - loadedCheerio('div.header-stats > span').each(function () { - if (loadedCheerio(this).find('small').text() === 'Status') { - novel.status = loadedCheerio(this).find('strong').text(); - } - }); - novel.genres = novel.genres.slice(0, -1); - novel.author = loadedCheerio('span[itemprop=author]').text(); - let novelChapters = []; - const novelId = novelUrl.replace('.html', '').replace(exports.site, ''); - const latestChapterNo = parseInt(loadedCheerio('.header-stats') - .find('span > strong') - .first() - .text() - .trim()); - let lastChapterNo = 1; - loadedCheerio('.chapter-list li').each(function () { - var _a; - const chapterName = loadedCheerio(this) - .find('a .chapter-title') - .text() - .trim(); - const chapterUrl = exports.site + ((_a = loadedCheerio(this).find('a').attr('href')) === null || _a === void 0 ? void 0 : _a.trim()); - const releaseDate = loadedCheerio(this) - .find('a .chapter-update') - .text() - .trim(); - lastChapterNo = parseInt(loadedCheerio(this).find('a .chapter-no').text().trim()); - const chapter = { name: chapterName, releaseTime: (0, parseMadaraDate_1.parseMadaraDate)(releaseDate), url: chapterUrl }; - novelChapters.push(chapter); - }); - // Itterate once more before loop to finish off - lastChapterNo++; - for (let i = lastChapterNo; i <= latestChapterNo; i++) { - const chapterName = 'Chapter ' + i; - const chapterUrl = exports.site + novelId + '_' + i + '.html'; - const releaseDate = null; - const chapter = { name: chapterName, releaseTime: releaseDate, url: chapterUrl }; - novelChapters.push(chapter); - } - novel.chapters = novelChapters; - return novel; - }); -}; -exports.parseNovelAndChapters = parseNovelAndChapters; -const parseChapter = function (chapterUrl) { - return __awaiter(this, void 0, void 0, function* () { - const result = yield (0, fetch_1.fetchApi)(chapterUrl); - const body = yield result.text(); - const loadedCheerio = (0, cheerio_1.load)(body); - const chapterText = loadedCheerio('.chapter-content').html(); - return chapterText; - }); -}; -exports.parseChapter = parseChapter; -const searchNovels = (searchTerm) => __awaiter(void 0, void 0, void 0, function* () { - const novels = []; - const searchUrl = exports.site + 'e/search/index.php'; - const result = yield (0, fetch_1.fetchApi)(searchUrl, { - headers: { - 'Content-Type': 'application/x-www-form-urlencoded', - Referer: exports.site + 'search.html', - Origin: exports.site, - 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36', - }, - method: 'POST', - body: JSON.stringify({ - show: 'title', - tempid: 1, - tbname: 'news', - keyboard: searchTerm, - }), - }); - const body = yield result.text(); - const loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('li.novel-item').each(function () { - const novelName = loadedCheerio(this).find('h4').text(); - const novelUrl = exports.site + loadedCheerio(this).find('a').attr('href'); - const coverUri = exports.site + loadedCheerio(this).find('img').attr('data-src'); - const novelCover = exports.site + coverUri; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - }); - return novels; -}); -exports.searchNovels = searchNovels; -exports.fetchImage = fetch_1.fetchFile; -exports.filters = [{ "key": "sort", "label": "Sort By", "values": [{ "label": "New", "value": "newstime" }, { "label": "Popular", "value": "onclick" }, { "label": "Updates", "value": "lastdotime" }], "inputType": filterInputs_1.FilterInputs.Picker }, { "key": "status", "label": "Status", "values": [{ "label": "All", "value": "all" }, { "label": "Completed", "value": "Completed" }, { "label": "Ongoing", "value": "Ongoing" }], "inputType": filterInputs_1.FilterInputs.Picker }, { "key": "genres", "label": "Genre / Category", "values": [{ "label": "All", "value": "all" }, { "label": "Action", "value": "action" }, { "label": "Adult", "value": "adult" }, { "label": "Adventure", "value": "adventure" }, { "label": "Billionaire", "value": "billionaire" }, { "label": "CEO", "value": "ceo" }, { "label": "Chinese", "value": "chinese" }, { "label": "Comedy", "value": "comedy" }, { "label": "Contemporary Romance", "value": "contemporary-romance" }, { "label": "Drama", "value": "drama" }, { "label": "Eastern Fantasy", "value": "eastern-fantasy" }, { "label": "Ecchi", "value": "ecchi" }, { "label": "Erciyuan", "value": "erciyuan" }, { "label": "Faloo", "value": "faloo" }, { "label": "Fan-Fiction", "value": "fan-fiction" }, { "label": "Fantasy", "value": "fantasy" }, { "label": "Fantasy Romance", "value": "fantasy-romance" }, { "label": "Farming", "value": "farming" }, { "label": "Game", "value": "game" }, { "label": "Games", "value": "games" }, { "label": "Gay Romance", "value": "gay-romance" }, { "label": "Gender Bender", "value": "gender-bender" }, { "label": "Harem", "value": "harem" }, { "label": "Historical", "value": "historical" }, { "label": "Historical Romance", "value": "historical-romance" }, { "label": "Horror", "value": "horror" }, { "label": "Isekai", "value": "isekai" }, { "label": "Japanese", "value": "japanese" }, { "label": "Josei", "value": "josei" }, { "label": "Korean", "value": "korean" }, { "label": "Lolicon", "value": "lolicon" }, { "label": "Magic", "value": "magic" }, { "label": "Magical Realism", "value": "magical-realism" }, { "label": "Martial Arts", "value": "martial-arts" }, { "label": "Mature", "value": "mature" }, { "label": "Mecha", "value": "mecha" }, { "label": "Military", "value": "military" }, { "label": "Modern Life", "value": "modern-life" }, { "label": "Modern Romance", "value": "modern-romance" }, { "label": "Mystery", "value": "mystery" }, { "label": "Psychological", "value": "psychological" }, { "label": "Romance", "value": "romance" }, { "label": "Romantic", "value": "romantic" }, { "label": "School Life", "value": "school-life" }, { "label": "Sci-fi", "value": "sci-fi" }, { "label": "Seinen", "value": "seinen" }, { "label": "Shoujo", "value": "shoujo" }, { "label": "Shoujo Ai", "value": "shoujo-ai" }, { "label": "Shounen", "value": "shounen" }, { "label": "Shounen Ai", "value": "shounen-ai" }, { "label": "Slice of Life", "value": "slice-of-life" }, { "label": "Smut", "value": "smut" }, { "label": "Sports", "value": "sports" }, { "label": "Supernatural", "value": "supernatural" }, { "label": "Tragedy", "value": "tragedy" }, { "label": "Two-dimensional", "value": "two-dimensional" }, { "label": "Urban", "value": "urban" }, { "label": "Urban Life", "value": "urban-life" }, { "label": "Video Games", "value": "video-games" }, { "label": "Virtual Reality", "value": "virtual-reality" }, { "label": "Wuxia", "value": "wuxia" }, { "label": "Xianxia", "value": "xianxia" }, { "label": "Xuanhuan", "value": "xuanhuan" }, { "label": "Yaoi", "value": "yaoi" }, { "label": "Yuri", "value": "yuri" }], "inputType": filterInputs_1.FilterInputs.Picker }]; diff --git a/js/plugins/english/Novelroomnet[madara].js b/js/plugins/english/Novelroomnet[madara].js deleted file mode 100644 index b48ffab..0000000 --- a/js/plugins/english/Novelroomnet[madara].js +++ /dev/null @@ -1,178 +0,0 @@ -"use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.filters = exports.fetchImage = exports.searchNovels = exports.parseChapter = exports.parseNovelAndChapters = exports.popularNovels = exports.site = exports.version = exports.icon = exports.name = exports.id = void 0; -const cheerio_1 = require("cheerio"); -const fetch_1 = require("@libs/fetch"); -const defaultCover_1 = require("@libs/defaultCover"); -const novelStatus_1 = require("@libs/novelStatus"); -const parseMadaraDate_1 = require("@libs/parseMadaraDate"); -const dayjs_1 = __importDefault(require("dayjs")); -exports.id = "novelroom"; -exports.name = "Novelroom.net [madara]"; -exports.icon = "multisrc/madara/icons/novelroom.net.png"; -exports.version = "1.0.0"; -exports.site = "https://novelroom.net/"; -const baseUrl = exports.site; -const popularNovels = (pageNo, { filters, showLatestNovels }) => __awaiter(void 0, void 0, void 0, function* () { - const novels = []; - let url = exports.site; - if (filters === null || filters === void 0 ? void 0 : filters.genres) { - url += "novel-genre/" + filters.genres + '/'; - } - else { - url += "manga/"; - } - url += '/page/' + pageNo + '/' + - '?m_orderby=' + (showLatestNovels ? 'latest' : ((filters === null || filters === void 0 ? void 0 : filters.sort) || 'rating')); - const body = yield (0, fetch_1.fetchApi)(url).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.manga-title-badges').remove(); - loadedCheerio('.page-item-detail').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - let novelUrl = loadedCheerio(this).find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - }); - return novels; -}); -exports.popularNovels = popularNovels; -const parseNovelAndChapters = (novelUrl) => __awaiter(void 0, void 0, void 0, function* () { - const novel = { - url: novelUrl, - }; - const body = yield (0, fetch_1.fetchApi)(novelUrl).then(res => res.text()); - let loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.manga-title-badges').remove(); - novel.name = loadedCheerio('.post-title h1').text().trim(); - novel.cover = - loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || - loadedCheerio('.summary_image > a > img').attr('data-src') || - loadedCheerio('.summary_image > a > img').attr('src') || - defaultCover_1.defaultCover; - loadedCheerio('.post-content_item, .post-content').each(function () { - const detailName = loadedCheerio(this).find('h5').text().trim(); - const detail = loadedCheerio(this).find('.summary-content').text().trim(); - switch (detailName) { - case 'Genre(s)': - case 'التصنيفات': - novel.genres = detail.replace(/[\t\n]/g, ','); - break; - case 'Author(s)': - case 'المؤلف': - case 'المؤلف (ين)': - novel.author = detail; - break; - case 'Status': - case 'الحالة': - novel.status = - detail.includes('OnGoing') || detail.includes('مستمرة') - ? novelStatus_1.NovelStatus.Ongoing - : novelStatus_1.NovelStatus.Completed; - break; - } - }); - loadedCheerio('div.summary__content .code-block,script').remove(); - novel.summary = loadedCheerio('div.summary__content').text().trim(); - let html; - if (false) { - const novelId = loadedCheerio('.rating-post-id').attr('value') || - loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; - const body = { - action: "manga_get_chapters", - manga: novelId, - }; - html = yield (0, fetch_1.fetchApi)(baseUrl + 'wp-admin/admin-ajax.php', { - method: 'POST', - body: JSON.stringify(body), - }) - .then(res => res.text()); - } - else { - html = yield (0, fetch_1.fetchApi)(baseUrl + 'ajax/chapters/', { method: 'POST' }) - .then(res => res.text()); - } - if (html !== '0') { - loadedCheerio = (0, cheerio_1.load)(html); - } - const chapters = []; - loadedCheerio('.wp-manga-chapter').each(function () { - const chapterName = loadedCheerio(this).find('a').text().trim(); - let releaseDate = null; - releaseDate = loadedCheerio(this) - .find('span.chapter-release-date') - .text() - .trim(); - if (releaseDate) { - releaseDate = (0, parseMadaraDate_1.parseMadaraDate)(releaseDate); - } - else { - /** - * Insert current date - */ - releaseDate = (0, dayjs_1.default)().format('LL'); - } - let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; - chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); - }); - novel.chapters = chapters.reverse(); - return novel; -}); -exports.parseNovelAndChapters = parseNovelAndChapters; -const parseChapter = (chapterUrl) => __awaiter(void 0, void 0, void 0, function* () { - const url = baseUrl + "/" + "manga" + "/" + chapterUrl; - const body = yield (0, fetch_1.fetchApi)(chapterUrl).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - const chapterText = loadedCheerio('.text-left').html() || - loadedCheerio('.text-right').html() || - loadedCheerio('.entry-content').html(); - return chapterText; -}); -exports.parseChapter = parseChapter; -const searchNovels = (searchTerm) => __awaiter(void 0, void 0, void 0, function* () { - const novels = []; - const url = baseUrl + "?s=" + searchTerm + "&post_type=wp-manga"; - const body = yield (0, fetch_1.fetchApi)(url).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.c-tabs-item__content').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - let novelUrl = loadedCheerio(this) - .find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - }); - return novels; -}); -exports.searchNovels = searchNovels; -const fetchImage = (url) => __awaiter(void 0, void 0, void 0, function* () { - return yield (0, fetch_1.fetchFile)(url); -}); -exports.fetchImage = fetchImage; -exports.filters = []; diff --git a/js/plugins/english/Novelstic[madara].js b/js/plugins/english/Novelstic[madara].js deleted file mode 100644 index 198324b..0000000 --- a/js/plugins/english/Novelstic[madara].js +++ /dev/null @@ -1,179 +0,0 @@ -"use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.filters = exports.fetchImage = exports.searchNovels = exports.parseChapter = exports.parseNovelAndChapters = exports.popularNovels = exports.site = exports.version = exports.icon = exports.name = exports.id = void 0; -const cheerio_1 = require("cheerio"); -const fetch_1 = require("@libs/fetch"); -const filterInputs_1 = require("@libs/filterInputs"); -const defaultCover_1 = require("@libs/defaultCover"); -const novelStatus_1 = require("@libs/novelStatus"); -const parseMadaraDate_1 = require("@libs/parseMadaraDate"); -const dayjs_1 = __importDefault(require("dayjs")); -exports.id = "novelstic"; -exports.name = "Novelstic [madara]"; -exports.icon = "multisrc/madara/icons/novelstic.png"; -exports.version = "1.0.0"; -exports.site = "https://novelstic.com/"; -const baseUrl = exports.site; -const popularNovels = (pageNo, { filters, showLatestNovels }) => __awaiter(void 0, void 0, void 0, function* () { - const novels = []; - let url = exports.site; - if (filters === null || filters === void 0 ? void 0 : filters.genres) { - url += "novel-genre/" + filters.genres + '/'; - } - else { - url += "novel/"; - } - url += '/page/' + pageNo + '/' + - '?m_orderby=' + (showLatestNovels ? 'latest' : ((filters === null || filters === void 0 ? void 0 : filters.sort) || 'rating')); - const body = yield (0, fetch_1.fetchApi)(url).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.manga-title-badges').remove(); - loadedCheerio('.page-item-detail').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - let novelUrl = loadedCheerio(this).find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - }); - return novels; -}); -exports.popularNovels = popularNovels; -const parseNovelAndChapters = (novelUrl) => __awaiter(void 0, void 0, void 0, function* () { - const novel = { - url: novelUrl, - }; - const body = yield (0, fetch_1.fetchApi)(novelUrl).then(res => res.text()); - let loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.manga-title-badges').remove(); - novel.name = loadedCheerio('.post-title h1').text().trim(); - novel.cover = - loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || - loadedCheerio('.summary_image > a > img').attr('data-src') || - loadedCheerio('.summary_image > a > img').attr('src') || - defaultCover_1.defaultCover; - loadedCheerio('.post-content_item, .post-content').each(function () { - const detailName = loadedCheerio(this).find('h5').text().trim(); - const detail = loadedCheerio(this).find('.summary-content').text().trim(); - switch (detailName) { - case 'Genre(s)': - case 'التصنيفات': - novel.genres = detail.replace(/[\t\n]/g, ','); - break; - case 'Author(s)': - case 'المؤلف': - case 'المؤلف (ين)': - novel.author = detail; - break; - case 'Status': - case 'الحالة': - novel.status = - detail.includes('OnGoing') || detail.includes('مستمرة') - ? novelStatus_1.NovelStatus.Ongoing - : novelStatus_1.NovelStatus.Completed; - break; - } - }); - loadedCheerio('div.summary__content .code-block,script').remove(); - novel.summary = loadedCheerio('div.summary__content').text().trim(); - let html; - if (true) { - const novelId = loadedCheerio('.rating-post-id').attr('value') || - loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; - const body = { - action: "manga_get_chapters", - manga: novelId, - }; - html = yield (0, fetch_1.fetchApi)(baseUrl + 'wp-admin/admin-ajax.php', { - method: 'POST', - body: JSON.stringify(body), - }) - .then(res => res.text()); - } - else { - html = yield (0, fetch_1.fetchApi)(baseUrl + 'ajax/chapters/', { method: 'POST' }) - .then(res => res.text()); - } - if (html !== '0') { - loadedCheerio = (0, cheerio_1.load)(html); - } - const chapters = []; - loadedCheerio('.wp-manga-chapter').each(function () { - const chapterName = loadedCheerio(this).find('a').text().trim(); - let releaseDate = null; - releaseDate = loadedCheerio(this) - .find('span.chapter-release-date') - .text() - .trim(); - if (releaseDate) { - releaseDate = (0, parseMadaraDate_1.parseMadaraDate)(releaseDate); - } - else { - /** - * Insert current date - */ - releaseDate = (0, dayjs_1.default)().format('LL'); - } - let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; - chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); - }); - novel.chapters = chapters.reverse(); - return novel; -}); -exports.parseNovelAndChapters = parseNovelAndChapters; -const parseChapter = (chapterUrl) => __awaiter(void 0, void 0, void 0, function* () { - const url = baseUrl + "/" + "novel" + "/" + chapterUrl; - const body = yield (0, fetch_1.fetchApi)(chapterUrl).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - const chapterText = loadedCheerio('.text-left').html() || - loadedCheerio('.text-right').html() || - loadedCheerio('.entry-content').html(); - return chapterText; -}); -exports.parseChapter = parseChapter; -const searchNovels = (searchTerm) => __awaiter(void 0, void 0, void 0, function* () { - const novels = []; - const url = baseUrl + "?s=" + searchTerm + "&post_type=wp-manga"; - const body = yield (0, fetch_1.fetchApi)(url).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.c-tabs-item__content').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - let novelUrl = loadedCheerio(this) - .find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - }); - return novels; -}); -exports.searchNovels = searchNovels; -const fetchImage = (url) => __awaiter(void 0, void 0, void 0, function* () { - return yield (0, fetch_1.fetchFile)(url); -}); -exports.fetchImage = fetchImage; -exports.filters = [{ "key": "sort", "label": "Order by", "values": [{ "label": "Rating", "value": "rating" }, { "label": "A-Z", "value": "alphabet" }, { "label": "Latest", "value": "latest" }, { "label": "Most Views", "value": "views" }, { "label": "New", "value": "new-manga" }, { "label": "Trending", "value": "trending" }], "inputType": filterInputs_1.FilterInputs.Picker }]; diff --git a/js/plugins/english/OnlyMTL[madara].js b/js/plugins/english/OnlyMTL[madara].js deleted file mode 100644 index 768c663..0000000 --- a/js/plugins/english/OnlyMTL[madara].js +++ /dev/null @@ -1,178 +0,0 @@ -"use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.filters = exports.fetchImage = exports.searchNovels = exports.parseChapter = exports.parseNovelAndChapters = exports.popularNovels = exports.site = exports.version = exports.icon = exports.name = exports.id = void 0; -const cheerio_1 = require("cheerio"); -const fetch_1 = require("@libs/fetch"); -const defaultCover_1 = require("@libs/defaultCover"); -const novelStatus_1 = require("@libs/novelStatus"); -const parseMadaraDate_1 = require("@libs/parseMadaraDate"); -const dayjs_1 = __importDefault(require("dayjs")); -exports.id = "onlymtl"; -exports.name = "OnlyMTL [madara]"; -exports.icon = "multisrc/madara/icons/onlymtl.png"; -exports.version = "1.0.0"; -exports.site = "https://www.onlymtl.com/"; -const baseUrl = exports.site; -const popularNovels = (pageNo, { filters, showLatestNovels }) => __awaiter(void 0, void 0, void 0, function* () { - const novels = []; - let url = exports.site; - if (filters === null || filters === void 0 ? void 0 : filters.genres) { - url += "novel-genre/" + filters.genres + '/'; - } - else { - url += "novel/"; - } - url += '/page/' + pageNo + '/' + - '?m_orderby=' + (showLatestNovels ? 'latest' : ((filters === null || filters === void 0 ? void 0 : filters.sort) || 'rating')); - const body = yield (0, fetch_1.fetchApi)(url).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.manga-title-badges').remove(); - loadedCheerio('.page-item-detail').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - let novelUrl = loadedCheerio(this).find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - }); - return novels; -}); -exports.popularNovels = popularNovels; -const parseNovelAndChapters = (novelUrl) => __awaiter(void 0, void 0, void 0, function* () { - const novel = { - url: novelUrl, - }; - const body = yield (0, fetch_1.fetchApi)(novelUrl).then(res => res.text()); - let loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.manga-title-badges').remove(); - novel.name = loadedCheerio('.post-title h1').text().trim(); - novel.cover = - loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || - loadedCheerio('.summary_image > a > img').attr('data-src') || - loadedCheerio('.summary_image > a > img').attr('src') || - defaultCover_1.defaultCover; - loadedCheerio('.post-content_item, .post-content').each(function () { - const detailName = loadedCheerio(this).find('h5').text().trim(); - const detail = loadedCheerio(this).find('.summary-content').text().trim(); - switch (detailName) { - case 'Genre(s)': - case 'التصنيفات': - novel.genres = detail.replace(/[\t\n]/g, ','); - break; - case 'Author(s)': - case 'المؤلف': - case 'المؤلف (ين)': - novel.author = detail; - break; - case 'Status': - case 'الحالة': - novel.status = - detail.includes('OnGoing') || detail.includes('مستمرة') - ? novelStatus_1.NovelStatus.Ongoing - : novelStatus_1.NovelStatus.Completed; - break; - } - }); - loadedCheerio('div.summary__content .code-block,script').remove(); - novel.summary = loadedCheerio('div.summary__content').text().trim(); - let html; - if (true) { - const novelId = loadedCheerio('.rating-post-id').attr('value') || - loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; - const body = { - action: "manga_get_chapters", - manga: novelId, - }; - html = yield (0, fetch_1.fetchApi)(baseUrl + 'wp-admin/admin-ajax.php', { - method: 'POST', - body: JSON.stringify(body), - }) - .then(res => res.text()); - } - else { - html = yield (0, fetch_1.fetchApi)(baseUrl + 'ajax/chapters/', { method: 'POST' }) - .then(res => res.text()); - } - if (html !== '0') { - loadedCheerio = (0, cheerio_1.load)(html); - } - const chapters = []; - loadedCheerio('.wp-manga-chapter').each(function () { - const chapterName = loadedCheerio(this).find('a').text().trim(); - let releaseDate = null; - releaseDate = loadedCheerio(this) - .find('span.chapter-release-date') - .text() - .trim(); - if (releaseDate) { - releaseDate = (0, parseMadaraDate_1.parseMadaraDate)(releaseDate); - } - else { - /** - * Insert current date - */ - releaseDate = (0, dayjs_1.default)().format('LL'); - } - let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; - chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); - }); - novel.chapters = chapters.reverse(); - return novel; -}); -exports.parseNovelAndChapters = parseNovelAndChapters; -const parseChapter = (chapterUrl) => __awaiter(void 0, void 0, void 0, function* () { - const url = baseUrl + "/" + "novel" + "/" + chapterUrl; - const body = yield (0, fetch_1.fetchApi)(chapterUrl).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - const chapterText = loadedCheerio('.text-left').html() || - loadedCheerio('.text-right').html() || - loadedCheerio('.entry-content').html(); - return chapterText; -}); -exports.parseChapter = parseChapter; -const searchNovels = (searchTerm) => __awaiter(void 0, void 0, void 0, function* () { - const novels = []; - const url = baseUrl + "?s=" + searchTerm + "&post_type=wp-manga"; - const body = yield (0, fetch_1.fetchApi)(url).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.c-tabs-item__content').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - let novelUrl = loadedCheerio(this) - .find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - }); - return novels; -}); -exports.searchNovels = searchNovels; -const fetchImage = (url) => __awaiter(void 0, void 0, void 0, function* () { - return yield (0, fetch_1.fetchFile)(url); -}); -exports.fetchImage = fetchImage; -exports.filters = []; diff --git a/js/plugins/english/ReadWebNovels[madara].js b/js/plugins/english/ReadWebNovels[madara].js deleted file mode 100644 index e066bb2..0000000 --- a/js/plugins/english/ReadWebNovels[madara].js +++ /dev/null @@ -1,179 +0,0 @@ -"use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.filters = exports.fetchImage = exports.searchNovels = exports.parseChapter = exports.parseNovelAndChapters = exports.popularNovels = exports.site = exports.version = exports.icon = exports.name = exports.id = void 0; -const cheerio_1 = require("cheerio"); -const fetch_1 = require("@libs/fetch"); -const filterInputs_1 = require("@libs/filterInputs"); -const defaultCover_1 = require("@libs/defaultCover"); -const novelStatus_1 = require("@libs/novelStatus"); -const parseMadaraDate_1 = require("@libs/parseMadaraDate"); -const dayjs_1 = __importDefault(require("dayjs")); -exports.id = "readwebnovels"; -exports.name = "ReadWebNovels [madara]"; -exports.icon = "multisrc/madara/icons/readwebnovels.png"; -exports.version = "1.0.0"; -exports.site = "https://readwebnovels.net/"; -const baseUrl = exports.site; -const popularNovels = (pageNo, { filters, showLatestNovels }) => __awaiter(void 0, void 0, void 0, function* () { - const novels = []; - let url = exports.site; - if (filters === null || filters === void 0 ? void 0 : filters.genres) { - url += "novel-genre/" + filters.genres + '/'; - } - else { - url += "novel/"; - } - url += '/page/' + pageNo + '/' + - '?m_orderby=' + (showLatestNovels ? 'latest' : ((filters === null || filters === void 0 ? void 0 : filters.sort) || 'rating')); - const body = yield (0, fetch_1.fetchApi)(url).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.manga-title-badges').remove(); - loadedCheerio('.page-item-detail').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - let novelUrl = loadedCheerio(this).find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - }); - return novels; -}); -exports.popularNovels = popularNovels; -const parseNovelAndChapters = (novelUrl) => __awaiter(void 0, void 0, void 0, function* () { - const novel = { - url: novelUrl, - }; - const body = yield (0, fetch_1.fetchApi)(novelUrl).then(res => res.text()); - let loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.manga-title-badges').remove(); - novel.name = loadedCheerio('.post-title h1').text().trim(); - novel.cover = - loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || - loadedCheerio('.summary_image > a > img').attr('data-src') || - loadedCheerio('.summary_image > a > img').attr('src') || - defaultCover_1.defaultCover; - loadedCheerio('.post-content_item, .post-content').each(function () { - const detailName = loadedCheerio(this).find('h5').text().trim(); - const detail = loadedCheerio(this).find('.summary-content').text().trim(); - switch (detailName) { - case 'Genre(s)': - case 'التصنيفات': - novel.genres = detail.replace(/[\t\n]/g, ','); - break; - case 'Author(s)': - case 'المؤلف': - case 'المؤلف (ين)': - novel.author = detail; - break; - case 'Status': - case 'الحالة': - novel.status = - detail.includes('OnGoing') || detail.includes('مستمرة') - ? novelStatus_1.NovelStatus.Ongoing - : novelStatus_1.NovelStatus.Completed; - break; - } - }); - loadedCheerio('div.summary__content .code-block,script').remove(); - novel.summary = loadedCheerio('div.summary__content').text().trim(); - let html; - if (false) { - const novelId = loadedCheerio('.rating-post-id').attr('value') || - loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; - const body = { - action: "manga_get_chapters", - manga: novelId, - }; - html = yield (0, fetch_1.fetchApi)(baseUrl + 'wp-admin/admin-ajax.php', { - method: 'POST', - body: JSON.stringify(body), - }) - .then(res => res.text()); - } - else { - html = yield (0, fetch_1.fetchApi)(baseUrl + 'ajax/chapters/', { method: 'POST' }) - .then(res => res.text()); - } - if (html !== '0') { - loadedCheerio = (0, cheerio_1.load)(html); - } - const chapters = []; - loadedCheerio('.wp-manga-chapter').each(function () { - const chapterName = loadedCheerio(this).find('a').text().trim(); - let releaseDate = null; - releaseDate = loadedCheerio(this) - .find('span.chapter-release-date') - .text() - .trim(); - if (releaseDate) { - releaseDate = (0, parseMadaraDate_1.parseMadaraDate)(releaseDate); - } - else { - /** - * Insert current date - */ - releaseDate = (0, dayjs_1.default)().format('LL'); - } - let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; - chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); - }); - novel.chapters = chapters.reverse(); - return novel; -}); -exports.parseNovelAndChapters = parseNovelAndChapters; -const parseChapter = (chapterUrl) => __awaiter(void 0, void 0, void 0, function* () { - const url = baseUrl + "/" + "novel" + "/" + chapterUrl; - const body = yield (0, fetch_1.fetchApi)(chapterUrl).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - const chapterText = loadedCheerio('.text-left').html() || - loadedCheerio('.text-right').html() || - loadedCheerio('.entry-content').html(); - return chapterText; -}); -exports.parseChapter = parseChapter; -const searchNovels = (searchTerm) => __awaiter(void 0, void 0, void 0, function* () { - const novels = []; - const url = baseUrl + "?s=" + searchTerm + "&post_type=wp-manga"; - const body = yield (0, fetch_1.fetchApi)(url).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.c-tabs-item__content').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - let novelUrl = loadedCheerio(this) - .find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - }); - return novels; -}); -exports.searchNovels = searchNovels; -const fetchImage = (url) => __awaiter(void 0, void 0, void 0, function* () { - return yield (0, fetch_1.fetchFile)(url); -}); -exports.fetchImage = fetchImage; -exports.filters = [{ "key": "sort", "label": "Order by", "values": [{ "label": "Rating", "value": "rating" }, { "label": "A-Z", "value": "alphabet" }, { "label": "Latest", "value": "latest" }, { "label": "Most Views", "value": "views" }, { "label": "New", "value": "new-manga" }, { "label": "Trending", "value": "trending" }], "inputType": filterInputs_1.FilterInputs.Picker }]; diff --git a/js/plugins/english/Readwncom[readwn].js b/js/plugins/english/Readwncom[readwn].js deleted file mode 100644 index 84d16a7..0000000 --- a/js/plugins/english/Readwncom[readwn].js +++ /dev/null @@ -1,163 +0,0 @@ -"use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.filters = exports.fetchImage = exports.searchNovels = exports.parseChapter = exports.parseNovelAndChapters = exports.popularNovels = exports.site = exports.version = exports.icon = exports.name = exports.id = void 0; -const cheerio_1 = require("cheerio"); -// import dayjs from 'dayjs'; -const fetch_1 = require("@libs/fetch"); -const parseMadaraDate_1 = require("@libs/parseMadaraDate"); -// import { isUrlAbsolute } from '@libs/isAbsoluteUrl'; -// import { showToast } from "@libs/showToast"; -const filterInputs_1 = require("@libs/filterInputs"); -// import { NovelStatus } from '@libs/novelStatus'; -// import { defaultCover } from "@libs/defaultCover"; -exports.id = "Readwn.com"; -exports.name = "Readwn.com"; -exports.icon = "multisrc/readwn/icons/readwn.png"; -exports.version = "1.0.0"; -exports.site = "https://www.readwn.com/"; -const popularNovels = function (page, { filters, showLatestNovels }) { - return __awaiter(this, void 0, void 0, function* () { - const novels = []; - const pageNo = page - 1; - let url = exports.site + 'list/'; - url += ((filters === null || filters === void 0 ? void 0 : filters.genres) || 'all') + '/'; - url += ((filters === null || filters === void 0 ? void 0 : filters.status) || 'all') + '-'; - url += (showLatestNovels ? 'lastdotime' : (filters === null || filters === void 0 ? void 0 : filters.sort) || 'newstime') + '-'; - url += pageNo + '.html'; - const result = yield (0, fetch_1.fetchApi)(url); - const body = yield result.text(); - const loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('li.novel-item').each(function () { - const novelName = loadedCheerio(this).find('h4').text(); - const novelUrl = exports.site + loadedCheerio(this).find('a').attr('href'); - const coverUri = loadedCheerio(this) - .find('.novel-cover > img') - .attr('data-src'); - const novelCover = exports.site + coverUri; - const novel = { name: novelName, cover: novelCover, url: novelUrl }; - novels.push(novel); - }); - return novels; - }); -}; -exports.popularNovels = popularNovels; -const parseNovelAndChapters = function (novelUrl) { - return __awaiter(this, void 0, void 0, function* () { - const result = yield (0, fetch_1.fetchApi)(novelUrl); - const body = yield result.text(); - let loadedCheerio = (0, cheerio_1.load)(body); - const novel = { - url: novelUrl, - chapters: [], - }; - novel.name = loadedCheerio('h1.novel-title').text(); - const coverUri = loadedCheerio('figure.cover > img').attr('data-src'); - novel.cover = exports.site + coverUri; - novel.summary = loadedCheerio('.summary') - .text() - .replace('Summary', '') - .trim(); - novel.genres = ''; - loadedCheerio('div.categories > ul > li').each(function () { - novel.genres += loadedCheerio(this).text().trim() + ','; - }); - loadedCheerio('div.header-stats > span').each(function () { - if (loadedCheerio(this).find('small').text() === 'Status') { - novel.status = loadedCheerio(this).find('strong').text(); - } - }); - novel.genres = novel.genres.slice(0, -1); - novel.author = loadedCheerio('span[itemprop=author]').text(); - let novelChapters = []; - const novelId = novelUrl.replace('.html', '').replace(exports.site, ''); - const latestChapterNo = parseInt(loadedCheerio('.header-stats') - .find('span > strong') - .first() - .text() - .trim()); - let lastChapterNo = 1; - loadedCheerio('.chapter-list li').each(function () { - var _a; - const chapterName = loadedCheerio(this) - .find('a .chapter-title') - .text() - .trim(); - const chapterUrl = exports.site + ((_a = loadedCheerio(this).find('a').attr('href')) === null || _a === void 0 ? void 0 : _a.trim()); - const releaseDate = loadedCheerio(this) - .find('a .chapter-update') - .text() - .trim(); - lastChapterNo = parseInt(loadedCheerio(this).find('a .chapter-no').text().trim()); - const chapter = { name: chapterName, releaseTime: (0, parseMadaraDate_1.parseMadaraDate)(releaseDate), url: chapterUrl }; - novelChapters.push(chapter); - }); - // Itterate once more before loop to finish off - lastChapterNo++; - for (let i = lastChapterNo; i <= latestChapterNo; i++) { - const chapterName = 'Chapter ' + i; - const chapterUrl = exports.site + novelId + '_' + i + '.html'; - const releaseDate = null; - const chapter = { name: chapterName, releaseTime: releaseDate, url: chapterUrl }; - novelChapters.push(chapter); - } - novel.chapters = novelChapters; - return novel; - }); -}; -exports.parseNovelAndChapters = parseNovelAndChapters; -const parseChapter = function (chapterUrl) { - return __awaiter(this, void 0, void 0, function* () { - const result = yield (0, fetch_1.fetchApi)(chapterUrl); - const body = yield result.text(); - const loadedCheerio = (0, cheerio_1.load)(body); - const chapterText = loadedCheerio('.chapter-content').html(); - return chapterText; - }); -}; -exports.parseChapter = parseChapter; -const searchNovels = (searchTerm) => __awaiter(void 0, void 0, void 0, function* () { - const novels = []; - const searchUrl = exports.site + 'e/search/index.php'; - const result = yield (0, fetch_1.fetchApi)(searchUrl, { - headers: { - 'Content-Type': 'application/x-www-form-urlencoded', - Referer: exports.site + 'search.html', - Origin: exports.site, - 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36', - }, - method: 'POST', - body: JSON.stringify({ - show: 'title', - tempid: 1, - tbname: 'news', - keyboard: searchTerm, - }), - }); - const body = yield result.text(); - const loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('li.novel-item').each(function () { - const novelName = loadedCheerio(this).find('h4').text(); - const novelUrl = exports.site + loadedCheerio(this).find('a').attr('href'); - const coverUri = exports.site + loadedCheerio(this).find('img').attr('data-src'); - const novelCover = exports.site + coverUri; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - }); - return novels; -}); -exports.searchNovels = searchNovels; -exports.fetchImage = fetch_1.fetchFile; -exports.filters = [{ "key": "sort", "label": "Sort By", "values": [{ "label": "New", "value": "newstime" }, { "label": "Popular", "value": "onclick" }, { "label": "Updates", "value": "lastdotime" }], "inputType": filterInputs_1.FilterInputs.Picker }, { "key": "status", "label": "Status", "values": [{ "label": "All", "value": "all" }, { "label": "Completed", "value": "Completed" }, { "label": "Ongoing", "value": "Ongoing" }], "inputType": filterInputs_1.FilterInputs.Picker }, { "key": "genres", "label": "Genre / Category", "values": [{ "label": "All", "value": "all" }, { "label": "Action", "value": "action" }, { "label": "Adventure", "value": "adventure" }, { "label": "Chinese", "value": "chinese" }, { "label": "Comedy", "value": "comedy" }, { "label": "Contemporary Romance", "value": "contemporary-romance" }, { "label": "Drama", "value": "drama" }, { "label": "Eastern Fantasy", "value": "eastern-fantasy" }, { "label": "Ecchi", "value": "ecchi" }, { "label": "Erciyuan", "value": "erciyuan" }, { "label": "Faloo", "value": "faloo" }, { "label": "Fan-Fiction", "value": "fan-fiction" }, { "label": "Fantasy", "value": "fantasy" }, { "label": "Fantasy Romance", "value": "fantasy-romance" }, { "label": "Game", "value": "game" }, { "label": "Gender Bender", "value": "gender-bender" }, { "label": "Harem", "value": "harem" }, { "label": "Hentai", "value": "hentai" }, { "label": "Historical", "value": "historical" }, { "label": "Horror", "value": "horror" }, { "label": "Isekai", "value": "isekai" }, { "label": "Japanese", "value": "japanese" }, { "label": "Josei", "value": "josei" }, { "label": "Korean", "value": "korean" }, { "label": "Lolicon", "value": "lolicon" }, { "label": "Magic", "value": "magic" }, { "label": "Magical Realism", "value": "magical-realism" }, { "label": "Martial Arts", "value": "martial-arts" }, { "label": "Mecha", "value": "mecha" }, { "label": "Military", "value": "military" }, { "label": "Mystery", "value": "mystery" }, { "label": "Official Circles", "value": "official_circles" }, { "label": "Psychological", "value": "psychological" }, { "label": "Romance", "value": "romance" }, { "label": "School Life", "value": "school-life" }, { "label": "Sci-fi", "value": "sci-fi" }, { "label": "Science Fiction", "value": "science_fiction" }, { "label": "Seinen", "value": "seinen" }, { "label": "Shoujo", "value": "shoujo" }, { "label": "Shoujo Ai", "value": "shoujo-ai" }, { "label": "Shounen", "value": "shounen" }, { "label": "Shounen Ai", "value": "shounen-ai" }, { "label": "Slice of Life", "value": "slice-of-life" }, { "label": "Sports", "value": "sports" }, { "label": "Supernatural", "value": "supernatural" }, { "label": "Suspense Thriller", "value": "suspense_thriller" }, { "label": "Tragedy", "value": "tragedy" }, { "label": "Travel Through Time", "value": "travel_through_time" }, { "label": "Two-dimensional", "value": "two-dimensional" }, { "label": "Urban", "value": "urban" }, { "label": "Urban Life", "value": "urban-life" }, { "label": "Video Games", "value": "video-games" }, { "label": "Virtual Reality", "value": "virtual-reality" }, { "label": "Wuxia", "value": "wuxia" }, { "label": "Wuxia Xianxia", "value": "wuxia_xianxia" }, { "label": "Xianxia", "value": "xianxia" }, { "label": "Xuanhuan", "value": "xuanhuan" }, { "label": "Yaoi", "value": "yaoi" }, { "label": "Yuri", "value": "yuri" }], "inputType": filterInputs_1.FilterInputs.Picker }]; diff --git a/js/plugins/english/SleepyTranslations[madara].js b/js/plugins/english/SleepyTranslations[madara].js deleted file mode 100644 index 78a0a1f..0000000 --- a/js/plugins/english/SleepyTranslations[madara].js +++ /dev/null @@ -1,179 +0,0 @@ -"use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.filters = exports.fetchImage = exports.searchNovels = exports.parseChapter = exports.parseNovelAndChapters = exports.popularNovels = exports.site = exports.version = exports.icon = exports.name = exports.id = void 0; -const cheerio_1 = require("cheerio"); -const fetch_1 = require("@libs/fetch"); -const filterInputs_1 = require("@libs/filterInputs"); -const defaultCover_1 = require("@libs/defaultCover"); -const novelStatus_1 = require("@libs/novelStatus"); -const parseMadaraDate_1 = require("@libs/parseMadaraDate"); -const dayjs_1 = __importDefault(require("dayjs")); -exports.id = "sleeptTLS"; -exports.name = "SleepyTranslations [madara]"; -exports.icon = "multisrc/madara/icons/sleepytranslations.png"; -exports.version = "1.0.0"; -exports.site = "https://sleepytranslations.com/"; -const baseUrl = exports.site; -const popularNovels = (pageNo, { filters, showLatestNovels }) => __awaiter(void 0, void 0, void 0, function* () { - const novels = []; - let url = exports.site; - if (filters === null || filters === void 0 ? void 0 : filters.genres) { - url += "novel-genre/" + filters.genres + '/'; - } - else { - url += "series/"; - } - url += '/page/' + pageNo + '/' + - '?m_orderby=' + (showLatestNovels ? 'latest' : ((filters === null || filters === void 0 ? void 0 : filters.sort) || 'rating')); - const body = yield (0, fetch_1.fetchApi)(url).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.manga-title-badges').remove(); - loadedCheerio('.page-item-detail').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - let novelUrl = loadedCheerio(this).find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - }); - return novels; -}); -exports.popularNovels = popularNovels; -const parseNovelAndChapters = (novelUrl) => __awaiter(void 0, void 0, void 0, function* () { - const novel = { - url: novelUrl, - }; - const body = yield (0, fetch_1.fetchApi)(novelUrl).then(res => res.text()); - let loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.manga-title-badges').remove(); - novel.name = loadedCheerio('.post-title h1').text().trim(); - novel.cover = - loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || - loadedCheerio('.summary_image > a > img').attr('data-src') || - loadedCheerio('.summary_image > a > img').attr('src') || - defaultCover_1.defaultCover; - loadedCheerio('.post-content_item, .post-content').each(function () { - const detailName = loadedCheerio(this).find('h5').text().trim(); - const detail = loadedCheerio(this).find('.summary-content').text().trim(); - switch (detailName) { - case 'Genre(s)': - case 'التصنيفات': - novel.genres = detail.replace(/[\t\n]/g, ','); - break; - case 'Author(s)': - case 'المؤلف': - case 'المؤلف (ين)': - novel.author = detail; - break; - case 'Status': - case 'الحالة': - novel.status = - detail.includes('OnGoing') || detail.includes('مستمرة') - ? novelStatus_1.NovelStatus.Ongoing - : novelStatus_1.NovelStatus.Completed; - break; - } - }); - loadedCheerio('div.summary__content .code-block,script').remove(); - novel.summary = loadedCheerio('div.summary__content').text().trim(); - let html; - if (true) { - const novelId = loadedCheerio('.rating-post-id').attr('value') || - loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; - const body = { - action: "manga_get_chapters", - manga: novelId, - }; - html = yield (0, fetch_1.fetchApi)(baseUrl + 'wp-admin/admin-ajax.php', { - method: 'POST', - body: JSON.stringify(body), - }) - .then(res => res.text()); - } - else { - html = yield (0, fetch_1.fetchApi)(baseUrl + 'ajax/chapters/', { method: 'POST' }) - .then(res => res.text()); - } - if (html !== '0') { - loadedCheerio = (0, cheerio_1.load)(html); - } - const chapters = []; - loadedCheerio('.wp-manga-chapter').each(function () { - const chapterName = loadedCheerio(this).find('a').text().trim(); - let releaseDate = null; - releaseDate = loadedCheerio(this) - .find('span.chapter-release-date') - .text() - .trim(); - if (releaseDate) { - releaseDate = (0, parseMadaraDate_1.parseMadaraDate)(releaseDate); - } - else { - /** - * Insert current date - */ - releaseDate = (0, dayjs_1.default)().format('LL'); - } - let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; - chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); - }); - novel.chapters = chapters.reverse(); - return novel; -}); -exports.parseNovelAndChapters = parseNovelAndChapters; -const parseChapter = (chapterUrl) => __awaiter(void 0, void 0, void 0, function* () { - const url = baseUrl + "/" + "series" + "/" + chapterUrl; - const body = yield (0, fetch_1.fetchApi)(chapterUrl).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - const chapterText = loadedCheerio('.text-left').html() || - loadedCheerio('.text-right').html() || - loadedCheerio('.entry-content').html(); - return chapterText; -}); -exports.parseChapter = parseChapter; -const searchNovels = (searchTerm) => __awaiter(void 0, void 0, void 0, function* () { - const novels = []; - const url = baseUrl + "?s=" + searchTerm + "&post_type=wp-manga"; - const body = yield (0, fetch_1.fetchApi)(url).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.c-tabs-item__content').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - let novelUrl = loadedCheerio(this) - .find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - }); - return novels; -}); -exports.searchNovels = searchNovels; -const fetchImage = (url) => __awaiter(void 0, void 0, void 0, function* () { - return yield (0, fetch_1.fetchFile)(url); -}); -exports.fetchImage = fetchImage; -exports.filters = [{ "key": "sort", "label": "Order by", "values": [{ "label": "Rating", "value": "rating" }, { "label": "A-Z", "value": "alphabet" }, { "label": "Latest", "value": "latest" }, { "label": "Most Views", "value": "views" }, { "label": "New", "value": "new-manga" }, { "label": "Trending", "value": "trending" }], "inputType": filterInputs_1.FilterInputs.Picker }]; diff --git a/js/plugins/english/SonicMTL[madara].js b/js/plugins/english/SonicMTL[madara].js deleted file mode 100644 index 62718ae..0000000 --- a/js/plugins/english/SonicMTL[madara].js +++ /dev/null @@ -1,179 +0,0 @@ -"use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.filters = exports.fetchImage = exports.searchNovels = exports.parseChapter = exports.parseNovelAndChapters = exports.popularNovels = exports.site = exports.version = exports.icon = exports.name = exports.id = void 0; -const cheerio_1 = require("cheerio"); -const fetch_1 = require("@libs/fetch"); -const filterInputs_1 = require("@libs/filterInputs"); -const defaultCover_1 = require("@libs/defaultCover"); -const novelStatus_1 = require("@libs/novelStatus"); -const parseMadaraDate_1 = require("@libs/parseMadaraDate"); -const dayjs_1 = __importDefault(require("dayjs")); -exports.id = "sonicmtl"; -exports.name = "SonicMTL [madara]"; -exports.icon = "multisrc/madara/icons/sonicmtl.png"; -exports.version = "1.0.0"; -exports.site = "https://www.sonicmtl.com/"; -const baseUrl = exports.site; -const popularNovels = (pageNo, { filters, showLatestNovels }) => __awaiter(void 0, void 0, void 0, function* () { - const novels = []; - let url = exports.site; - if (filters === null || filters === void 0 ? void 0 : filters.genres) { - url += "novel-genre/" + filters.genres + '/'; - } - else { - url += "novel/"; - } - url += '/page/' + pageNo + '/' + - '?m_orderby=' + (showLatestNovels ? 'latest' : ((filters === null || filters === void 0 ? void 0 : filters.sort) || 'rating')); - const body = yield (0, fetch_1.fetchApi)(url).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.manga-title-badges').remove(); - loadedCheerio('.page-item-detail').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - let novelUrl = loadedCheerio(this).find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - }); - return novels; -}); -exports.popularNovels = popularNovels; -const parseNovelAndChapters = (novelUrl) => __awaiter(void 0, void 0, void 0, function* () { - const novel = { - url: novelUrl, - }; - const body = yield (0, fetch_1.fetchApi)(novelUrl).then(res => res.text()); - let loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.manga-title-badges').remove(); - novel.name = loadedCheerio('.post-title h1').text().trim(); - novel.cover = - loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || - loadedCheerio('.summary_image > a > img').attr('data-src') || - loadedCheerio('.summary_image > a > img').attr('src') || - defaultCover_1.defaultCover; - loadedCheerio('.post-content_item, .post-content').each(function () { - const detailName = loadedCheerio(this).find('h5').text().trim(); - const detail = loadedCheerio(this).find('.summary-content').text().trim(); - switch (detailName) { - case 'Genre(s)': - case 'التصنيفات': - novel.genres = detail.replace(/[\t\n]/g, ','); - break; - case 'Author(s)': - case 'المؤلف': - case 'المؤلف (ين)': - novel.author = detail; - break; - case 'Status': - case 'الحالة': - novel.status = - detail.includes('OnGoing') || detail.includes('مستمرة') - ? novelStatus_1.NovelStatus.Ongoing - : novelStatus_1.NovelStatus.Completed; - break; - } - }); - loadedCheerio('div.summary__content .code-block,script').remove(); - novel.summary = loadedCheerio('div.summary__content').text().trim(); - let html; - if (true) { - const novelId = loadedCheerio('.rating-post-id').attr('value') || - loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; - const body = { - action: "manga_get_chapters", - manga: novelId, - }; - html = yield (0, fetch_1.fetchApi)(baseUrl + 'wp-admin/admin-ajax.php', { - method: 'POST', - body: JSON.stringify(body), - }) - .then(res => res.text()); - } - else { - html = yield (0, fetch_1.fetchApi)(baseUrl + 'ajax/chapters/', { method: 'POST' }) - .then(res => res.text()); - } - if (html !== '0') { - loadedCheerio = (0, cheerio_1.load)(html); - } - const chapters = []; - loadedCheerio('.wp-manga-chapter').each(function () { - const chapterName = loadedCheerio(this).find('a').text().trim(); - let releaseDate = null; - releaseDate = loadedCheerio(this) - .find('span.chapter-release-date') - .text() - .trim(); - if (releaseDate) { - releaseDate = (0, parseMadaraDate_1.parseMadaraDate)(releaseDate); - } - else { - /** - * Insert current date - */ - releaseDate = (0, dayjs_1.default)().format('LL'); - } - let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; - chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); - }); - novel.chapters = chapters.reverse(); - return novel; -}); -exports.parseNovelAndChapters = parseNovelAndChapters; -const parseChapter = (chapterUrl) => __awaiter(void 0, void 0, void 0, function* () { - const url = baseUrl + "/" + "novel" + "/" + chapterUrl; - const body = yield (0, fetch_1.fetchApi)(chapterUrl).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - const chapterText = loadedCheerio('.text-left').html() || - loadedCheerio('.text-right').html() || - loadedCheerio('.entry-content').html(); - return chapterText; -}); -exports.parseChapter = parseChapter; -const searchNovels = (searchTerm) => __awaiter(void 0, void 0, void 0, function* () { - const novels = []; - const url = baseUrl + "?s=" + searchTerm + "&post_type=wp-manga"; - const body = yield (0, fetch_1.fetchApi)(url).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.c-tabs-item__content').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - let novelUrl = loadedCheerio(this) - .find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - }); - return novels; -}); -exports.searchNovels = searchNovels; -const fetchImage = (url) => __awaiter(void 0, void 0, void 0, function* () { - return yield (0, fetch_1.fetchFile)(url); -}); -exports.fetchImage = fetchImage; -exports.filters = [{ "key": "sort", "label": "Order by", "values": [{ "label": "Rating", "value": "rating" }, { "label": "A-Z", "value": "alphabet" }, { "label": "Latest", "value": "latest" }, { "label": "Most Views", "value": "views" }, { "label": "New", "value": "new-manga" }, { "label": "Trending", "value": "trending" }], "inputType": filterInputs_1.FilterInputs.Picker }, { "key": "genres", "label": "GENRES", "values": [{ "label": "Action", "value": "action" }, { "label": "Adult", "value": "adult" }, { "label": "Adventure", "value": "adventure" }, { "label": "Comedy", "value": "comedy" }, { "label": "Cooking", "value": "cooking" }, { "label": "Detective", "value": "detective" }, { "label": "Doujinshi", "value": "doujinshi" }, { "label": "Drama", "value": "drama" }, { "label": "Ecchi", "value": "ecchi" }, { "label": "Fan-Fiction", "value": "fan-fiction" }, { "label": "Fantasy", "value": "fantasy" }, { "label": "Gender Bender", "value": "gender-bender" }, { "label": "Harem", "value": "harem" }, { "label": "Historical", "value": "historical" }, { "label": "Horror", "value": "horror" }, { "label": "Josei", "value": "josei" }, { "label": "Live action", "value": "live-action" }, { "label": "Manga", "value": "manga" }, { "label": "Manhua", "value": "manhua" }, { "label": "Manhwa", "value": "manhwa" }, { "label": "Martial Arts", "value": "martial-arts" }, { "label": "Mature", "value": "mature" }, { "label": "Mecha", "value": "mecha" }, { "label": "Mystery", "value": "mystery" }, { "label": "One shot", "value": "one-shot" }, { "label": "Psychological", "value": "psychological" }, { "label": "Romance", "value": "romance" }, { "label": "School Life", "value": "school-life" }, { "label": "Sci-fi", "value": "sci-fi" }, { "label": "Seinen", "value": "seinen" }, { "label": "Shoujo", "value": "shoujo" }, { "label": "Shoujo Ai", "value": "shoujo-ai" }, { "label": "Shounen", "value": "shounen" }, { "label": "Shounen Ai", "value": "shounen-ai" }, { "label": "Slice of Life", "value": "slice-of-life" }, { "label": "Smut", "value": "smut" }, { "label": "Soft Yaoi", "value": "soft-yaoi" }, { "label": "Soft Yuri", "value": "soft-yuri" }, { "label": "Sports", "value": "sports" }, { "label": "Supernatural", "value": "supernatural" }, { "label": "Tragedy", "value": "tragedy" }, { "label": "Urban Life", "value": "urban-life" }, { "label": "Wuxia", "value": "wuxia" }, { "label": "Xianxia", "value": "xianxia" }, { "label": "Xuanhuan", "value": "xuanhuan" }, { "label": "Yaoi", "value": "yaoi" }, { "label": "Yuri", "value": "yuri" }], "inputType": filterInputs_1.FilterInputs.Picker }]; diff --git a/js/plugins/english/SugarBabies[madara].js b/js/plugins/english/SugarBabies[madara].js deleted file mode 100644 index 058c420..0000000 --- a/js/plugins/english/SugarBabies[madara].js +++ /dev/null @@ -1,178 +0,0 @@ -"use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.filters = exports.fetchImage = exports.searchNovels = exports.parseChapter = exports.parseNovelAndChapters = exports.popularNovels = exports.site = exports.version = exports.icon = exports.name = exports.id = void 0; -const cheerio_1 = require("cheerio"); -const fetch_1 = require("@libs/fetch"); -const defaultCover_1 = require("@libs/defaultCover"); -const novelStatus_1 = require("@libs/novelStatus"); -const parseMadaraDate_1 = require("@libs/parseMadaraDate"); -const dayjs_1 = __importDefault(require("dayjs")); -exports.id = "sugarbbscan"; -exports.name = "Sugar Babies [madara]"; -exports.icon = "multisrc/madara/icons/sugarbabies.png"; -exports.version = "1.0.0"; -exports.site = "https://sugarbbscan.com/"; -const baseUrl = exports.site; -const popularNovels = (pageNo, { filters, showLatestNovels }) => __awaiter(void 0, void 0, void 0, function* () { - const novels = []; - let url = exports.site; - if (filters === null || filters === void 0 ? void 0 : filters.genres) { - url += "novel-genre/" + filters.genres + '/'; - } - else { - url += "series/"; - } - url += '/page/' + pageNo + '/' + - '?m_orderby=' + (showLatestNovels ? 'latest' : ((filters === null || filters === void 0 ? void 0 : filters.sort) || 'rating')); - const body = yield (0, fetch_1.fetchApi)(url).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.manga-title-badges').remove(); - loadedCheerio('.page-item-detail').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - let novelUrl = loadedCheerio(this).find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - }); - return novels; -}); -exports.popularNovels = popularNovels; -const parseNovelAndChapters = (novelUrl) => __awaiter(void 0, void 0, void 0, function* () { - const novel = { - url: novelUrl, - }; - const body = yield (0, fetch_1.fetchApi)(novelUrl).then(res => res.text()); - let loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.manga-title-badges').remove(); - novel.name = loadedCheerio('.post-title h1').text().trim(); - novel.cover = - loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || - loadedCheerio('.summary_image > a > img').attr('data-src') || - loadedCheerio('.summary_image > a > img').attr('src') || - defaultCover_1.defaultCover; - loadedCheerio('.post-content_item, .post-content').each(function () { - const detailName = loadedCheerio(this).find('h5').text().trim(); - const detail = loadedCheerio(this).find('.summary-content').text().trim(); - switch (detailName) { - case 'Genre(s)': - case 'التصنيفات': - novel.genres = detail.replace(/[\t\n]/g, ','); - break; - case 'Author(s)': - case 'المؤلف': - case 'المؤلف (ين)': - novel.author = detail; - break; - case 'Status': - case 'الحالة': - novel.status = - detail.includes('OnGoing') || detail.includes('مستمرة') - ? novelStatus_1.NovelStatus.Ongoing - : novelStatus_1.NovelStatus.Completed; - break; - } - }); - loadedCheerio('div.summary__content .code-block,script').remove(); - novel.summary = loadedCheerio('div.summary__content').text().trim(); - let html; - if (false) { - const novelId = loadedCheerio('.rating-post-id').attr('value') || - loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; - const body = { - action: "manga_get_chapters", - manga: novelId, - }; - html = yield (0, fetch_1.fetchApi)(baseUrl + 'wp-admin/admin-ajax.php', { - method: 'POST', - body: JSON.stringify(body), - }) - .then(res => res.text()); - } - else { - html = yield (0, fetch_1.fetchApi)(baseUrl + 'ajax/chapters/', { method: 'POST' }) - .then(res => res.text()); - } - if (html !== '0') { - loadedCheerio = (0, cheerio_1.load)(html); - } - const chapters = []; - loadedCheerio('.wp-manga-chapter').each(function () { - const chapterName = loadedCheerio(this).find('a').text().trim(); - let releaseDate = null; - releaseDate = loadedCheerio(this) - .find('span.chapter-release-date') - .text() - .trim(); - if (releaseDate) { - releaseDate = (0, parseMadaraDate_1.parseMadaraDate)(releaseDate); - } - else { - /** - * Insert current date - */ - releaseDate = (0, dayjs_1.default)().format('LL'); - } - let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; - chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); - }); - novel.chapters = chapters.reverse(); - return novel; -}); -exports.parseNovelAndChapters = parseNovelAndChapters; -const parseChapter = (chapterUrl) => __awaiter(void 0, void 0, void 0, function* () { - const url = baseUrl + "/" + "series" + "/" + chapterUrl; - const body = yield (0, fetch_1.fetchApi)(chapterUrl).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - const chapterText = loadedCheerio('.text-left').html() || - loadedCheerio('.text-right').html() || - loadedCheerio('.entry-content').html(); - return chapterText; -}); -exports.parseChapter = parseChapter; -const searchNovels = (searchTerm) => __awaiter(void 0, void 0, void 0, function* () { - const novels = []; - const url = baseUrl + "?s=" + searchTerm + "&post_type=wp-manga"; - const body = yield (0, fetch_1.fetchApi)(url).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.c-tabs-item__content').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - let novelUrl = loadedCheerio(this) - .find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - }); - return novels; -}); -exports.searchNovels = searchNovels; -const fetchImage = (url) => __awaiter(void 0, void 0, void 0, function* () { - return yield (0, fetch_1.fetchFile)(url); -}); -exports.fetchImage = fetchImage; -exports.filters = []; diff --git a/js/plugins/english/SweetEscapeTranslations[madara].js b/js/plugins/english/SweetEscapeTranslations[madara].js deleted file mode 100644 index 8feed1b..0000000 --- a/js/plugins/english/SweetEscapeTranslations[madara].js +++ /dev/null @@ -1,179 +0,0 @@ -"use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.filters = exports.fetchImage = exports.searchNovels = exports.parseChapter = exports.parseNovelAndChapters = exports.popularNovels = exports.site = exports.version = exports.icon = exports.name = exports.id = void 0; -const cheerio_1 = require("cheerio"); -const fetch_1 = require("@libs/fetch"); -const filterInputs_1 = require("@libs/filterInputs"); -const defaultCover_1 = require("@libs/defaultCover"); -const novelStatus_1 = require("@libs/novelStatus"); -const parseMadaraDate_1 = require("@libs/parseMadaraDate"); -const dayjs_1 = __importDefault(require("dayjs")); -exports.id = "sweetEscapeTL"; -exports.name = "Sweet Escape Translations [madara]"; -exports.icon = "multisrc/madara/icons/sweetescapetranslations.png"; -exports.version = "1.0.0"; -exports.site = "https://sweetescapetranslations.com/"; -const baseUrl = exports.site; -const popularNovels = (pageNo, { filters, showLatestNovels }) => __awaiter(void 0, void 0, void 0, function* () { - const novels = []; - let url = exports.site; - if (filters === null || filters === void 0 ? void 0 : filters.genres) { - url += "manga-genre/" + filters.genres + '/'; - } - else { - url += "manga/"; - } - url += '/page/' + pageNo + '/' + - '?m_orderby=' + (showLatestNovels ? 'latest' : ((filters === null || filters === void 0 ? void 0 : filters.sort) || 'rating')); - const body = yield (0, fetch_1.fetchApi)(url).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.manga-title-badges').remove(); - loadedCheerio('.page-item-detail').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - let novelUrl = loadedCheerio(this).find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - }); - return novels; -}); -exports.popularNovels = popularNovels; -const parseNovelAndChapters = (novelUrl) => __awaiter(void 0, void 0, void 0, function* () { - const novel = { - url: novelUrl, - }; - const body = yield (0, fetch_1.fetchApi)(novelUrl).then(res => res.text()); - let loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.manga-title-badges').remove(); - novel.name = loadedCheerio('.post-title h1').text().trim(); - novel.cover = - loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || - loadedCheerio('.summary_image > a > img').attr('data-src') || - loadedCheerio('.summary_image > a > img').attr('src') || - defaultCover_1.defaultCover; - loadedCheerio('.post-content_item, .post-content').each(function () { - const detailName = loadedCheerio(this).find('h5').text().trim(); - const detail = loadedCheerio(this).find('.summary-content').text().trim(); - switch (detailName) { - case 'Genre(s)': - case 'التصنيفات': - novel.genres = detail.replace(/[\t\n]/g, ','); - break; - case 'Author(s)': - case 'المؤلف': - case 'المؤلف (ين)': - novel.author = detail; - break; - case 'Status': - case 'الحالة': - novel.status = - detail.includes('OnGoing') || detail.includes('مستمرة') - ? novelStatus_1.NovelStatus.Ongoing - : novelStatus_1.NovelStatus.Completed; - break; - } - }); - loadedCheerio('div.summary__content .code-block,script').remove(); - novel.summary = loadedCheerio('div.summary__content').text().trim(); - let html; - if (false) { - const novelId = loadedCheerio('.rating-post-id').attr('value') || - loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; - const body = { - action: "manga_get_chapters", - manga: novelId, - }; - html = yield (0, fetch_1.fetchApi)(baseUrl + 'wp-admin/admin-ajax.php', { - method: 'POST', - body: JSON.stringify(body), - }) - .then(res => res.text()); - } - else { - html = yield (0, fetch_1.fetchApi)(baseUrl + 'ajax/chapters/', { method: 'POST' }) - .then(res => res.text()); - } - if (html !== '0') { - loadedCheerio = (0, cheerio_1.load)(html); - } - const chapters = []; - loadedCheerio('.wp-manga-chapter').each(function () { - const chapterName = loadedCheerio(this).find('a').text().trim(); - let releaseDate = null; - releaseDate = loadedCheerio(this) - .find('span.chapter-release-date') - .text() - .trim(); - if (releaseDate) { - releaseDate = (0, parseMadaraDate_1.parseMadaraDate)(releaseDate); - } - else { - /** - * Insert current date - */ - releaseDate = (0, dayjs_1.default)().format('LL'); - } - let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; - chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); - }); - novel.chapters = chapters.reverse(); - return novel; -}); -exports.parseNovelAndChapters = parseNovelAndChapters; -const parseChapter = (chapterUrl) => __awaiter(void 0, void 0, void 0, function* () { - const url = baseUrl + "/" + "manga" + "/" + chapterUrl; - const body = yield (0, fetch_1.fetchApi)(chapterUrl).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - const chapterText = loadedCheerio('.text-left').html() || - loadedCheerio('.text-right').html() || - loadedCheerio('.entry-content').html(); - return chapterText; -}); -exports.parseChapter = parseChapter; -const searchNovels = (searchTerm) => __awaiter(void 0, void 0, void 0, function* () { - const novels = []; - const url = baseUrl + "?s=" + searchTerm + "&post_type=wp-manga"; - const body = yield (0, fetch_1.fetchApi)(url).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.c-tabs-item__content').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - let novelUrl = loadedCheerio(this) - .find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - }); - return novels; -}); -exports.searchNovels = searchNovels; -const fetchImage = (url) => __awaiter(void 0, void 0, void 0, function* () { - return yield (0, fetch_1.fetchFile)(url); -}); -exports.fetchImage = fetchImage; -exports.filters = [{ "key": "sort", "label": "Order by", "values": [{ "label": "Rating", "value": "rating" }, { "label": "A-Z", "value": "alphabet" }, { "label": "Latest", "value": "latest" }, { "label": "Most Views", "value": "views" }, { "label": "New", "value": "new-manga" }, { "label": "Trending", "value": "trending" }], "inputType": filterInputs_1.FilterInputs.Picker }, { "key": "genres", "label": "GENRES", "values": [{ "label": "Action", "value": "action" }, { "label": "Adult", "value": "adult" }, { "label": "Comedy", "value": "comedy" }, { "label": "Drama", "value": "drama" }, { "label": "Fantasy", "value": "fantasy" }, { "label": "Gender Bender", "value": "gender-bender" }, { "label": "Mature", "value": "mature" }, { "label": "Modern", "value": "modern" }, { "label": "Mystery", "value": "mystery" }, { "label": "R-15", "value": "r-15" }, { "label": "Romance", "value": "romance" }, { "label": "Slice of Life", "value": "slice-of-life" }], "inputType": filterInputs_1.FilterInputs.Picker }]; diff --git a/js/plugins/english/WebNovelLover[madara].js b/js/plugins/english/WebNovelLover[madara].js deleted file mode 100644 index 0daf7f7..0000000 --- a/js/plugins/english/WebNovelLover[madara].js +++ /dev/null @@ -1,179 +0,0 @@ -"use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.filters = exports.fetchImage = exports.searchNovels = exports.parseChapter = exports.parseNovelAndChapters = exports.popularNovels = exports.site = exports.version = exports.icon = exports.name = exports.id = void 0; -const cheerio_1 = require("cheerio"); -const fetch_1 = require("@libs/fetch"); -const filterInputs_1 = require("@libs/filterInputs"); -const defaultCover_1 = require("@libs/defaultCover"); -const novelStatus_1 = require("@libs/novelStatus"); -const parseMadaraDate_1 = require("@libs/parseMadaraDate"); -const dayjs_1 = __importDefault(require("dayjs")); -exports.id = "webnovelover"; -exports.name = "WebNovelLover [madara]"; -exports.icon = "multisrc/madara/icons/webnovellover.png"; -exports.version = "1.0.0"; -exports.site = "https://www.webnovelover.com/"; -const baseUrl = exports.site; -const popularNovels = (pageNo, { filters, showLatestNovels }) => __awaiter(void 0, void 0, void 0, function* () { - const novels = []; - let url = exports.site; - if (filters === null || filters === void 0 ? void 0 : filters.genres) { - url += "novel-genre/" + filters.genres + '/'; - } - else { - url += "novel/"; - } - url += '/page/' + pageNo + '/' + - '?m_orderby=' + (showLatestNovels ? 'latest' : ((filters === null || filters === void 0 ? void 0 : filters.sort) || 'rating')); - const body = yield (0, fetch_1.fetchApi)(url).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.manga-title-badges').remove(); - loadedCheerio('.page-item-detail').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - let novelUrl = loadedCheerio(this).find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - }); - return novels; -}); -exports.popularNovels = popularNovels; -const parseNovelAndChapters = (novelUrl) => __awaiter(void 0, void 0, void 0, function* () { - const novel = { - url: novelUrl, - }; - const body = yield (0, fetch_1.fetchApi)(novelUrl).then(res => res.text()); - let loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.manga-title-badges').remove(); - novel.name = loadedCheerio('.post-title h1').text().trim(); - novel.cover = - loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || - loadedCheerio('.summary_image > a > img').attr('data-src') || - loadedCheerio('.summary_image > a > img').attr('src') || - defaultCover_1.defaultCover; - loadedCheerio('.post-content_item, .post-content').each(function () { - const detailName = loadedCheerio(this).find('h5').text().trim(); - const detail = loadedCheerio(this).find('.summary-content').text().trim(); - switch (detailName) { - case 'Genre(s)': - case 'التصنيفات': - novel.genres = detail.replace(/[\t\n]/g, ','); - break; - case 'Author(s)': - case 'المؤلف': - case 'المؤلف (ين)': - novel.author = detail; - break; - case 'Status': - case 'الحالة': - novel.status = - detail.includes('OnGoing') || detail.includes('مستمرة') - ? novelStatus_1.NovelStatus.Ongoing - : novelStatus_1.NovelStatus.Completed; - break; - } - }); - loadedCheerio('div.summary__content .code-block,script').remove(); - novel.summary = loadedCheerio('div.summary__content').text().trim(); - let html; - if (false) { - const novelId = loadedCheerio('.rating-post-id').attr('value') || - loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; - const body = { - action: "manga_get_chapters", - manga: novelId, - }; - html = yield (0, fetch_1.fetchApi)(baseUrl + 'wp-admin/admin-ajax.php', { - method: 'POST', - body: JSON.stringify(body), - }) - .then(res => res.text()); - } - else { - html = yield (0, fetch_1.fetchApi)(baseUrl + 'ajax/chapters/', { method: 'POST' }) - .then(res => res.text()); - } - if (html !== '0') { - loadedCheerio = (0, cheerio_1.load)(html); - } - const chapters = []; - loadedCheerio('.wp-manga-chapter').each(function () { - const chapterName = loadedCheerio(this).find('a').text().trim(); - let releaseDate = null; - releaseDate = loadedCheerio(this) - .find('span.chapter-release-date') - .text() - .trim(); - if (releaseDate) { - releaseDate = (0, parseMadaraDate_1.parseMadaraDate)(releaseDate); - } - else { - /** - * Insert current date - */ - releaseDate = (0, dayjs_1.default)().format('LL'); - } - let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; - chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); - }); - novel.chapters = chapters.reverse(); - return novel; -}); -exports.parseNovelAndChapters = parseNovelAndChapters; -const parseChapter = (chapterUrl) => __awaiter(void 0, void 0, void 0, function* () { - const url = baseUrl + "/" + "novel" + "/" + chapterUrl; - const body = yield (0, fetch_1.fetchApi)(chapterUrl).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - const chapterText = loadedCheerio('.text-left').html() || - loadedCheerio('.text-right').html() || - loadedCheerio('.entry-content').html(); - return chapterText; -}); -exports.parseChapter = parseChapter; -const searchNovels = (searchTerm) => __awaiter(void 0, void 0, void 0, function* () { - const novels = []; - const url = baseUrl + "?s=" + searchTerm + "&post_type=wp-manga"; - const body = yield (0, fetch_1.fetchApi)(url).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.c-tabs-item__content').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - let novelUrl = loadedCheerio(this) - .find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - }); - return novels; -}); -exports.searchNovels = searchNovels; -const fetchImage = (url) => __awaiter(void 0, void 0, void 0, function* () { - return yield (0, fetch_1.fetchFile)(url); -}); -exports.fetchImage = fetchImage; -exports.filters = [{ "key": "sort", "label": "Order by", "values": [{ "label": "Rating", "value": "rating" }, { "label": "A-Z", "value": "alphabet" }, { "label": "Latest", "value": "latest" }, { "label": "Most Views", "value": "views" }, { "label": "New", "value": "new-manga" }, { "label": "Trending", "value": "trending" }], "inputType": filterInputs_1.FilterInputs.Picker }, { "key": "genres", "label": "GENRES", "values": [{ "label": "Action", "value": "action" }, { "label": "Adapted into drama", "value": "adapted-into-drama" }, { "label": "Adventure", "value": "adventure" }, { "label": "Comedy", "value": "comedy" }, { "label": "Completed", "value": "completed" }, { "label": "Drama", "value": "drama" }, { "label": "English Novel", "value": "english-novel" }, { "label": "Fantasy", "value": "fantasy" }, { "label": "Gender Bender", "value": "gender-bender" }, { "label": "Harem", "value": "harem" }, { "label": "Historical", "value": "historical" }, { "label": "Horror", "value": "horror" }, { "label": "Indo Novel", "value": "indo-novel" }, { "label": "Josei", "value": "josei" }, { "label": "Martial Arts", "value": "martial-arts" }, { "label": "Mature", "value": "mature" }, { "label": "Mystery", "value": "mystery" }, { "label": "Rebirth", "value": "rebirth" }, { "label": "Reincarnation", "value": "reincarnation" }, { "label": "Romance", "value": "romance" }, { "label": "Sci-fi", "value": "sci-fi" }, { "label": "Shoujo", "value": "shoujo" }, { "label": "Shounen", "value": "shounen" }, { "label": "Slice of Life", "value": "slice-of-life" }, { "label": "Spiritual", "value": "spiritual" }, { "label": "Supernatural", "value": "supernatural" }, { "label": "Tragedy", "value": "tragedy" }, { "label": "Transmigration", "value": "transmigration" }, { "label": "University", "value": "university" }, { "label": "Wuxia", "value": "wuxia" }, { "label": "Xianxia", "value": "xianxia" }, { "label": "Xuanhuan", "value": "xuanhuan" }, { "label": "Youth", "value": "youth" }], "inputType": filterInputs_1.FilterInputs.Picker }]; diff --git a/js/plugins/english/WuxiaWorldSite[madara].js b/js/plugins/english/WuxiaWorldSite[madara].js deleted file mode 100644 index bb8b570..0000000 --- a/js/plugins/english/WuxiaWorldSite[madara].js +++ /dev/null @@ -1,179 +0,0 @@ -"use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.filters = exports.fetchImage = exports.searchNovels = exports.parseChapter = exports.parseNovelAndChapters = exports.popularNovels = exports.site = exports.version = exports.icon = exports.name = exports.id = void 0; -const cheerio_1 = require("cheerio"); -const fetch_1 = require("@libs/fetch"); -const filterInputs_1 = require("@libs/filterInputs"); -const defaultCover_1 = require("@libs/defaultCover"); -const novelStatus_1 = require("@libs/novelStatus"); -const parseMadaraDate_1 = require("@libs/parseMadaraDate"); -const dayjs_1 = __importDefault(require("dayjs")); -exports.id = "wuxiaworld.site"; -exports.name = "WuxiaWorld.Site [madara]"; -exports.icon = "multisrc/madara/icons/wuxiaworld.site.png"; -exports.version = "1.0.0"; -exports.site = "https://wuxiaworld.site/"; -const baseUrl = exports.site; -const popularNovels = (pageNo, { filters, showLatestNovels }) => __awaiter(void 0, void 0, void 0, function* () { - const novels = []; - let url = exports.site; - if (filters === null || filters === void 0 ? void 0 : filters.genres) { - url += "novel-genre/" + filters.genres + '/'; - } - else { - url += "novel/"; - } - url += '/page/' + pageNo + '/' + - '?m_orderby=' + (showLatestNovels ? 'latest' : ((filters === null || filters === void 0 ? void 0 : filters.sort) || 'rating')); - const body = yield (0, fetch_1.fetchApi)(url).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.manga-title-badges').remove(); - loadedCheerio('.page-item-detail').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - let novelUrl = loadedCheerio(this).find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - }); - return novels; -}); -exports.popularNovels = popularNovels; -const parseNovelAndChapters = (novelUrl) => __awaiter(void 0, void 0, void 0, function* () { - const novel = { - url: novelUrl, - }; - const body = yield (0, fetch_1.fetchApi)(novelUrl).then(res => res.text()); - let loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.manga-title-badges').remove(); - novel.name = loadedCheerio('.post-title h1').text().trim(); - novel.cover = - loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || - loadedCheerio('.summary_image > a > img').attr('data-src') || - loadedCheerio('.summary_image > a > img').attr('src') || - defaultCover_1.defaultCover; - loadedCheerio('.post-content_item, .post-content').each(function () { - const detailName = loadedCheerio(this).find('h5').text().trim(); - const detail = loadedCheerio(this).find('.summary-content').text().trim(); - switch (detailName) { - case 'Genre(s)': - case 'التصنيفات': - novel.genres = detail.replace(/[\t\n]/g, ','); - break; - case 'Author(s)': - case 'المؤلف': - case 'المؤلف (ين)': - novel.author = detail; - break; - case 'Status': - case 'الحالة': - novel.status = - detail.includes('OnGoing') || detail.includes('مستمرة') - ? novelStatus_1.NovelStatus.Ongoing - : novelStatus_1.NovelStatus.Completed; - break; - } - }); - loadedCheerio('div.summary__content .code-block,script').remove(); - novel.summary = loadedCheerio('div.summary__content').text().trim(); - let html; - if (true) { - const novelId = loadedCheerio('.rating-post-id').attr('value') || - loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; - const body = { - action: "manga_get_chapters", - manga: novelId, - }; - html = yield (0, fetch_1.fetchApi)(baseUrl + 'wp-admin/admin-ajax.php', { - method: 'POST', - body: JSON.stringify(body), - }) - .then(res => res.text()); - } - else { - html = yield (0, fetch_1.fetchApi)(baseUrl + 'ajax/chapters/', { method: 'POST' }) - .then(res => res.text()); - } - if (html !== '0') { - loadedCheerio = (0, cheerio_1.load)(html); - } - const chapters = []; - loadedCheerio('.wp-manga-chapter').each(function () { - const chapterName = loadedCheerio(this).find('a').text().trim(); - let releaseDate = null; - releaseDate = loadedCheerio(this) - .find('span.chapter-release-date') - .text() - .trim(); - if (releaseDate) { - releaseDate = (0, parseMadaraDate_1.parseMadaraDate)(releaseDate); - } - else { - /** - * Insert current date - */ - releaseDate = (0, dayjs_1.default)().format('LL'); - } - let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; - chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); - }); - novel.chapters = chapters.reverse(); - return novel; -}); -exports.parseNovelAndChapters = parseNovelAndChapters; -const parseChapter = (chapterUrl) => __awaiter(void 0, void 0, void 0, function* () { - const url = baseUrl + "/" + "novel" + "/" + chapterUrl; - const body = yield (0, fetch_1.fetchApi)(chapterUrl).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - const chapterText = loadedCheerio('.text-left').html() || - loadedCheerio('.text-right').html() || - loadedCheerio('.entry-content').html(); - return chapterText; -}); -exports.parseChapter = parseChapter; -const searchNovels = (searchTerm) => __awaiter(void 0, void 0, void 0, function* () { - const novels = []; - const url = baseUrl + "?s=" + searchTerm + "&post_type=wp-manga"; - const body = yield (0, fetch_1.fetchApi)(url).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.c-tabs-item__content').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - let novelUrl = loadedCheerio(this) - .find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - }); - return novels; -}); -exports.searchNovels = searchNovels; -const fetchImage = (url) => __awaiter(void 0, void 0, void 0, function* () { - return yield (0, fetch_1.fetchFile)(url); -}); -exports.fetchImage = fetchImage; -exports.filters = [{ "key": "sort", "label": "Order by", "values": [{ "label": "Rating", "value": "rating" }, { "label": "A-Z", "value": "alphabet" }, { "label": "Latest", "value": "latest" }, { "label": "Most Views", "value": "views" }, { "label": "New", "value": "new-manga" }, { "label": "Trending", "value": "trending" }], "inputType": filterInputs_1.FilterInputs.Picker }]; diff --git a/js/plugins/english/ZetroTranslation[madara].js b/js/plugins/english/ZetroTranslation[madara].js deleted file mode 100644 index 6a062f6..0000000 --- a/js/plugins/english/ZetroTranslation[madara].js +++ /dev/null @@ -1,179 +0,0 @@ -"use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.filters = exports.fetchImage = exports.searchNovels = exports.parseChapter = exports.parseNovelAndChapters = exports.popularNovels = exports.site = exports.version = exports.icon = exports.name = exports.id = void 0; -const cheerio_1 = require("cheerio"); -const fetch_1 = require("@libs/fetch"); -const filterInputs_1 = require("@libs/filterInputs"); -const defaultCover_1 = require("@libs/defaultCover"); -const novelStatus_1 = require("@libs/novelStatus"); -const parseMadaraDate_1 = require("@libs/parseMadaraDate"); -const dayjs_1 = __importDefault(require("dayjs")); -exports.id = "zetroTL"; -exports.name = "Zetro Translation [madara]"; -exports.icon = "multisrc/madara/icons/zetrotranslation.png"; -exports.version = "1.0.0"; -exports.site = "https://zetrotranslation.com/"; -const baseUrl = exports.site; -const popularNovels = (pageNo, { filters, showLatestNovels }) => __awaiter(void 0, void 0, void 0, function* () { - const novels = []; - let url = exports.site; - if (filters === null || filters === void 0 ? void 0 : filters.genres) { - url += "genre/" + filters.genres + '/'; - } - else { - url += "novel/"; - } - url += '/page/' + pageNo + '/' + - '?m_orderby=' + (showLatestNovels ? 'latest' : ((filters === null || filters === void 0 ? void 0 : filters.sort) || 'rating')); - const body = yield (0, fetch_1.fetchApi)(url).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.manga-title-badges').remove(); - loadedCheerio('.page-item-detail').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - let novelUrl = loadedCheerio(this).find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - }); - return novels; -}); -exports.popularNovels = popularNovels; -const parseNovelAndChapters = (novelUrl) => __awaiter(void 0, void 0, void 0, function* () { - const novel = { - url: novelUrl, - }; - const body = yield (0, fetch_1.fetchApi)(novelUrl).then(res => res.text()); - let loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.manga-title-badges').remove(); - novel.name = loadedCheerio('.post-title h1').text().trim(); - novel.cover = - loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || - loadedCheerio('.summary_image > a > img').attr('data-src') || - loadedCheerio('.summary_image > a > img').attr('src') || - defaultCover_1.defaultCover; - loadedCheerio('.post-content_item, .post-content').each(function () { - const detailName = loadedCheerio(this).find('h5').text().trim(); - const detail = loadedCheerio(this).find('.summary-content').text().trim(); - switch (detailName) { - case 'Genre(s)': - case 'التصنيفات': - novel.genres = detail.replace(/[\t\n]/g, ','); - break; - case 'Author(s)': - case 'المؤلف': - case 'المؤلف (ين)': - novel.author = detail; - break; - case 'Status': - case 'الحالة': - novel.status = - detail.includes('OnGoing') || detail.includes('مستمرة') - ? novelStatus_1.NovelStatus.Ongoing - : novelStatus_1.NovelStatus.Completed; - break; - } - }); - loadedCheerio('div.summary__content .code-block,script').remove(); - novel.summary = loadedCheerio('div.summary__content').text().trim(); - let html; - if (false) { - const novelId = loadedCheerio('.rating-post-id').attr('value') || - loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; - const body = { - action: "manga_get_chapters", - manga: novelId, - }; - html = yield (0, fetch_1.fetchApi)(baseUrl + 'wp-admin/admin-ajax.php', { - method: 'POST', - body: JSON.stringify(body), - }) - .then(res => res.text()); - } - else { - html = yield (0, fetch_1.fetchApi)(baseUrl + 'ajax/chapters/', { method: 'POST' }) - .then(res => res.text()); - } - if (html !== '0') { - loadedCheerio = (0, cheerio_1.load)(html); - } - const chapters = []; - loadedCheerio('.wp-manga-chapter').each(function () { - const chapterName = loadedCheerio(this).find('a').text().trim(); - let releaseDate = null; - releaseDate = loadedCheerio(this) - .find('span.chapter-release-date') - .text() - .trim(); - if (releaseDate) { - releaseDate = (0, parseMadaraDate_1.parseMadaraDate)(releaseDate); - } - else { - /** - * Insert current date - */ - releaseDate = (0, dayjs_1.default)().format('LL'); - } - let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; - chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); - }); - novel.chapters = chapters.reverse(); - return novel; -}); -exports.parseNovelAndChapters = parseNovelAndChapters; -const parseChapter = (chapterUrl) => __awaiter(void 0, void 0, void 0, function* () { - const url = baseUrl + "/" + "novel" + "/" + chapterUrl; - const body = yield (0, fetch_1.fetchApi)(chapterUrl).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - const chapterText = loadedCheerio('.text-left').html() || - loadedCheerio('.text-right').html() || - loadedCheerio('.entry-content').html(); - return chapterText; -}); -exports.parseChapter = parseChapter; -const searchNovels = (searchTerm) => __awaiter(void 0, void 0, void 0, function* () { - const novels = []; - const url = baseUrl + "?s=" + searchTerm + "&post_type=wp-manga"; - const body = yield (0, fetch_1.fetchApi)(url).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.c-tabs-item__content').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - let novelUrl = loadedCheerio(this) - .find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - }); - return novels; -}); -exports.searchNovels = searchNovels; -const fetchImage = (url) => __awaiter(void 0, void 0, void 0, function* () { - return yield (0, fetch_1.fetchFile)(url); -}); -exports.fetchImage = fetchImage; -exports.filters = [{ "key": "sort", "label": "Order by", "values": [{ "label": "Rating", "value": "rating" }, { "label": "A-Z", "value": "alphabet" }, { "label": "Latest", "value": "latest" }, { "label": "Most Views", "value": "views" }, { "label": "New", "value": "new-manga" }, { "label": "Trending", "value": "trending" }], "inputType": filterInputs_1.FilterInputs.Picker }, { "key": "genres", "label": "GENRES", "values": [{ "label": "Action", "value": "action" }, { "label": "Adventure", "value": "adventure" }, { "label": "Comedy", "value": "comedy" }, { "label": "Dark Elf", "value": "dark-elf" }, { "label": "Drama", "value": "drama" }, { "label": "Ecchi", "value": "ecchi" }, { "label": "Fantasy", "value": "fantasy" }, { "label": "Harem", "value": "harem" }, { "label": "Horror", "value": "horror" }, { "label": "Isekai", "value": "isekai" }, { "label": "Mecha", "value": "mecha" }, { "label": "Mystery", "value": "mystery" }, { "label": "NTR", "value": "ntr" }, { "label": "Original Works", "value": "original-works" }, { "label": "Rom-Com", "value": "rom-com" }, { "label": "Romance", "value": "romance" }, { "label": "School", "value": "school" }, { "label": "Shoujo", "value": "shoujo" }, { "label": "Slice of Life", "value": "slice-of-life" }, { "label": "Villain", "value": "villain" }, { "label": "Yuri", "value": "yuri" }], "inputType": filterInputs_1.FilterInputs.Picker }]; diff --git a/js/plugins/english/ZinnNovel[madara].js b/js/plugins/english/ZinnNovel[madara].js deleted file mode 100644 index 312e8df..0000000 --- a/js/plugins/english/ZinnNovel[madara].js +++ /dev/null @@ -1,179 +0,0 @@ -"use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.filters = exports.fetchImage = exports.searchNovels = exports.parseChapter = exports.parseNovelAndChapters = exports.popularNovels = exports.site = exports.version = exports.icon = exports.name = exports.id = void 0; -const cheerio_1 = require("cheerio"); -const fetch_1 = require("@libs/fetch"); -const filterInputs_1 = require("@libs/filterInputs"); -const defaultCover_1 = require("@libs/defaultCover"); -const novelStatus_1 = require("@libs/novelStatus"); -const parseMadaraDate_1 = require("@libs/parseMadaraDate"); -const dayjs_1 = __importDefault(require("dayjs")); -exports.id = "zinnovel"; -exports.name = "ZinnNovel [madara]"; -exports.icon = "multisrc/madara/icons/zinnnovel.png"; -exports.version = "1.0.0"; -exports.site = "https://zinnovel.com/"; -const baseUrl = exports.site; -const popularNovels = (pageNo, { filters, showLatestNovels }) => __awaiter(void 0, void 0, void 0, function* () { - const novels = []; - let url = exports.site; - if (filters === null || filters === void 0 ? void 0 : filters.genres) { - url += "manga-genre/" + filters.genres + '/'; - } - else { - url += "manga/"; - } - url += '/page/' + pageNo + '/' + - '?m_orderby=' + (showLatestNovels ? 'latest' : ((filters === null || filters === void 0 ? void 0 : filters.sort) || 'rating')); - const body = yield (0, fetch_1.fetchApi)(url).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.manga-title-badges').remove(); - loadedCheerio('.page-item-detail').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - let novelUrl = loadedCheerio(this).find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - }); - return novels; -}); -exports.popularNovels = popularNovels; -const parseNovelAndChapters = (novelUrl) => __awaiter(void 0, void 0, void 0, function* () { - const novel = { - url: novelUrl, - }; - const body = yield (0, fetch_1.fetchApi)(novelUrl).then(res => res.text()); - let loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.manga-title-badges').remove(); - novel.name = loadedCheerio('.post-title h1').text().trim(); - novel.cover = - loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || - loadedCheerio('.summary_image > a > img').attr('data-src') || - loadedCheerio('.summary_image > a > img').attr('src') || - defaultCover_1.defaultCover; - loadedCheerio('.post-content_item, .post-content').each(function () { - const detailName = loadedCheerio(this).find('h5').text().trim(); - const detail = loadedCheerio(this).find('.summary-content').text().trim(); - switch (detailName) { - case 'Genre(s)': - case 'التصنيفات': - novel.genres = detail.replace(/[\t\n]/g, ','); - break; - case 'Author(s)': - case 'المؤلف': - case 'المؤلف (ين)': - novel.author = detail; - break; - case 'Status': - case 'الحالة': - novel.status = - detail.includes('OnGoing') || detail.includes('مستمرة') - ? novelStatus_1.NovelStatus.Ongoing - : novelStatus_1.NovelStatus.Completed; - break; - } - }); - loadedCheerio('div.summary__content .code-block,script').remove(); - novel.summary = loadedCheerio('div.summary__content').text().trim(); - let html; - if (false) { - const novelId = loadedCheerio('.rating-post-id').attr('value') || - loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; - const body = { - action: "manga_get_chapters", - manga: novelId, - }; - html = yield (0, fetch_1.fetchApi)(baseUrl + 'wp-admin/admin-ajax.php', { - method: 'POST', - body: JSON.stringify(body), - }) - .then(res => res.text()); - } - else { - html = yield (0, fetch_1.fetchApi)(baseUrl + 'ajax/chapters/', { method: 'POST' }) - .then(res => res.text()); - } - if (html !== '0') { - loadedCheerio = (0, cheerio_1.load)(html); - } - const chapters = []; - loadedCheerio('.wp-manga-chapter').each(function () { - const chapterName = loadedCheerio(this).find('a').text().trim(); - let releaseDate = null; - releaseDate = loadedCheerio(this) - .find('span.chapter-release-date') - .text() - .trim(); - if (releaseDate) { - releaseDate = (0, parseMadaraDate_1.parseMadaraDate)(releaseDate); - } - else { - /** - * Insert current date - */ - releaseDate = (0, dayjs_1.default)().format('LL'); - } - let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; - chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); - }); - novel.chapters = chapters.reverse(); - return novel; -}); -exports.parseNovelAndChapters = parseNovelAndChapters; -const parseChapter = (chapterUrl) => __awaiter(void 0, void 0, void 0, function* () { - const url = baseUrl + "/" + "manga" + "/" + chapterUrl; - const body = yield (0, fetch_1.fetchApi)(chapterUrl).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - const chapterText = loadedCheerio('.text-left').html() || - loadedCheerio('.text-right').html() || - loadedCheerio('.entry-content').html(); - return chapterText; -}); -exports.parseChapter = parseChapter; -const searchNovels = (searchTerm) => __awaiter(void 0, void 0, void 0, function* () { - const novels = []; - const url = baseUrl + "?s=" + searchTerm + "&post_type=wp-manga"; - const body = yield (0, fetch_1.fetchApi)(url).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.c-tabs-item__content').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - let novelUrl = loadedCheerio(this) - .find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - }); - return novels; -}); -exports.searchNovels = searchNovels; -const fetchImage = (url) => __awaiter(void 0, void 0, void 0, function* () { - return yield (0, fetch_1.fetchFile)(url); -}); -exports.fetchImage = fetchImage; -exports.filters = [{ "key": "sort", "label": "Order by", "values": [{ "label": "Rating", "value": "rating" }, { "label": "A-Z", "value": "alphabet" }, { "label": "Latest", "value": "latest" }, { "label": "Most Views", "value": "views" }, { "label": "New", "value": "new-manga" }, { "label": "Trending", "value": "trending" }], "inputType": filterInputs_1.FilterInputs.Picker }, { "key": "genres", "label": "GENRES", "values": [{ "label": "Action", "value": "action" }, { "label": "Adult", "value": "adult" }, { "label": "Adventure", "value": "adventure" }, { "label": "Anime", "value": "anime" }, { "label": "Cartoon", "value": "cartoon" }, { "label": "Comedy", "value": "comedy" }, { "label": "Comic", "value": "comic" }, { "label": "Cooking", "value": "cooking" }, { "label": "Detective", "value": "detective" }, { "label": "Doujinshi", "value": "doujinshi" }, { "label": "Drama", "value": "drama" }, { "label": "Ecchi", "value": "ecchi" }, { "label": "Fantasy", "value": "fantasy" }, { "label": "Game", "value": "game" }, { "label": "Gender Bender", "value": "gender-bender" }, { "label": "Harem", "value": "harem" }, { "label": "Historical", "value": "historical" }, { "label": "Horror", "value": "horror" }, { "label": "Isekai", "value": "isekai" }, { "label": "Josei", "value": "josei" }, { "label": "Live action", "value": "live-action" }, { "label": "Lolicon", "value": "lolicon" }, { "label": "Magical Realism", "value": "magical-realism" }, { "label": "Manga", "value": "manga" }, { "label": "Manhua", "value": "manhua" }, { "label": "Manhwa", "value": "manhwa" }, { "label": "Martial Arts", "value": "martial-arts" }, { "label": "Mature", "value": "mature" }, { "label": "Mecha", "value": "mecha" }, { "label": "Mystery", "value": "mystery" }, { "label": "One shot", "value": "one-shot" }, { "label": "Psychological", "value": "psychological" }, { "label": "Reincarnation", "value": "reincarnation" }, { "label": "Romance", "value": "romance" }, { "label": "School Life", "value": "school-life" }, { "label": "Sci-fi", "value": "sci-fi" }, { "label": "Seinen", "value": "seinen" }, { "label": "Shoujo", "value": "shoujo" }, { "label": "Shoujo Ai", "value": "shoujo-ai" }, { "label": "Shounen", "value": "shounen" }, { "label": "Shounen Ai", "value": "shounen-ai" }, { "label": "Slice of Life", "value": "slice-of-life" }, { "label": "Smut", "value": "smut" }, { "label": "Soft Yaoi", "value": "soft-yaoi" }, { "label": "Soft Yuri", "value": "soft-yuri" }, { "label": "Sports", "value": "sports" }, { "label": "Supernatural", "value": "supernatural" }, { "label": "Tragedy", "value": "tragedy" }, { "label": "Video Games", "value": "video-games" }, { "label": "Webtoon", "value": "webtoon" }, { "label": "Wuxia", "value": "wuxia" }, { "label": "Xianxia", "value": "xianxia" }, { "label": "Xuanhuan", "value": "xuanhuan" }, { "label": "Yaoi", "value": "yaoi" }, { "label": "Yuri", "value": "yuri" }], "inputType": filterInputs_1.FilterInputs.Picker }]; diff --git a/js/plugins/english/allnovelfull.js b/js/plugins/english/allnovelfull.js deleted file mode 100644 index da80d22..0000000 --- a/js/plugins/english/allnovelfull.js +++ /dev/null @@ -1,177 +0,0 @@ -"use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.fetchImage = exports.searchNovels = exports.parseChapter = exports.parseNovelAndChapters = exports.popularNovels = exports.icon = exports.version = exports.site = exports.name = exports.id = void 0; -const cheerio_1 = require("cheerio"); -const fetch_1 = require("@libs/fetch"); -exports.id = "ANF.com"; -exports.name = "AllNovelFull"; -exports.site = "https://allnovelfull.com"; -exports.version = "1.0.0"; -exports.icon = "src/en/allnovelfull/icon.png"; -const popularNovels = function (page) { - return __awaiter(this, void 0, void 0, function* () { - const url = `${exports.site}/most-popular?page=${page}`; - const result = yield (0, fetch_1.fetchApi)(url, {}); - if (!result.ok) { - console.error("Cloudflare error"); - // console.error(await result.text()); - // TODO: Cloudflare protection or other error - return []; - } - const body = yield result.text(); - const loadedCheerio = (0, cheerio_1.load)(body); - const novels = []; - loadedCheerio(".col-truyen-main .list-truyen .row").each(function () { - const novelName = loadedCheerio(this) - .find("h3.truyen-title > a") - .text(); - const novelCover = exports.site + loadedCheerio(this).find("img.cover").attr("src"); - const novelUrl = exports.site + loadedCheerio(this).find("h3.truyen-title > a").attr("href"); - const novel = { - url: novelUrl, - name: novelName, - cover: novelCover, - }; - novels.push(novel); - }); - return novels; - }); -}; -exports.popularNovels = popularNovels; -const parseNovelAndChapters = function (novelUrl) { - return __awaiter(this, void 0, void 0, function* () { - const url = novelUrl; - const result = yield (0, fetch_1.fetchApi)(url); - if (!result.ok) { - console.error("Cloudflare error"); - // console.error(await result.text()); - // TODO: Cloudflare protection or other error - return { url, chapters: [] }; - } - const body = yield result.text(); - let loadedCheerio = (0, cheerio_1.load)(body); - let novel = { - url: novelUrl, - }; - novel.name = loadedCheerio("div.book > img").attr("alt"); - novel.cover = exports.site + loadedCheerio("div.book > img").attr("src"); - novel.summary = loadedCheerio("div.desc-text").text().trim(); - novel.author = loadedCheerio("div.info > div > h3") - .filter(function () { - return loadedCheerio(this).text().trim() === "Author:"; - }) - .siblings() - .text(); - novel.genres = loadedCheerio("div.info > div") - .filter(function () { - return (loadedCheerio(this).find("h3").text().trim() === "Genre:"); - }) - .text() - .replace("Genre:", ""); - novel.status = loadedCheerio("div.info > div > h3") - .filter(function () { - return loadedCheerio(this).text().trim() === "Status:"; - }) - .next() - .text(); - const novelId = loadedCheerio("#rating").attr("data-novel-id"); - function getChapters(id) { - return __awaiter(this, void 0, void 0, function* () { - const chapterListUrl = exports.site + "/ajax/chapter-option?novelId=" + id; - const data = yield (0, fetch_1.fetchApi)(chapterListUrl); - if (!data.ok) { - console.error("Cloudflare error"); - // console.error(await result.text()); - // TODO: Cloudflare protection or other error - return []; - } - const chapters = yield data.text(); - loadedCheerio = (0, cheerio_1.load)(chapters); - const novelChapters = []; - loadedCheerio("select > option").each(function () { - var _a; - let chapterName = loadedCheerio(this).text(); - let releaseDate = null; - let chapterUrl = (_a = loadedCheerio(this) - .attr("value")) === null || _a === void 0 ? void 0 : _a.replace(`/${novelUrl}`, ""); - if (chapterUrl) { - novelChapters.push({ - name: chapterName, - releaseTime: releaseDate, - url: chapterUrl, - }); - } - }); - return novelChapters; - }); - } - if (novelId) { - novel.chapters = yield getChapters(novelId); - } - return novel; - }); -}; -exports.parseNovelAndChapters = parseNovelAndChapters; -const parseChapter = function (chapterUrl) { - return __awaiter(this, void 0, void 0, function* () { - const url = exports.site + chapterUrl; - const result = yield (0, fetch_1.fetchApi)(url); - if (!result.ok) { - console.error("Cloudflare error"); - // console.error(await result.text()); - // TODO: Cloudflare protection or other error - return "Cloudflare protected site!"; - } - const body = yield result.text(); - const loadedCheerio = (0, cheerio_1.load)(body); - const chapterText = loadedCheerio("#chapter-content").html() || ""; - return chapterText; - }); -}; -exports.parseChapter = parseChapter; -const searchNovels = function (searchTerm) { - return __awaiter(this, void 0, void 0, function* () { - const url = `${exports.site}/search?keyword=${searchTerm}`; - const result = yield (0, fetch_1.fetchApi)(url); - if (!result.ok) { - console.error(yield result.text()); - // TODO: Cloudflare protection or other error - return []; - } - const body = yield result.text(); - const loadedCheerio = (0, cheerio_1.load)(body); - let novels = []; - loadedCheerio("div.col-truyen-main > div.list-truyen > .row").each(function () { - const novelUrl = exports.site + - loadedCheerio(this).find("h3.truyen-title > a").attr("href"); - const novelName = loadedCheerio(this) - .find("h3.truyen-title > a") - .text(); - const novelCover = exports.site + loadedCheerio(this).find("img").attr("src"); - if (novelUrl) { - novels.push({ - url: novelUrl, - name: novelName, - cover: novelCover, - }); - } - }); - return novels; - }); -}; -exports.searchNovels = searchNovels; -const fetchImage = function (url, init) { - return __awaiter(this, void 0, void 0, function* () { - return yield (0, fetch_1.fetchFile)(url, init); - }); -}; -exports.fetchImage = fetchImage; diff --git a/js/plugins/english/bestlightnovel.js b/js/plugins/english/bestlightnovel.js deleted file mode 100644 index 77095ae..0000000 --- a/js/plugins/english/bestlightnovel.js +++ /dev/null @@ -1,149 +0,0 @@ -"use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.fetchImage = exports.searchNovels = exports.parseChapter = exports.parseNovelAndChapters = exports.popularNovels = exports.icon = exports.version = exports.site = exports.name = exports.id = void 0; -const cheerio_1 = require("cheerio"); -const defaultCover_1 = require("@libs/defaultCover"); -const fetch_1 = require("@libs/fetch"); -const novelStatus_1 = require("@libs/novelStatus"); -exports.id = "BLN.com"; -exports.name = "BestLightNovel"; -exports.site = "https://bestlightnovel.com/"; -exports.version = "1.0.0"; -exports.icon = "src/en/bestlightnovel/icon.png"; -const popularNovels = function (page) { - return __awaiter(this, void 0, void 0, function* () { - const url = exports.site + "novel_list?type=topview&category=all&state=all&page=1" + page; - const result = yield (0, fetch_1.fetchApi)(url); - if (!result.ok) { - console.error(yield result.text()); - // TODO: Cloudflare protection or other error - return []; - } - const body = yield result.text(); - const loadedCheerio = (0, cheerio_1.load)(body); - let novels = []; - loadedCheerio(".update_item.list_category").each(function () { - const novelName = loadedCheerio(this).find("h3 > a").text(); - const novelCover = loadedCheerio(this).find("img").attr("src"); - const novelUrl = loadedCheerio(this).find("h3 > a").attr("href"); - if (!novelUrl) { - // TODO: Handle error - console.error("No novel url!"); - return; - } - const novel = { - name: novelName, - url: novelUrl, - cover: novelCover, - }; - novels.push(novel); - }); - return novels; - }); -}; -exports.popularNovels = popularNovels; -const parseNovelAndChapters = function (novelUrl) { - var _a, _b, _c; - return __awaiter(this, void 0, void 0, function* () { - const url = novelUrl; - const result = yield (0, fetch_1.fetchApi)(url); - if (!result.ok) { - console.error(yield result.text()); - // TODO: Cloudflare protection - return { url, chapters: [] }; - } - const body = yield result.text(); - let loadedCheerio = (0, cheerio_1.load)(body); - let novel = { - url, - name: "", - cover: "", - author: "", - status: novelStatus_1.NovelStatus.Unknown, - genres: "", - summary: "", - chapters: [], - }; - novel.name = loadedCheerio(".truyen_info_right h1").text().trim(); - novel.cover = - loadedCheerio(".info_image img").attr("src") || defaultCover_1.defaultCover; - novel.summary = (_a = loadedCheerio("#noidungm").text()) === null || _a === void 0 ? void 0 : _a.trim(); - novel.author = (_b = loadedCheerio("#main_body > div.cotgiua > div.truyen_info_wrapper > div.truyen_info > div.entry-header > div.truyen_if_wrap > ul > li:nth-child(2) > a") - .text()) === null || _b === void 0 ? void 0 : _b.trim(); - let status = (_c = loadedCheerio("#main_body > div.cotgiua > div.truyen_info_wrapper > div.truyen_info > div.entry-header > div.truyen_if_wrap > ul > li:nth-child(4) > a") - .text()) === null || _c === void 0 ? void 0 : _c.trim(); - novel.status = - status === "ONGOING" - ? novelStatus_1.NovelStatus.Ongoing - : status === "COMPLETED" - ? novelStatus_1.NovelStatus.Completed - : novelStatus_1.NovelStatus.Unknown; - let novelChapters = []; - loadedCheerio(".chapter-list div.row").each(function () { - const chapterName = loadedCheerio(this).find("a").text().trim(); - const releaseDate = loadedCheerio(this) - .find("span:nth-child(2)") - .text() - .trim(); - const chapterUrl = loadedCheerio(this).find("a").attr("href"); - if (!chapterUrl) { - // TODO: Handle error - console.error("No chapter url!"); - return; - } - novelChapters.push({ - name: chapterName, - releaseTime: releaseDate, - url: chapterUrl, - }); - }); - novel.chapters = novelChapters.reverse(); - return novel; - }); -}; -exports.parseNovelAndChapters = parseNovelAndChapters; -const parseChapter = function (chapterUrl) { - return __awaiter(this, void 0, void 0, function* () { - const url = chapterUrl; - const result = yield (0, fetch_1.fetchApi)(url); - const body = yield result.text(); - let loadedCheerio = (0, cheerio_1.load)(body); - const chapterText = loadedCheerio("#vung_doc").html(); - return chapterText; - }); -}; -exports.parseChapter = parseChapter; -const searchNovels = function (searchTerm) { - return __awaiter(this, void 0, void 0, function* () { - const url = `${exports.site}search_novels/${searchTerm}`; - const result = yield (0, fetch_1.fetchApi)(url); - const body = yield result.text(); - let loadedCheerio = (0, cheerio_1.load)(body); - let novels = []; - loadedCheerio(".update_item.list_category").each(function () { - const novelName = loadedCheerio(this).find("h3 > a").text(); - const novelCover = loadedCheerio(this).find("img").attr("src"); - const novelUrl = loadedCheerio(this).find("h3 > a").attr("href"); - if (!novelUrl) { - // TODO: Handle error - console.error("No novel url!"); - return; - } - const novel = { name: novelName, cover: novelCover, url: novelUrl }; - novels.push(novel); - }); - return novels; - }); -}; -exports.searchNovels = searchNovels; -const fetchImage = (...args) => (0, fetch_1.fetchFile)(...args); -exports.fetchImage = fetchImage; diff --git a/js/plugins/english/comrademao.js b/js/plugins/english/comrademao.js deleted file mode 100644 index 1d4fa39..0000000 --- a/js/plugins/english/comrademao.js +++ /dev/null @@ -1,146 +0,0 @@ -"use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.fetchImage = exports.searchNovels = exports.parseChapter = exports.parseNovelAndChapters = exports.popularNovels = exports.icon = exports.version = exports.site = exports.name = exports.id = void 0; -const cheerio_1 = require("cheerio"); -const fetch_1 = require("@libs/fetch"); -const dayjs_1 = __importDefault(require("dayjs")); -exports.id = "comrademao"; -exports.name = "Comrade Mao"; -exports.site = "https://comrademao.com/"; -exports.version = "1.0.0"; -exports.icon = "src/en/comrademao/icon.png"; -const popularNovels = function (page) { - return __awaiter(this, void 0, void 0, function* () { - let url = exports.site + "page/" + page + "/?post_type=novel"; - const result = yield (0, fetch_1.fetchApi)(url); - const body = yield result.text(); - const loadedCheerio = (0, cheerio_1.load)(body); - let novels = []; - loadedCheerio(".listupd") - .find("div.bs") - .each(function () { - const novelName = loadedCheerio(this).find(".tt").text().trim(); - const novelCover = loadedCheerio(this).find("img").attr("src"); - const novelUrl = loadedCheerio(this).find("a").attr("href"); - if (!novelUrl) { - // TODO: Handle error - console.error("No novel url!"); - return; - } - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - }); - return novels; - }); -}; -exports.popularNovels = popularNovels; -const parseNovelAndChapters = function (novelUrl) { - return __awaiter(this, void 0, void 0, function* () { - const url = novelUrl; - const result = yield (0, fetch_1.fetchApi)(url); - const body = yield result.text(); - const loadedCheerio = (0, cheerio_1.load)(body); - let novel = { url }; - novel.name = loadedCheerio(".entry-title").text().trim(); - novel.cover = loadedCheerio("div.thumbook > div > img").attr("src"); - novel.summary = loadedCheerio("div.infox > div:nth-child(6) > span > p") - .text() - .trim(); - novel.genres = loadedCheerio("div.infox > div:nth-child(4) > span") - .text() - .replace(/\s/g, ""); - novel.status = loadedCheerio("div.infox > div:nth-child(3) > span") - .text() - .trim(); - novel.author = loadedCheerio("div.infox > div:nth-child(2) > span") - .text() - .trim(); - let novelChapters = []; - loadedCheerio("#chapterlist") - .find("li") - .each(function () { - const releaseDate = (0, dayjs_1.default)(loadedCheerio(this).find(".chapterdate").text()).format("LL"); - const chapterName = loadedCheerio(this) - .find(".chapternum") - .text(); - const chapterUrl = loadedCheerio(this).find("a").attr("href"); - if (!chapterUrl) { - // TODO: Handle error - console.error("No chapter url!"); - return; - } - novelChapters.push({ - name: chapterName, - url: chapterUrl, - releaseTime: releaseDate, - }); - }); - novel.chapters = novelChapters.reverse(); - return novel; - }); -}; -exports.parseNovelAndChapters = parseNovelAndChapters; -const parseChapter = function (chapterUrl) { - return __awaiter(this, void 0, void 0, function* () { - const url = chapterUrl; - const result = yield (0, fetch_1.fetchApi)(url); - if (!result.ok) { - const err = yield result.text(); - console.error(err); - // TODO: Cloudflare protection or other error - return "Error!" + err; - } - const body = yield result.text(); - const loadedCheerio = (0, cheerio_1.load)(body); - let chapterText = loadedCheerio("#chaptercontent").html(); - return chapterText; - }); -}; -exports.parseChapter = parseChapter; -const searchNovels = function (searchTerm) { - return __awaiter(this, void 0, void 0, function* () { - const url = exports.site + "?s=" + searchTerm + "&post_type=novel"; - const result = yield (0, fetch_1.fetchApi)(url); - const body = yield result.text(); - const loadedCheerio = (0, cheerio_1.load)(body); - let novels = []; - loadedCheerio(".listupd") - .find("div.bs") - .each(function () { - const novelName = loadedCheerio(this).find(".tt").text().trim(); - const novelCover = loadedCheerio(this).find("img").attr("src"); - const novelUrl = loadedCheerio(this).find("a").attr("href"); - if (!novelUrl) { - // TODO: Handle error - console.error("No novel url!"); - return; - } - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - }); - return novels; - }); -}; -exports.searchNovels = searchNovels; -const fetchImage = (...args) => (0, fetch_1.fetchFile)(...args); -exports.fetchImage = fetchImage; diff --git a/js/plugins/english/divinedaolibrary.js b/js/plugins/english/divinedaolibrary.js deleted file mode 100644 index 3309a14..0000000 --- a/js/plugins/english/divinedaolibrary.js +++ /dev/null @@ -1,134 +0,0 @@ -"use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.fetchImage = exports.searchNovels = exports.parseChapter = exports.parseNovelAndChapters = exports.popularNovels = exports.icon = exports.version = exports.site = exports.name = exports.id = void 0; -const cheerio_1 = require("cheerio"); -const fetch_1 = require("@libs/fetch"); -const defaultCover_1 = require("@libs/defaultCover"); -exports.id = "DDL.com"; -exports.name = "Divine Dao Library"; -exports.site = "https://www.divinedaolibrary.com/"; -exports.version = "1.0.0"; -exports.icon = "src/en/divinedaolibrary/icon.png"; -const baseUrl = exports.site; -const popularNovels = function (page) { - return __awaiter(this, void 0, void 0, function* () { - let url = baseUrl + "novels"; - const result = yield (0, fetch_1.fetchApi)(url); - const body = yield result.text(); - const loadedCheerio = (0, cheerio_1.load)(body); - let novels = []; - loadedCheerio("#main") - .find("li") - .each(function () { - const novelName = loadedCheerio(this).find("a").text(); - const novelCover = defaultCover_1.defaultCover; - const novelUrl = loadedCheerio(this).find(" a").attr("href"); - if (!novelUrl) - return; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - }); - return novels; - }); -}; -exports.popularNovels = popularNovels; -const parseNovelAndChapters = function (novelUrl) { - return __awaiter(this, void 0, void 0, function* () { - const url = novelUrl; - const result = yield (0, fetch_1.fetchApi)(url); - const body = yield result.text(); - const loadedCheerio = (0, cheerio_1.load)(body); - let novel = { url }; - novel.name = loadedCheerio("h1.entry-title").text().trim(); - novel.cover = - loadedCheerio(".entry-content").find("img").attr("data-ezsrc") || - defaultCover_1.defaultCover; - novel.summary = loadedCheerio("#main > article > div > p:nth-child(6)") - .text() - .trim(); - novel.author = loadedCheerio("#main > article > div > h3:nth-child(2)") - .text() - .replace(/Author:/g, "") - .trim(); - let novelChapters = []; - loadedCheerio("#main") - .find("li > span > a") - .each(function () { - const chapterName = loadedCheerio(this).text().trim(); - const releaseDate = null; - const chapterUrl = loadedCheerio(this).attr("href"); - if (!chapterUrl) - return; - novelChapters.push({ - name: chapterName, - releaseTime: releaseDate, - url: chapterUrl, - }); - }); - novel.chapters = novelChapters; - return novel; - }); -}; -exports.parseNovelAndChapters = parseNovelAndChapters; -const parseChapter = function (chapterUrl) { - return __awaiter(this, void 0, void 0, function* () { - const url = chapterUrl; - const result = yield (0, fetch_1.fetchApi)(url); - const body = yield result.text(); - const loadedCheerio = (0, cheerio_1.load)(body); - let chapterName = loadedCheerio(".entry-title").text().trim(); - let chapterText = loadedCheerio(".entry-content").html(); - if (!chapterText) { - chapterText = loadedCheerio(".page-header").html(); - } - chapterText = `

${chapterName}

` + chapterText; - return chapterText; - }); -}; -exports.parseChapter = parseChapter; -const searchNovels = function (searchTerm) { - return __awaiter(this, void 0, void 0, function* () { - let url = baseUrl + "novels"; - const result = yield (0, fetch_1.fetchApi)(url); - const body = yield result.text(); - const loadedCheerio = (0, cheerio_1.load)(body); - let novels = []; - loadedCheerio("#main") - .find("li") - .each(function () { - const novelName = loadedCheerio(this).find("a").text(); - const novelCover = defaultCover_1.defaultCover; - const novelUrl = loadedCheerio(this).find(" a").attr("href"); - if (!novelUrl) - return; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - }); - novels = novels.filter((novel) => novel.name.toLowerCase().includes(searchTerm.toLowerCase())); - return novels; - }); -}; -exports.searchNovels = searchNovels; -const fetchImage = function (url, init) { - return __awaiter(this, void 0, void 0, function* () { - return yield (0, fetch_1.fetchFile)(url, init); - }); -}; -exports.fetchImage = fetchImage; diff --git a/js/plugins/english/earlynovel.js b/js/plugins/english/earlynovel.js deleted file mode 100644 index f39a00c..0000000 --- a/js/plugins/english/earlynovel.js +++ /dev/null @@ -1,174 +0,0 @@ -"use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.fetchImage = exports.searchNovels = exports.parseChapter = exports.parseNovelAndChapters = exports.popularNovels = exports.site = exports.icon = exports.version = exports.name = exports.id = void 0; -const cheerio_1 = require("cheerio"); -const fetch_1 = require("@libs/fetch"); -const showToast_1 = require("@libs/showToast"); -const defaultCover_1 = require("@libs/defaultCover"); -exports.id = "earlynovel"; -exports.name = "Early Novel"; -exports.version = "1.0.0"; -exports.icon = "multisrc/madara/icons/latestnovel.png"; -exports.site = "https://earlynovel.net/"; -const pluginId = exports.id; -const baseUrl = exports.site; -const popularNovels = function (page) { - return __awaiter(this, void 0, void 0, function* () { - const url = `${baseUrl}most-popular?page=${page}`; - const body = yield (0, fetch_1.fetchApi)(url, {}, pluginId).then((r) => r.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - let novels = []; - loadedCheerio(".col-truyen-main > .list-truyen > .row").each(function () { - var _a; - const novelName = loadedCheerio(this) - .find("h3.truyen-title > a") - .attr("title"); - const novelCover = loadedCheerio(this).find(".lazyimg").attr("data-desk-image") || - loadedCheerio(this).find("img.cover").attr("src"); - const novelUrl = baseUrl + - ((_a = loadedCheerio(this) - .find("h3.truyen-title > a") - .attr("href")) === null || _a === void 0 ? void 0 : _a.slice(1)); - if (!novelUrl || !novelName) - return; - const novel = { - name: novelName, - cover: novelCover || defaultCover_1.defaultCover, - url: novelUrl, - }; - novels.push(novel); - }); - return novels; - }); -}; -exports.popularNovels = popularNovels; -const parseNovelAndChapters = function (novelUrl) { - var _a; - return __awaiter(this, void 0, void 0, function* () { - (0, showToast_1.showToast)("Early Novel may take 20-30 seconds"); - const url = novelUrl; - const body = yield (0, fetch_1.fetchApi)(url, {}, pluginId).then((r) => r.text()); - let loadedCheerio = (0, cheerio_1.load)(body); - const name = loadedCheerio(".book > img").attr("alt"); - const cover = loadedCheerio(".book > img").attr("src") || defaultCover_1.defaultCover; - const summary = loadedCheerio(".desc-text").text().trim(); - const novel = { - url, - chapters: [], - name, - summary, - cover, - }; - loadedCheerio(".info > div > h3").each(function () { - let detailName = loadedCheerio(this).text(); - let detail = loadedCheerio(this) - .siblings() - .map((i, el) => loadedCheerio(el).text()) - .toArray() - .join(","); - switch (detailName) { - case "Author:": - novel.author = detail; - break; - case "Status:": - novel.status = detail; - break; - case "Genre:": - novel.genres = detail; - break; - } - }); - //! Doesn't work since there are multiple pages and can't find source API - //# Since cannot find sourceAPI i try similar function to lightnovelpub - const delay = (ms) => new Promise((res) => setTimeout(res, ms)); - const lastPageStr = (_a = loadedCheerio('a:contains("Last ")') - .attr("title")) === null || _a === void 0 ? void 0 : _a.match(/(\d+)/g); - const lastPage = Number((lastPageStr === null || lastPageStr === void 0 ? void 0 : lastPageStr[1]) || "0"); - function getChapters() { - return __awaiter(this, void 0, void 0, function* () { - let chapter = []; - for (let i = 1; i <= lastPage; i++) { - const chaptersUrl = `${novelUrl}?page=${i}`; - const chaptersHtml = yield (0, fetch_1.fetchApi)(chaptersUrl, {}, pluginId).then((r) => r.text()); - loadedCheerio = (0, cheerio_1.load)(chaptersHtml); - loadedCheerio("ul.list-chapter > li").each(function () { - var _a; - const chapterName = loadedCheerio(this) - .find(".chapter-text") - .text() - .trim(); - const releaseDate = null; - const chapterHref = (_a = loadedCheerio(this) - .find("a") - .attr("href")) === null || _a === void 0 ? void 0 : _a.slice(1); - if (!chapterHref) - return; - const chapterUrl = baseUrl + chapterHref; - chapter.push({ - name: chapterName, - releaseTime: releaseDate, - url: chapterUrl, - }); - }); - yield delay(1000); - } - return chapter; - }); - } - novel.chapters = yield getChapters(); - return novel; - }); -}; -exports.parseNovelAndChapters = parseNovelAndChapters; -const parseChapter = function (chapterUrl) { - return __awaiter(this, void 0, void 0, function* () { - const body = yield (0, fetch_1.fetchApi)(chapterUrl, {}, pluginId).then((r) => r.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - const chapterText = loadedCheerio("#chapter-c").html() || ""; - return chapterText; - }); -}; -exports.parseChapter = parseChapter; -const searchNovels = function (searchTerm) { - return __awaiter(this, void 0, void 0, function* () { - const url = `${baseUrl}search?keyword=${searchTerm}`; - const body = yield (0, fetch_1.fetchApi)(url, {}, pluginId).then((r) => r.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - let novels = []; - loadedCheerio("div.col-truyen-main > div.list-truyen > .row").each(function () { - const novelUrl = baseUrl + - loadedCheerio(this).find("h3.truyen-title > a").attr("href"); - const novelName = loadedCheerio(this) - .find("h3.truyen-title > a") - .text(); - const novelCover = baseUrl + loadedCheerio(this).find("img").attr("src"); - if (novelUrl) { - novels.push({ - url: novelUrl, - name: novelName, - cover: novelCover, - }); - } - }); - return novels; - }); -}; -exports.searchNovels = searchNovels; -const fetchImage = function fetchImage(url) { - return __awaiter(this, void 0, void 0, function* () { - const headers = { - Referer: baseUrl, - }; - return yield (0, fetch_1.fetchFile)(url, { headers: headers }); - }); -}; -exports.fetchImage = fetchImage; diff --git a/js/plugins/english/fastnovel.js b/js/plugins/english/fastnovel.js deleted file mode 100644 index 23db36d..0000000 --- a/js/plugins/english/fastnovel.js +++ /dev/null @@ -1,152 +0,0 @@ -"use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.fetchImage = exports.searchNovels = exports.parseChapter = exports.parseNovelAndChapters = exports.popularNovels = exports.site = exports.icon = exports.version = exports.name = exports.id = void 0; -const cheerio_1 = require("cheerio"); -const fetch_1 = require("@libs/fetch"); -exports.id = "fastnovel"; -exports.name = "Fast Novel"; -exports.version = "1.0.0"; -exports.icon = "src/en/fastnovel/icon.png"; -exports.site = "https://fastnovel.org/"; -const pluginId = exports.id; -const baseUrl = exports.site; -const popularNovels = function (page) { - return __awaiter(this, void 0, void 0, function* () { - const url = `${baseUrl}sort/p/?page=${page}`; - const body = yield (0, fetch_1.fetchApi)(url, {}, pluginId).then((r) => r.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - let novels = []; - loadedCheerio(".col-novel-main .list-novel .row").each(function () { - const novelName = loadedCheerio(this).find("h3.novel-title > a").text(); - const novelCover = loadedCheerio(this).find("img.cover").attr("src"); - const novelUrl = loadedCheerio(this) - .find("h3.novel-title > a") - .attr("href"); - if (!novelUrl) - return; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - }); - return novels; - }); -}; -exports.popularNovels = popularNovels; -const parseNovelAndChapters = function (novelUrl) { - return __awaiter(this, void 0, void 0, function* () { - const url = novelUrl; - const body = yield (0, fetch_1.fetchApi)(url, {}, pluginId).then((r) => r.text()); - let loadedCheerio = (0, cheerio_1.load)(body); - const novel = { - url, - chapters: [], - }; - novel.name = loadedCheerio("div.book > img").attr("alt"); - novel.cover = loadedCheerio("div.book > img").attr("src"); - novel.summary = loadedCheerio("div.desc-text").text().trim(); - loadedCheerio("ul.info > li > h3").each(function () { - let detailName = loadedCheerio(this).text(); - let detail = loadedCheerio(this) - .siblings() - .map((i, el) => loadedCheerio(el).text()) - .toArray() - .join(","); - switch (detailName) { - case "Author:": - novel.author = detail; - break; - case "Status:": - novel.status = detail; - break; - case "Genre:": - novel.genres = detail; - break; - } - }); - const novelId = loadedCheerio("#rating").attr("data-novel-id"); - function getChapters(id) { - return __awaiter(this, void 0, void 0, function* () { - const chapterListUrl = baseUrl + "ajax/chapter-archive?novelId=" + id; - const data = yield (0, fetch_1.fetchApi)(chapterListUrl); - const chapterdata = yield data.text(); - loadedCheerio = (0, cheerio_1.load)(chapterdata); - let chapter = []; - loadedCheerio("ul.list-chapter > li").each(function () { - const chapterName = loadedCheerio(this).find("a").attr("title"); - const releaseDate = null; - const chapterUrl = loadedCheerio(this).find("a").attr("href"); - if (!chapterName || !chapterUrl) - return; - chapter.push({ - name: chapterName, - releaseTime: releaseDate, - url: chapterUrl, - }); - }); - return chapter; - }); - } - if (novelId) { - novel.chapters = yield getChapters(novelId); - } - return novel; - }); -}; -exports.parseNovelAndChapters = parseNovelAndChapters; -const parseChapter = function (chapterUrl) { - return __awaiter(this, void 0, void 0, function* () { - const body = yield (0, fetch_1.fetchApi)(chapterUrl, {}, pluginId).then((r) => r.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('#chr-content > div,h6,p[style="display: none;"]').remove(); - let chapterText = loadedCheerio("#chr-content").html(); - return chapterText; - }); -}; -exports.parseChapter = parseChapter; -const searchNovels = function (searchTerm) { - return __awaiter(this, void 0, void 0, function* () { - const url = `${baseUrl}search/?keyword=${searchTerm}`; - const body = yield (0, fetch_1.fetchApi)(url, {}, pluginId).then((r) => r.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - let novels = []; - loadedCheerio("div.col-novel-main > div.list-novel > .row").each(function () { - const novelUrl = loadedCheerio(this) - .find("h3.novel-title > a") - .attr("href"); - const novelName = loadedCheerio(this) - .find("h3.novel-title > a") - .text(); - const novelCover = loadedCheerio(this).find("img").attr("src"); - if (novelUrl) { - novels.push({ - url: novelUrl, - name: novelName, - cover: novelCover, - }); - } - }); - return novels; - }); -}; -exports.searchNovels = searchNovels; -const fetchImage = function (url) { - return __awaiter(this, void 0, void 0, function* () { - const headers = { - Referer: baseUrl, - }; - return yield (0, fetch_1.fetchFile)(url, { headers: headers }); - }); -}; -exports.fetchImage = fetchImage; diff --git a/js/plugins/english/foxaholic.js b/js/plugins/english/foxaholic.js deleted file mode 100644 index 3dd859f..0000000 --- a/js/plugins/english/foxaholic.js +++ /dev/null @@ -1,154 +0,0 @@ -"use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.fetchImage = exports.searchNovels = exports.parseChapter = exports.parseNovelAndChapters = exports.popularNovels = exports.site = exports.icon = exports.version = exports.name = exports.id = void 0; -const cheerio_1 = require("cheerio"); -const fetch_1 = require("@libs/fetch"); -exports.id = "foxaholic"; -exports.name = "Foxaholic"; -exports.version = "1.0.0"; -exports.icon = "src/en/foxaholic/icon.png"; -exports.site = "https://www.foxaholic.com/"; -const pluginId = exports.id; -const baseUrl = exports.site; -const popularNovels = function (page) { - return __awaiter(this, void 0, void 0, function* () { - const link = `${baseUrl}novel/page/${page}/?m_orderby=rating`; - const result = yield (0, fetch_1.fetchApi)(link, {}, pluginId); - const body = yield result.text(); - const loadedCheerio = (0, cheerio_1.load)(body); - const novels = []; - loadedCheerio(".page-item-detail").each(function () { - const novelName = loadedCheerio(this).find(".h5 > a").text(); - const novelCover = loadedCheerio(this).find("img").attr("data-src"); - const novelUrl = loadedCheerio(this).find(".h5 > a").attr("href"); - if (!novelUrl) - return; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - }); - return novels; - }); -}; -exports.popularNovels = popularNovels; -const parseNovelAndChapters = function (novelUrl) { - return __awaiter(this, void 0, void 0, function* () { - const url = novelUrl; - const result = yield (0, fetch_1.fetchApi)(url, {}, pluginId); - const body = yield result.text(); - let loadedCheerio = (0, cheerio_1.load)(body); - const novel = { - url, - chapters: [], - }; - novel.name = loadedCheerio(".post-title > h1").text().trim(); - novel.cover = loadedCheerio(".summary_image > a > img").attr("data-src"); - loadedCheerio(".post-content_item").each(function () { - const detailName = loadedCheerio(this) - .find(".summary-heading > h5") - .text() - .trim(); - const detail = loadedCheerio(this).find(".summary-content").html(); - if (!detail) - return; - switch (detailName) { - case "Genre": - novel.genres = loadedCheerio(detail) - .children("a") - .map((i, el) => loadedCheerio(el).text()) - .toArray() - .join(","); - break; - case "Author": - novel.author = loadedCheerio(detail) - .children("a") - .map((i, el) => loadedCheerio(el).text()) - .toArray() - .join(", "); - break; - case "Novel": - novel.status = detail === null || detail === void 0 ? void 0 : detail.trim().replace(/G/g, "g"); - break; - } - }); - loadedCheerio(".description-summary > div.summary__content > div").remove(); - novel.summary = loadedCheerio(".description-summary > div.summary__content") - .text() - .trim(); - let chapter = []; - loadedCheerio(".wp-manga-chapter").each(function () { - const chapterName = loadedCheerio(this) - .find("a") - .text() - .replace(/[\t\n]/g, "") - .trim(); - const releaseDate = loadedCheerio(this).find("span").text().trim(); - const chapterUrl = loadedCheerio(this).find("a").attr("href"); - if (!chapterUrl) - return; - chapter.push({ - name: chapterName, - releaseTime: releaseDate, - url: chapterUrl, - }); - }); - novel.chapters = chapter.reverse(); - return novel; - }); -}; -exports.parseNovelAndChapters = parseNovelAndChapters; -const parseChapter = function (chapterUrl) { - return __awaiter(this, void 0, void 0, function* () { - const result = yield (0, fetch_1.fetchApi)(chapterUrl, {}, pluginId); - const body = yield result.text(); - const loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio("img").removeAttr("srcset"); - let chapterText = loadedCheerio(".reading-content").html(); - return chapterText; - }); -}; -exports.parseChapter = parseChapter; -const searchNovels = function (searchTerm) { - return __awaiter(this, void 0, void 0, function* () { - const url = `${baseUrl}?s=${searchTerm}&post_type=wp-manga`; - const result = yield (0, fetch_1.fetchApi)(url, {}, pluginId); - const body = yield result.text(); - const loadedCheerio = (0, cheerio_1.load)(body); - const novels = []; - loadedCheerio(".c-tabs-item__content").each(function () { - const novelName = loadedCheerio(this).find(".h4 > a").text(); - const novelCover = loadedCheerio(this).find("img").attr("data-src"); - const novelUrl = loadedCheerio(this).find(".h4 > a").attr("href"); - if (!novelUrl) - return; - novels.push({ - name: novelName, - url: novelUrl, - cover: novelCover, - }); - }); - return novels; - }); -}; -exports.searchNovels = searchNovels; -const fetchImage = function (url) { - return __awaiter(this, void 0, void 0, function* () { - const headers = { - Referer: baseUrl, - }; - return yield (0, fetch_1.fetchFile)(url, { headers: headers }); - }); -}; -exports.fetchImage = fetchImage; diff --git a/js/plugins/english/freenovelupdates.js b/js/plugins/english/freenovelupdates.js deleted file mode 100644 index e37a6e3..0000000 --- a/js/plugins/english/freenovelupdates.js +++ /dev/null @@ -1,118 +0,0 @@ -"use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.fetchImage = exports.searchNovels = exports.parseChapter = exports.parseNovelAndChapters = exports.popularNovels = exports.site = exports.icon = exports.version = exports.name = exports.id = void 0; -const cheerio_1 = require("cheerio"); -const fetch_1 = require("@libs/fetch"); -const showToast_1 = require("@libs/showToast"); -const isAbsoluteUrl_1 = require("@libs/isAbsoluteUrl"); -exports.id = "freenovelupdates"; -exports.name = "Free Novel Updates (Broken)"; -exports.version = "1.0.0"; -exports.icon = "src/en/freenovelupdates/icon.png"; -exports.site = "https://www.freenovelupdates.com"; -const pluginId = exports.id; -const baseUrl = exports.site; -const popularNovels = function (page) { - return __awaiter(this, void 0, void 0, function* () { - const url = `${baseUrl}genres/light-novel-1002`; - const body = yield (0, fetch_1.fetchApi)(url, {}, pluginId).then((r) => r.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - let novels = []; - loadedCheerio(".books-item").each(function () { - let novelUrl = loadedCheerio(this).find("a").attr("href"); - if (novelUrl && !(0, isAbsoluteUrl_1.isUrlAbsolute)(novelUrl)) { - novelUrl = baseUrl + novelUrl; - } - if (novelUrl) { - const novelName = loadedCheerio(this).find(".title").text().trim(); - let novelCover = loadedCheerio(this).find("img").attr("src"); - if (novelCover && !(0, isAbsoluteUrl_1.isUrlAbsolute)(novelCover)) { - novelCover = baseUrl + novelCover; - } - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - } - }); - return novels; - }); -}; -exports.popularNovels = popularNovels; -const parseNovelAndChapters = function (novelUrl) { - return __awaiter(this, void 0, void 0, function* () { - const url = novelUrl; - const body = yield (0, fetch_1.fetchApi)(url, {}, pluginId).then((r) => r.text()); - let loadedCheerio = (0, cheerio_1.load)(body); - const novel = { - url, - chapters: [], - }; - novel.name = loadedCheerio("h1").text(); - let novelCover = loadedCheerio(".img > img").attr("src"); - novel.cover = novelCover - ? (0, isAbsoluteUrl_1.isUrlAbsolute)(novelCover) - ? novelCover - : baseUrl + novelCover - : undefined; - novel.summary = loadedCheerio(".description-content").text().trim(); - novel.author = loadedCheerio(".author").text().trim(); - novel.genres = loadedCheerio(".category").text().trim(); - novel.status = loadedCheerio(".status").text().trim(); - loadedCheerio(".chapter").each(function () { - var _a; - let chapterUrl = loadedCheerio(this).find("a").attr("href"); - if (chapterUrl && !(0, isAbsoluteUrl_1.isUrlAbsolute)(chapterUrl)) { - chapterUrl = baseUrl + chapterUrl; - } - if (chapterUrl) { - const chapterName = loadedCheerio(this).find("a").text().trim(); - const releaseDate = null; - const chapter = { - name: chapterName, - releaseTime: releaseDate, - url: chapterUrl, - }; - (_a = novel.chapters) === null || _a === void 0 ? void 0 : _a.push(chapter); - } - }); - return novel; - }); -}; -exports.parseNovelAndChapters = parseNovelAndChapters; -const parseChapter = function (chapterUrl) { - return __awaiter(this, void 0, void 0, function* () { - const body = yield (0, fetch_1.fetchApi)(chapterUrl, {}, pluginId).then((r) => r.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - const chapterText = loadedCheerio(".content").html() || ""; - return chapterText; - }); -}; -exports.parseChapter = parseChapter; -const searchNovels = function (searchTerm) { - return __awaiter(this, void 0, void 0, function* () { - (0, showToast_1.showToast)("Search is not available in this source"); - return []; - }); -}; -exports.searchNovels = searchNovels; -const fetchImage = function (url) { - return __awaiter(this, void 0, void 0, function* () { - const headers = { - Referer: baseUrl, - }; - return yield (0, fetch_1.fetchFile)(url, { headers: headers }); - }); -}; -exports.fetchImage = fetchImage; diff --git a/js/plugins/english/freewebnovel.js b/js/plugins/english/freewebnovel.js deleted file mode 100644 index 71fee28..0000000 --- a/js/plugins/english/freewebnovel.js +++ /dev/null @@ -1,141 +0,0 @@ -"use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.fetchImage = exports.searchNovels = exports.parseChapter = exports.parseNovelAndChapters = exports.popularNovels = exports.icon = exports.version = exports.site = exports.name = exports.id = void 0; -const cheerio_1 = require("cheerio"); -const fetch_1 = require("@libs/fetch"); -exports.id = "FWN.com"; -exports.name = "Web NOVEL"; -exports.site = "https://freewebnovel.com/"; -exports.version = "1.0.0"; -exports.icon = "src/en/freewebnovel/icon.png"; -const baseUrl = exports.site; -const popularNovels = function (page) { - return __awaiter(this, void 0, void 0, function* () { - let url = baseUrl + "completed-novel/" + page; - const result = yield (0, fetch_1.fetchApi)(url); - const body = yield result.text(); - const loadedCheerio = (0, cheerio_1.load)(body); - let novels = []; - loadedCheerio(".li-row").each(function () { - const novelName = loadedCheerio(this).find(".tit").text(); - const novelCover = loadedCheerio(this).find("img").attr("src"); - let novelUrl = "https://freewebnovel.com" + - loadedCheerio(this).find("h3 > a").attr("href"); - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - }); - return novels; - }); -}; -exports.popularNovels = popularNovels; -const parseNovelAndChapters = function (novelUrl) { - return __awaiter(this, void 0, void 0, function* () { - const url = novelUrl; - const result = yield (0, fetch_1.fetchApi)(url); - const body = yield result.text(); - const loadedCheerio = (0, cheerio_1.load)(body); - let novel = { - url, - }; - novel.name = loadedCheerio("h1.tit").text(); - novel.cover = loadedCheerio(".pic > img").attr("src"); - novel.genres = loadedCheerio("[title=Genre]") - .next() - .text() - .replace(/[\t\n]/g, ""); - novel.author = loadedCheerio("[title=Author]") - .next() - .text() - .replace(/[\t\n]/g, ""); - novel.status = loadedCheerio("[title=Status]") - .next() - .text() - .replace(/[\t\n]/g, ""); - let novelSummary = loadedCheerio(".inner").text().trim(); - novel.summary = novelSummary; - let novelChapters = []; - let latestChapter; - loadedCheerio("h3.tit").each(function (res) { - var _a; - if (loadedCheerio(this).find("a").text() === novel.name) { - latestChapter = (_a = loadedCheerio(this) - .next() - .find("span.s3") - .text() - .match(/(\d+)/)) === null || _a === void 0 ? void 0 : _a[0]; - } - }); - let prefixUrl = novelUrl.replace(".html", "/"); - for (let i = 1; i <= parseInt(latestChapter || "0", 10); i++) { - const chapterName = "Chapter " + i; - const releaseDate = null; - let chapterUrl = "chapter-" + i; - chapterUrl = `${prefixUrl}${chapterUrl}.html`; - const chapter = { - name: chapterName, - releaseTime: releaseDate, - url: chapterUrl, - }; - novelChapters.push(chapter); - } - novel.chapters = novelChapters; - return novel; - }); -}; -exports.parseNovelAndChapters = parseNovelAndChapters; -const parseChapter = function (chapterUrl) { - return __awaiter(this, void 0, void 0, function* () { - const url = chapterUrl; - const result = yield (0, fetch_1.fetchApi)(url); - const body = yield result.text(); - const loadedCheerio = (0, cheerio_1.load)(body); - let chapterText = loadedCheerio("div.txt").html(); - return chapterText; - }); -}; -exports.parseChapter = parseChapter; -const searchNovels = function (searchTerm) { - return __awaiter(this, void 0, void 0, function* () { - const url = baseUrl + "search/"; - const formData = { - searchkey: searchTerm, - }; - const result = yield (0, fetch_1.fetchApi)(url, { - method: "POST", - body: JSON.stringify(formData), - }); - const body = yield result.text(); - const loadedCheerio = (0, cheerio_1.load)(body); - let novels = []; - loadedCheerio(".li-row > .li > .con").each(function () { - const novelName = loadedCheerio(this).find(".tit").text(); - const novelCover = loadedCheerio(this) - .find(".pic > a > img") - .attr("data-cfsrc"); - let novelUrl = "https://freewebnovel.com" + - loadedCheerio(this).find("h3 > a").attr("href"); - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - }); - return novels; - }); -}; -exports.searchNovels = searchNovels; -exports.fetchImage = fetch_1.fetchFile; diff --git a/js/plugins/english/lightnovelpub.js b/js/plugins/english/lightnovelpub.js deleted file mode 100644 index b397d5c..0000000 --- a/js/plugins/english/lightnovelpub.js +++ /dev/null @@ -1,171 +0,0 @@ -"use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.fetchImage = exports.searchNovels = exports.parseChapter = exports.parseNovelAndChapters = exports.popularNovels = exports.site = exports.icon = exports.version = exports.name = exports.id = void 0; -const cheerio_1 = require("cheerio"); -const fetch_1 = require("@libs/fetch"); -exports.id = "lightnovelpub"; -exports.name = "LightNovelPub"; -exports.version = "1.0.0"; -exports.icon = "src/en/lightnovelpub/icon.png"; -exports.site = "https://www.lightnovelpub.com/"; -const baseUrl = exports.site; -const pluginId = exports.id; -const headers = { - Accept: "application/json", - "Content-Type": "application/json", -}; -const popularNovels = function (page) { - return __awaiter(this, void 0, void 0, function* () { - const url = `${baseUrl}browse/all/popular/all/${page}`; - const body = yield (0, fetch_1.fetchApi)(url, {}, pluginId).then((r) => r.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - const novels = []; - loadedCheerio(".novel-item.ads").remove(); - loadedCheerio(".novel-item").each(function () { - var _a; - const novelName = loadedCheerio(this) - .find(".novel-title") - .text() - .trim(); - const novelCover = loadedCheerio(this).find("img").attr("data-src"); - const novelUrl = baseUrl + - ((_a = loadedCheerio(this) - .find(".novel-title > a") - .attr("href")) === null || _a === void 0 ? void 0 : _a.substring(1)); - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - }); - return novels; - }); -}; -exports.popularNovels = popularNovels; -const parseNovelAndChapters = function (novelUrl) { - var _a; - return __awaiter(this, void 0, void 0, function* () { - const url = novelUrl; - const body = yield (0, fetch_1.fetchApi)(url, {}, pluginId).then((r) => r.text()); - let loadedCheerio = (0, cheerio_1.load)(body); - const novel = { - url, - chapters: [], - }; - novel.name = loadedCheerio("h1.novel-title").text().trim(); - novel.cover = loadedCheerio("figure.cover > img").attr("data-src"); - novel.genres = ""; - loadedCheerio(".categories > ul > li > a").each(function () { - novel.genres += loadedCheerio(this).text() + ","; - }); - novel.genres = novel.genres.slice(0, -1); - loadedCheerio("div.header-stats > span").each(function () { - if (loadedCheerio(this).find("small").text() === "Status") { - novel.status = loadedCheerio(this).find("strong").text(); - } - }); - novel.author = loadedCheerio(".author > a > span").text(); - novel.summary = loadedCheerio(".summary > .content").text().trim(); - const delay = (ms) => new Promise((res) => setTimeout(res, ms)); - let lastPage = 1; - lastPage = parseInt((_a = loadedCheerio("#novel > header > div.header-body.container > div.novel-info > div.header-stats > span:nth-child(1) > strong") - .text()) === null || _a === void 0 ? void 0 : _a.trim()); - lastPage = Math.ceil(lastPage / 100); - function getChapters() { - return __awaiter(this, void 0, void 0, function* () { - let chapter = []; - for (let i = 1; i <= lastPage; i++) { - const chaptersUrl = `${novelUrl}/chapters/page-${i}`; - const chaptersHtml = yield (0, fetch_1.fetchApi)(chaptersUrl, { headers: headers }, pluginId).then((r) => r.text()); - loadedCheerio = (0, cheerio_1.load)(chaptersHtml); - loadedCheerio(".chapter-list li").each(function () { - var _a; - const chapterName = loadedCheerio(this) - .find(".chapter-title") - .text() - .trim(); - const releaseDate = loadedCheerio(this) - .find(".chapter-update") - .text() - .trim(); - const chapterUrl = baseUrl + - ((_a = loadedCheerio(this) - .find("a") - .attr("href")) === null || _a === void 0 ? void 0 : _a.substring(1)); - chapter.push({ - name: chapterName, - releaseTime: releaseDate, - url: chapterUrl, - }); - }); - yield delay(1000); - } - return chapter; - }); - } - novel.chapters = yield getChapters(); - return novel; - }); -}; -exports.parseNovelAndChapters = parseNovelAndChapters; -const parseChapter = function (chapterUrl) { - return __awaiter(this, void 0, void 0, function* () { - const body = yield (0, fetch_1.fetchApi)(chapterUrl, {}, pluginId).then((r) => r.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - let chapterText = loadedCheerio("#chapter-container").html(); - return chapterText; - }); -}; -exports.parseChapter = parseChapter; -const searchNovels = function (searchTerm) { - return __awaiter(this, void 0, void 0, function* () { - const url = `${baseUrl}lnsearchlive`; - const link = `${baseUrl}search`; - const response = yield (0, fetch_1.fetchApi)(link, {}, pluginId).then((r) => r.text()); - const token = (0, cheerio_1.load)(response); - let verifytoken = token("#novelSearchForm > input").attr("value"); - let formData = new FormData(); - formData.append("inputContent", searchTerm); - const body = yield (0, fetch_1.fetchApi)(url, { - method: "POST", - headers: { LNRequestVerifyToken: verifytoken }, - body: formData, - }, pluginId).then((r) => r.text()); - let loadedCheerio = (0, cheerio_1.load)(body); - let novels = []; - let results = JSON.parse(loadedCheerio("body").text()); - loadedCheerio = (0, cheerio_1.load)(results.resultview); - loadedCheerio(".novel-item").each(function () { - var _a; - const novelName = loadedCheerio(this) - .find("h4.novel-title") - .text() - .trim(); - const novelCover = loadedCheerio(this).find("img").attr("src"); - const novelUrl = baseUrl + ((_a = loadedCheerio(this).find("a").attr("href")) === null || _a === void 0 ? void 0 : _a.substring(1)); - novels.push({ - name: novelName, - url: novelUrl, - cover: novelCover, - }); - }); - return novels; - }); -}; -exports.searchNovels = searchNovels; -const fetchImage = function (url) { - return __awaiter(this, void 0, void 0, function* () { - return yield (0, fetch_1.fetchFile)(url, { headers: headers }); - }); -}; -exports.fetchImage = fetchImage; diff --git a/js/plugins/english/mtlreader.js b/js/plugins/english/mtlreader.js deleted file mode 100644 index 06d7285..0000000 --- a/js/plugins/english/mtlreader.js +++ /dev/null @@ -1,121 +0,0 @@ -"use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.fetchImage = exports.searchNovels = exports.parseChapter = exports.parseNovelAndChapters = exports.popularNovels = exports.site = exports.icon = exports.version = exports.name = exports.id = void 0; -const cheerio_1 = require("cheerio"); -const fetch_1 = require("@libs/fetch"); -exports.id = "mtlreader"; -exports.name = "MTL Reader"; -exports.version = "1.0.0"; -exports.icon = "src/en/mtlreader/icon.png"; -exports.site = "https://mtlreader.com/"; -const pluginId = exports.id; -const baseUrl = exports.site; -const popularNovels = function (page) { - return __awaiter(this, void 0, void 0, function* () { - const url = `${baseUrl}novels?page=${page}`; - const body = yield (0, fetch_1.fetchApi)(url, {}, pluginId).then((r) => r.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - let novels = []; - loadedCheerio(".col-md-4.col-sm-4").each(function () { - const novelName = loadedCheerio(this).find("h5").text(); - const novelCover = loadedCheerio(this).find("img").attr("src"); - const novelUrl = loadedCheerio(this).find("h5 > a").attr("href"); - if (!novelUrl) - return; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - }); - return novels; - }); -}; -exports.popularNovels = popularNovels; -const parseNovelAndChapters = function (novelUrl) { - return __awaiter(this, void 0, void 0, function* () { - const url = novelUrl; - const body = yield (0, fetch_1.fetchApi)(url, {}, pluginId).then((r) => r.text()); - let loadedCheerio = (0, cheerio_1.load)(body); - const novel = { - url, - chapters: [], - }; - novel.name = loadedCheerio(".agent-title").text().trim(); - novel.cover = loadedCheerio(".agent-p-img > img").attr("src"); - novel.summary = loadedCheerio("#editdescription").text().trim(); - novel.author = loadedCheerio("i.fa-user") - .parent() - .text() - .replace("Author: ", "") - .trim(); - let chapter = []; - loadedCheerio("tr.spaceUnder").each(function () { - const chapterName = loadedCheerio(this).find("a").text().trim(); - const releaseDate = null; - const chapterUrl = loadedCheerio(this).find("a").attr("href"); - if (!chapterUrl) - return; - chapter.push({ - name: chapterName, - releaseTime: releaseDate, - url: chapterUrl, - }); - }); - novel.chapters = chapter; - return novel; - }); -}; -exports.parseNovelAndChapters = parseNovelAndChapters; -const parseChapter = function (chapterUrl) { - return __awaiter(this, void 0, void 0, function* () { - const body = yield (0, fetch_1.fetchApi)(chapterUrl, {}, pluginId).then((r) => r.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio(".container ins,script,p.mtlreader").remove(); - const chapterText = loadedCheerio(".container").html(); - return chapterText; - }); -}; -exports.parseChapter = parseChapter; -const searchNovels = function (searchTerm) { - return __awaiter(this, void 0, void 0, function* () { - const url = `${baseUrl}search?input=${searchTerm}`; - const body = yield (0, fetch_1.fetchApi)(url, {}, pluginId).then((r) => r.text()); - let loadedCheerio = (0, cheerio_1.load)(body); - let novels = []; - loadedCheerio(".col-md-4.col-sm-4").each(function () { - const novelName = loadedCheerio(this).find("h5").text(); - const novelCover = loadedCheerio(this).find("img").attr("src"); - const novelUrl = loadedCheerio(this).find("h5 > a").attr("href"); - if (!novelUrl) - return; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - }); - return novels; - }); -}; -exports.searchNovels = searchNovels; -const fetchImage = function (url) { - return __awaiter(this, void 0, void 0, function* () { - const headers = { - Referer: baseUrl, - }; - return yield (0, fetch_1.fetchFile)(url, { headers: headers }); - }); -}; -exports.fetchImage = fetchImage; diff --git a/js/plugins/english/nitroscans.js b/js/plugins/english/nitroscans.js deleted file mode 100644 index 4a9355e..0000000 --- a/js/plugins/english/nitroscans.js +++ /dev/null @@ -1,166 +0,0 @@ -"use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.fetchImage = exports.searchNovels = exports.parseChapter = exports.parseNovelAndChapters = exports.popularNovels = exports.site = exports.icon = exports.version = exports.name = exports.id = void 0; -const cheerio_1 = require("cheerio"); -const fetch_1 = require("@libs/fetch"); -exports.id = "nitroscans"; -exports.name = "Nitroscans"; -exports.version = "1.0.0"; -exports.icon = "src/en/nitroscans/icon.png"; -exports.site = "https://nitroscans.com/"; -const baseUrl = exports.site; -const popularNovels = function (page) { - return __awaiter(this, void 0, void 0, function* () { - const url = baseUrl + "wp-admin/admin-ajax.php"; - let formData = new FormData(); - formData.append("action", "madara_load_more"); - formData.append("page", `${Number(page - 1)}`); - formData.append("template", "madara-core/content/content-archive"); - formData.append("vars[orderby]", "meta_value_num"); - formData.append("vars[post_type]", "wp-manga"); - formData.append("vars[meta_key]", "_wp_manga_views"); - formData.append("vars[wp-manga-genre]", "novels"); - const body = yield (0, fetch_1.fetchApi)(url, { - method: "POST", - body: formData, - }).then((r) => r.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - let novels = []; - loadedCheerio(".page-item-detail").each(function () { - const novelName = loadedCheerio(this).find("h3 > a").text(); - const novelCover = loadedCheerio(this).find("img").attr("data-src"); - const novelUrl = loadedCheerio(this).find("h3 > a").attr("href"); - if (!novelUrl) - return; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - }); - return novels; - }); -}; -exports.popularNovels = popularNovels; -const parseNovelAndChapters = function (novelUrl) { - var _a; - return __awaiter(this, void 0, void 0, function* () { - const url = novelUrl; - const body = yield (0, fetch_1.fetchApi)(url).then((r) => r.text()); - let loadedCheerio = (0, cheerio_1.load)(body); - const novel = { - url, - chapters: [], - }; - loadedCheerio(".manga-title-badges.custom.novel").remove(); - novel.name = loadedCheerio(".post-title > h1").text().trim(); - novel.cover = loadedCheerio(".summary_image") - .find("img") - .attr("data-src"); - novel.summary = (_a = loadedCheerio(".summary__content").text()) === null || _a === void 0 ? void 0 : _a.trim(); - novel.genres = loadedCheerio(".genres-content") - .children("a") - .map((i, el) => loadedCheerio(el).text()) - .toArray() - .join(","); - loadedCheerio(".post-content_item").each(function () { - const detailName = loadedCheerio(this) - .find(".summary-heading") - .text() - .trim(); - const detail = loadedCheerio(this) - .find(".summary-content") - .text() - .trim(); - switch (detailName) { - case "Author(s)": - novel.author = detail; - break; - case "Status": - novel.status = detail.replace(/G/g, "g"); - break; - } - }); - let chapter = []; - let chapterlisturl = novelUrl + "ajax/chapters/"; - const data = yield (0, fetch_1.fetchApi)(chapterlisturl, { method: "POST" }); - const text = yield data.text(); - loadedCheerio = (0, cheerio_1.load)(text); - loadedCheerio(".wp-manga-chapter").each(function () { - const chapterName = loadedCheerio(this).find("a").text().trim(); - const releaseDate = loadedCheerio(this).find("span").text().trim(); - const chapterUrl = loadedCheerio(this).find("a").attr("href"); - if (!chapterUrl) - return; - chapter.push({ - name: chapterName, - releaseTime: releaseDate, - url: chapterUrl, - }); - }); - novel.chapters = chapter.reverse(); - return novel; - }); -}; -exports.parseNovelAndChapters = parseNovelAndChapters; -const parseChapter = function (chapterUrl) { - return __awaiter(this, void 0, void 0, function* () { - const body = yield (0, fetch_1.fetchApi)(chapterUrl).then((r) => r.text()); - let loadedCheerio = (0, cheerio_1.load)(body); - const chapterText = loadedCheerio(".text-left").html(); - return chapterText; - }); -}; -exports.parseChapter = parseChapter; -const searchNovels = function (searchTerm) { - return __awaiter(this, void 0, void 0, function* () { - const url = baseUrl + "wp-admin/admin-ajax.php"; - let formData = new FormData(); - formData.append("action", "madara_load_more"); - formData.append("page", `${Number(1 - 1)}`); - formData.append("template", "madara-core/content/content-search"); - formData.append("vars[s]", searchTerm); - formData.append("vars[post_type]", "wp-manga"); - formData.append("vars[wp-manga-genre]", "novels"); - const body = yield (0, fetch_1.fetchApi)(url, { - method: "POST", - body: formData, - }).then((r) => r.text()); - let loadedCheerio = (0, cheerio_1.load)(body); - let novels = []; - loadedCheerio(".c-tabs-item__content").each(function () { - const novelName = loadedCheerio(this).find("h3 > a").text(); - const novelCover = loadedCheerio(this).find("img").attr("data-src"); - const novelUrl = loadedCheerio(this).find("h3 > a").attr("href"); - if (!novelUrl) - return; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - }); - return novels; - }); -}; -exports.searchNovels = searchNovels; -const fetchImage = function (url) { - return __awaiter(this, void 0, void 0, function* () { - const headers = { - Referer: baseUrl, - }; - return yield (0, fetch_1.fetchFile)(url, { headers: headers }); - }); -}; -exports.fetchImage = fetchImage; diff --git a/js/plugins/english/nobleMTL.js b/js/plugins/english/nobleMTL.js deleted file mode 100644 index 5e8a120..0000000 --- a/js/plugins/english/nobleMTL.js +++ /dev/null @@ -1,299 +0,0 @@ -"use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.filters = exports.fetchImage = exports.searchNovels = exports.parseChapter = exports.parseNovelAndChapters = exports.popularNovels = exports.site = exports.icon = exports.version = exports.name = exports.id = void 0; -const cheerio_1 = require("cheerio"); -const fetch_1 = require("@libs/fetch"); -const filterInputs_1 = require("@libs/filterInputs"); -exports.id = "NobleMTL"; -exports.name = "NobleMTL"; -exports.version = "1.0.0"; -exports.icon = "src/en/noblemtl/icon.png"; -exports.site = "https://www.noblemtl.com/"; -const popularNovels = function (page, { filters }) { - var _a, _b; - return __awaiter(this, void 0, void 0, function* () { - let link = `${exports.site}series/?page=${page}`; - if ((_a = filters === null || filters === void 0 ? void 0 : filters.genres) === null || _a === void 0 ? void 0 : _a.length) { - if (Array.isArray(filters.genres)) - link += filters.genres.map((i) => `&genre[]=${i}`).join(""); - } - if ((_b = filters === null || filters === void 0 ? void 0 : filters.type) === null || _b === void 0 ? void 0 : _b.length) { - if (Array.isArray(filters.type)) - link += filters.type.map((i) => `&lang[]=${i}`).join(""); - } - link += "&status=" + ((filters === null || filters === void 0 ? void 0 : filters.status) ? filters === null || filters === void 0 ? void 0 : filters.status : ""); - link += "&order=" + ((filters === null || filters === void 0 ? void 0 : filters.order) ? filters === null || filters === void 0 ? void 0 : filters.order : "popular"); - const body = yield (0, fetch_1.fetchApi)(link).then((result) => result.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - const novels = []; - loadedCheerio("article.bs").each(function () { - const novelName = loadedCheerio(this).find(".ntitle").text().trim(); - let image = loadedCheerio(this).find("img"); - const novelCover = image.attr("data-src") || image.attr("src"); - const novelUrl = loadedCheerio(this).find("a").attr("href"); - if (!novelUrl) - return; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - }); - return novels; - }); -}; -exports.popularNovels = popularNovels; -const parseNovelAndChapters = function parseNovelAndChapters(novelUrl) { - return __awaiter(this, void 0, void 0, function* () { - const url = novelUrl; - const result = yield (0, fetch_1.fetchApi)(url); - const body = yield result.text(); - let loadedCheerio = (0, cheerio_1.load)(body); - const novel = { - url, - chapters: [], - }; - novel.name = loadedCheerio(".entry-title").text(); - novel.cover = - loadedCheerio("img.wp-post-image").attr("data-src") || - loadedCheerio("img.wp-post-image").attr("src"); - loadedCheerio("div.spe > span").each(function () { - const detailName = loadedCheerio(this).find("b").text().trim(); - const detail = loadedCheerio(this) - .find("b") - .remove() - .end() - .text() - .trim(); - switch (detailName) { - case "المؤلف:": - case "Yazar:": - case "Autor:": - case "Author:": - novel.author = detail; - break; - case "Status:": - case "Seviye:": - novel.status = detail; - break; - } - }); - novel.genres = loadedCheerio(".genxed") - .text() - .trim() - .replace(/\s/g, ","); - loadedCheerio('div[itemprop="description"] h3,p.a,strong').remove(); - novel.summary = loadedCheerio('div[itemprop="description"]') - .find("br") - .replaceWith("\n") - .end() - .text(); - let chapter = []; - loadedCheerio(".eplister") - .find("li") - .each(function () { - const chapterName = loadedCheerio(this).find(".epl-num").text() + - " - " + - loadedCheerio(this).find(".epl-title").text(); - const releaseDate = loadedCheerio(this) - .find(".epl-date") - .text() - .trim(); - const chapterUrl = loadedCheerio(this).find("a").attr("href"); - if (!chapterUrl) - return; - chapter.push({ - name: chapterName, - releaseTime: releaseDate, - url: chapterUrl, - }); - }); - novel.chapters = chapter.reverse(); - return novel; - }); -}; -exports.parseNovelAndChapters = parseNovelAndChapters; -const parseChapter = function (chapterUrl) { - return __awaiter(this, void 0, void 0, function* () { - const result = yield (0, fetch_1.fetchApi)(chapterUrl); - const body = yield result.text(); - const loadedCheerio = (0, cheerio_1.load)(body); - let chapterText = loadedCheerio("div.epcontent").html(); - return chapterText; - }); -}; -exports.parseChapter = parseChapter; -const searchNovels = function (searchTerm) { - return __awaiter(this, void 0, void 0, function* () { - const url = `${exports.site}?s=${searchTerm}`; - const result = yield (0, fetch_1.fetchApi)(url); - const body = yield result.text(); - const loadedCheerio = (0, cheerio_1.load)(body); - const novels = []; - loadedCheerio("article.bs").each(function () { - const novelName = loadedCheerio(this).find(".ntitle").text().trim(); - const novelCover = loadedCheerio(this).find("img").attr("src"); - const novelUrl = loadedCheerio(this).find("a").attr("href"); - if (!novelUrl) - return; - novels.push({ - name: novelName, - url: novelUrl, - cover: novelCover, - }); - }); - return novels; - }); -}; -exports.searchNovels = searchNovels; -const fetchImage = function (url) { - return __awaiter(this, void 0, void 0, function* () { - const headers = { - Referer: exports.site, - }; - return yield (0, fetch_1.fetchFile)(url, { headers: headers }); - }); -}; -exports.fetchImage = fetchImage; -exports.filters = [ - { - key: "order", - label: "Sort By", - values: [ - { label: "Default", value: "" }, - { label: "A-Z", value: "title" }, - { label: "Z-A", value: "titlereverse" }, - { label: "Latest Update", value: "update" }, - { label: "Latest Added", value: "latest" }, - { label: "Popular", value: "popular" }, - ], - inputType: filterInputs_1.FilterInputs.Picker, - }, - { - key: "status", - label: "Status", - values: [ - { label: "All", value: "" }, - { label: "Ongoing", value: "ongoing" }, - { label: "Hiatus", value: "hiatus" }, - { label: "Completed", value: "completed" }, - ], - inputType: filterInputs_1.FilterInputs.Picker, - }, - { - key: "type", - label: "Type", - values: [ - { label: "Chinese novel", value: "chinese-novel" }, - { label: "habyeol", value: "habyeol" }, - { label: "korean novel", value: "korean-novel" }, - { label: "Web Novel", value: "web-novel" }, - { label: "삼심", value: "%ec%82%bc%ec%8b%ac" }, - { label: "호곡", value: "%ed%98%b8%ea%b3%a1" }, - ], - inputType: filterInputs_1.FilterInputs.Checkbox, - }, - { - key: "genres", - label: "Genres", - values: [ - { label: "A.I", value: "a.i" }, - { label: "Academy", value: "academy" }, - { label: "Action", value: "action" }, - { label: "Adult", value: "adult" }, - { label: "Adventure", value: "adventure" }, - { label: "Alternative History", value: "alternative-history" }, - { label: "Another World", value: "another-world" }, - { label: "Apocalypse", value: "apocalypse" }, - { label: "Bromance", value: "bromance" }, - { label: "Comedy", value: "comedy" }, - { label: "Dark fantasy", value: "dark-fantasy" }, - { label: "Demons", value: "demons" }, - { label: "Drama", value: "drama" }, - { label: "Dystopia", value: "dystopia" }, - { label: "Ecchi", value: "ecchi" }, - { label: "Entertainment", value: "entertainment" }, - { label: "Exhaustion", value: "exhaustion" }, - { label: "Fanfiction", value: "fanfiction" }, - { label: "fantasy", value: "fantasy" }, - { label: "finance", value: "finance" }, - { label: "Full color", value: "full-color" }, - { label: "Game", value: "game" }, - { label: "Gender Bender", value: "gender-bender" }, - { label: "Genius", value: "genius" }, - { label: "Harem", value: "harem" }, - { label: "Hero", value: "hero" }, - { label: "Historical", value: "historical" }, - { label: "Hunter", value: "hunter" }, - { label: "korean novel", value: "korean-novel" }, - { label: "Light Novel", value: "light-novel" }, - { - label: "List Adventure Manga Genres", - value: "list-adventure-manga-genres", - }, - { label: "Long Strip", value: "long-strip" }, - { label: "Love comedy", value: "love-comedy" }, - { label: "magic", value: "magic" }, - { label: "Manhua", value: "manhua" }, - { label: "Martial Arts", value: "martial-arts" }, - { label: "Mature", value: "mature" }, - { label: "Medieval", value: "medieval" }, - { label: "Misunderstanding", value: "misunderstanding" }, - { label: "Modern", value: "modern" }, - { label: "modern fantasy", value: "modern-fantasy" }, - { label: "music", value: "music" }, - { label: "Mystery", value: "mystery" }, - { label: "Necromancy", value: "necromancy" }, - { label: "No Romance", value: "no-romance" }, - { label: "NTL", value: "ntl" }, - { label: "o", value: "o" }, - { label: "Obsession", value: "obsession" }, - { label: "Politics", value: "politics" }, - { label: "Possession", value: "possession" }, - { label: "Programming", value: "programming" }, - { label: "Psychological", value: "psychological" }, - { label: "Pure Love", value: "pure-love" }, - { label: "Redemption", value: "redemption" }, - { label: "Regression", value: "regression" }, - { label: "Regret", value: "regret" }, - { label: "Reincarnation", value: "reincarnation" }, - { label: "Revenge", value: "revenge" }, - { label: "Romance", value: "romance" }, - { label: "Romance Fanrasy", value: "romance-fanrasy" }, - { label: "Salvation", value: "salvation" }, - { label: "School Life", value: "school-life" }, - { label: "Sci-fi", value: "sci-fi" }, - { label: "Science fiction", value: "science-fiction" }, - { label: "Seinen", value: "seinen" }, - { label: "Shounen", value: "shounen" }, - { label: "Slice of Life", value: "slice-of-life" }, - { label: "Soft yandere", value: "soft-yandere" }, - { label: "Sports", value: "sports" }, - { label: "Supernatural", value: "supernatural" }, - { label: "Survival", value: "survival" }, - { label: "system", value: "system" }, - { label: "Time limit", value: "time-limit" }, - { label: "Tragedy", value: "tragedy" }, - { label: "Transmigration", value: "transmigration" }, - { label: "TS", value: "ts" }, - { label: "Tsundere", value: "tsundere" }, - { label: "Unique", value: "unique" }, - { label: "Wholesome", value: "wholesome" }, - { label: "Wuxia", value: "wuxia" }, - { label: "Xuanhuan", value: "xuanhuan" }, - { label: "Yandere", value: "yandere" }, - { label: "Yuri", value: "yuri" }, - ], - inputType: filterInputs_1.FilterInputs.Checkbox, - }, -]; diff --git a/js/plugins/english/novelforest.js b/js/plugins/english/novelforest.js deleted file mode 100644 index 70fa2d3..0000000 --- a/js/plugins/english/novelforest.js +++ /dev/null @@ -1,126 +0,0 @@ -"use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.fetchImage = exports.searchNovels = exports.parseChapter = exports.parseNovelAndChapters = exports.popularNovels = exports.site = exports.icon = exports.version = exports.name = exports.id = void 0; -const fetch_1 = require("@libs/fetch"); -const cheerio_1 = require("cheerio"); -exports.id = "novelforest"; -exports.name = "Novel Forest (Broken)"; -exports.version = "1.0.0"; -exports.icon = "src/en/novelforest/icon.png"; -exports.site = "https://novelforest.com/"; -const pluginId = exports.id; -const baseUrl = exports.site; -const popularNovels = function (page) { - return __awaiter(this, void 0, void 0, function* () { - const url = `${baseUrl}popular?page=${page}`; - const body = yield (0, fetch_1.fetchApi)(url, {}, pluginId).then((r) => r.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - let novels = []; - loadedCheerio(".book-item").each(function () { - var _a; - const novelName = loadedCheerio(this).find(".title").text(); - const novelCover = "https:" + loadedCheerio(this).find("img").attr("data-src"); - const novelUrl = baseUrl + - ((_a = loadedCheerio(this).find(".title a").attr("href")) === null || _a === void 0 ? void 0 : _a.substring(1)); - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - }); - return novels; - }); -}; -exports.popularNovels = popularNovels; -const parseNovelAndChapters = (novelUrl) => __awaiter(void 0, void 0, void 0, function* () { - var _a, _b, _c; - const url = novelUrl; - const body = yield (0, fetch_1.fetchApi)(url, {}, pluginId).then((r) => r.text()); - let loadedCheerio = (0, cheerio_1.load)(body); - const novel = { - url, - chapters: [], - }; - novel.name = loadedCheerio(".name h1").text().trim(); - novel.cover = "https:" + loadedCheerio(".img-cover img").attr("data-src"); - novel.summary = loadedCheerio("body > div.layout > div.main-container.book-details > div > div.row.no-gutters > div.col-lg-8 > div.mt-1 > div.section.box.mt-1.summary > div.section-body > p.content") - .text() - .trim(); - novel.author = (_a = loadedCheerio("body > div.layout > div.main-container.book-details > div > div.row.no-gutters > div.col-lg-8 > div.book-info > div.detail > div.meta.box.mt-1.p-10 > p:nth-child(1) > a > span") - .text()) === null || _a === void 0 ? void 0 : _a.trim(); - novel.status = (_b = loadedCheerio("body > div.layout > div.main-container.book-details > div > div.row.no-gutters > div.col-lg-8 > div.book-info > div.detail > div.meta.box.mt-1.p-10 > p:nth-child(2) > a > span") - .text()) === null || _b === void 0 ? void 0 : _b.trim(); - novel.genres = (_c = loadedCheerio("body > div.layout > div.main-container.book-details > div > div.row.no-gutters > div.col-lg-8 > div.book-info > div.detail > div.meta.box.mt-1.p-10 > p:nth-child(3)") - .text()) === null || _c === void 0 ? void 0 : _c.replace("Genres :", "").replace(/[\s\n]+/g, " ").trim(); - let chapter = []; - const chaptersUrl = novelUrl.replace(baseUrl, "https://novelforest.com/api/novels/") + - "/chapters?source=detail"; - const chaptersRequest = yield fetch(chaptersUrl); - const chaptersHtml = yield chaptersRequest.text(); - loadedCheerio = (0, cheerio_1.load)(chaptersHtml); - loadedCheerio("li").each(function () { - var _a; - const chapterName = loadedCheerio(this) - .find(".chapter-title") - .text() - .trim(); - const releaseDate = loadedCheerio(this) - .find(".chapter-update") - .text() - .trim(); - const chapterUrl = baseUrl + ((_a = loadedCheerio(this).find("a").attr("href")) === null || _a === void 0 ? void 0 : _a.substring(1)); - chapter.push({ - name: chapterName, - releaseTime: releaseDate, - url: chapterUrl, - }); - }); - novel.chapters = chapter; - return novel; -}); -exports.parseNovelAndChapters = parseNovelAndChapters; -const parseChapter = function (chapterUrl) { - return __awaiter(this, void 0, void 0, function* () { - const body = yield (0, fetch_1.fetchApi)(chapterUrl, {}, pluginId).then((r) => r.text()); - let loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio("#listen-chapter").remove(); - loadedCheerio("#google_translate_element").remove(); - const chapterText = loadedCheerio(".chapter__content").html(); - return chapterText; - }); -}; -exports.parseChapter = parseChapter; -const searchNovels = function (searchTerm) { - return __awaiter(this, void 0, void 0, function* () { - const url = `${baseUrl}search?q=${searchTerm}`; - const body = yield (0, fetch_1.fetchApi)(url, {}, pluginId).then((r) => r.text()); - let loadedCheerio = (0, cheerio_1.load)(body); - let novels = []; - loadedCheerio(".book-item").each(function () { - var _a; - const novelName = loadedCheerio(this).find(".title").text(); - const novelCover = "https:" + loadedCheerio(this).find("img").attr("data-src"); - const novelUrl = baseUrl + - ((_a = loadedCheerio(this).find(".title a").attr("href")) === null || _a === void 0 ? void 0 : _a.substring(1)); - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - }); - return novels; - }); -}; -exports.searchNovels = searchNovels; -exports.fetchImage = fetch_1.fetchFile; diff --git a/js/plugins/english/novelfull.js b/js/plugins/english/novelfull.js deleted file mode 100644 index 0022bbe..0000000 --- a/js/plugins/english/novelfull.js +++ /dev/null @@ -1,147 +0,0 @@ -"use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.fetchImage = exports.searchNovels = exports.parseChapter = exports.parseNovelAndChapters = exports.popularNovels = exports.site = exports.icon = exports.version = exports.name = exports.id = void 0; -const cheerio_1 = require("cheerio"); -const fetch_1 = require("@libs/fetch"); -exports.id = "novelfull"; -exports.name = "NovelFull"; -exports.version = "1.0.0"; -exports.icon = "src/en/novelfull/icon.png"; -exports.site = "https://novelfull.com/"; -const baseUrl = exports.site; -const popularNovels = function (page) { - return __awaiter(this, void 0, void 0, function* () { - const url = `${baseUrl}most-popular?page=${page}`; - const result = yield (0, fetch_1.fetchApi)(url); - const body = yield result.text(); - const loadedCheerio = (0, cheerio_1.load)(body); - let novels = []; - loadedCheerio(".col-truyen-main .list-truyen .row").each(function () { - var _a, _b; - const novelName = loadedCheerio(this) - .find("h3.truyen-title > a") - .text(); - const novelCover = baseUrl + ((_a = loadedCheerio(this).find("img").attr("src")) === null || _a === void 0 ? void 0 : _a.slice(1)); - const novelUrl = baseUrl + - ((_b = loadedCheerio(this) - .find("h3.truyen-title > a") - .attr("href")) === null || _b === void 0 ? void 0 : _b.slice(1)); - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - }); - return novels; - }); -}; -exports.popularNovels = popularNovels; -const parseNovelAndChapters = function (novelUrl) { - return __awaiter(this, void 0, void 0, function* () { - const url = novelUrl; - const result = yield (0, fetch_1.fetchApi)(url); - const body = yield result.text(); - let loadedCheerio = (0, cheerio_1.load)(body); - const novel = { - url, - chapters: [], - }; - novel.name = loadedCheerio("div.book > img").attr("alt"); - novel.cover = baseUrl + loadedCheerio("div.book > img").attr("src"); - novel.summary = loadedCheerio("div.desc-text").text().trim(); - novel.author = loadedCheerio('h3:contains("Author")') - .parent() - .contents() - .text() - .replace("Author:", ""); - novel.genres = loadedCheerio('h3:contains("Genre")') - .siblings() - .map((i, el) => loadedCheerio(el).text()) - .toArray() - .join(","); - novel.status = loadedCheerio('h3:contains("Status")').next().text(); - const novelId = loadedCheerio("#rating").attr("data-novel-id"); - function getChapters(id) { - return __awaiter(this, void 0, void 0, function* () { - const chapterListUrl = baseUrl + "ajax/chapter-option?novelId=" + id; - const data = yield (0, fetch_1.fetchApi)(chapterListUrl); - const chapterlist = yield data.text(); - loadedCheerio = (0, cheerio_1.load)(chapterlist); - let chapter = []; - loadedCheerio("select > option").each(function () { - var _a; - const chapterName = loadedCheerio(this).text(); - const releaseDate = null; - const chapterUrl = baseUrl + ((_a = loadedCheerio(this).attr("value")) === null || _a === void 0 ? void 0 : _a.slice(1)); - chapter.push({ - name: chapterName, - releaseTime: releaseDate, - url: chapterUrl, - }); - }); - return chapter; - }); - } - novel.chapters = yield getChapters(novelId); - return novel; - }); -}; -exports.parseNovelAndChapters = parseNovelAndChapters; -const parseChapter = function (chapterUrl) { - return __awaiter(this, void 0, void 0, function* () { - const result = yield (0, fetch_1.fetchApi)(chapterUrl); - const body = yield result.text(); - const loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio("#chapter-content div.ads").remove(); - let chapterText = loadedCheerio("#chapter-content").html(); - return chapterText; - }); -}; -exports.parseChapter = parseChapter; -const searchNovels = function (searchTerm) { - return __awaiter(this, void 0, void 0, function* () { - const searchUrl = `${baseUrl}search?keyword=${searchTerm}`; - const result = yield (0, fetch_1.fetchApi)(searchUrl); - const body = yield result.text(); - const loadedCheerio = (0, cheerio_1.load)(body); - let novels = []; - loadedCheerio(".col-truyen-main .list-truyen .row").each(function () { - var _a, _b; - const novelName = loadedCheerio(this) - .find("h3.truyen-title > a") - .text(); - const novelCover = baseUrl + ((_a = loadedCheerio(this).find("img").attr("src")) === null || _a === void 0 ? void 0 : _a.slice(1)); - const novelUrl = baseUrl + - ((_b = loadedCheerio(this) - .find("h3.truyen-title > a") - .attr("href")) === null || _b === void 0 ? void 0 : _b.slice(1)); - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - }); - return novels; - }); -}; -exports.searchNovels = searchNovels; -const fetchImage = function (url) { - return __awaiter(this, void 0, void 0, function* () { - const headers = { - Referer: baseUrl, - }; - return yield (0, fetch_1.fetchFile)(url, { headers: headers }); - }); -}; -exports.fetchImage = fetchImage; diff --git a/js/plugins/english/novelhold.js b/js/plugins/english/novelhold.js deleted file mode 100644 index 0e10088..0000000 --- a/js/plugins/english/novelhold.js +++ /dev/null @@ -1,132 +0,0 @@ -"use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.fetchImage = exports.searchNovels = exports.parseChapter = exports.parseNovelAndChapters = exports.popularNovels = exports.site = exports.icon = exports.version = exports.name = exports.id = void 0; -const cheerio_1 = require("cheerio"); -const fetch_1 = require("@libs/fetch"); -exports.id = "novelhold"; -exports.name = "Novel Hold"; -exports.version = "1.0.0"; -exports.icon = "src/en/novelhold/icon.png"; -exports.site = "https://novelhold.com/"; -const baseUrl = exports.site; -const popularNovels = function (page) { - return __awaiter(this, void 0, void 0, function* () { - const url = `${baseUrl}all-${page}.html`; - const body = yield (0, fetch_1.fetchApi)(url).then((r) => r.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - let novels = []; - loadedCheerio("#article_list_content > li").each(function () { - var _a; - const novelName = loadedCheerio(this) - .find("h3") - .text() - .replace(/\t+/g, "") - .replace(/\n/g, " "); - const novelCover = loadedCheerio(this).find("img").attr("data-src"); - const novelUrl = baseUrl + ((_a = loadedCheerio(this).find("a").attr("href")) === null || _a === void 0 ? void 0 : _a.slice(1)); - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - }); - return novels; - }); -}; -exports.popularNovels = popularNovels; -const parseNovelAndChapters = function (novelUrl) { - var _a; - return __awaiter(this, void 0, void 0, function* () { - const url = novelUrl; - const body = yield (0, fetch_1.fetchApi)(url).then((r) => r.text()); - let loadedCheerio = (0, cheerio_1.load)(body); - const novel = { - url, - chapters: [], - }; - novel.name = loadedCheerio(".booknav2 > h1").text(); - novel.cover = loadedCheerio('meta[property="og:image"]').attr("content"); - novel.summary = loadedCheerio(".navtxt").text().trim(); - novel.author = loadedCheerio('p:contains("Author")') - .text() - .replace("Author:", "") - .trim(); - novel.status = loadedCheerio('p:contains("Status")') - .text() - .replace("Status:", "") - .replace("Active", "Ongoing") - .trim(); - novel.genres = (_a = loadedCheerio('p:contains("Genre")') - .text()) === null || _a === void 0 ? void 0 : _a.replace("Genre:", "").trim(); - let chapter = []; - loadedCheerio("ul.chapterlist > li").each(function () { - var _a; - const chapterName = loadedCheerio(this).find("a").text().trim(); - const releaseDate = null; - const chapterUrl = baseUrl + ((_a = loadedCheerio(this).find("a").attr("href")) === null || _a === void 0 ? void 0 : _a.slice(1)); - chapter.push({ - name: chapterName, - releaseTime: releaseDate, - url: chapterUrl, - }); - }); - novel.chapters = chapter; - console.log(novel); - return novel; - }); -}; -exports.parseNovelAndChapters = parseNovelAndChapters; -const parseChapter = function (chapterUrl) { - return __awaiter(this, void 0, void 0, function* () { - const body = yield (0, fetch_1.fetchApi)(chapterUrl).then((r) => r.text()); - let loadedCheerio = (0, cheerio_1.load)(body); - const chapterText = loadedCheerio(".content").html(); - return chapterText; - }); -}; -exports.parseChapter = parseChapter; -const searchNovels = function (searchTerm) { - return __awaiter(this, void 0, void 0, function* () { - const url = `${baseUrl}index.php?s=so&module=book&keyword=${searchTerm}`; - const body = yield (0, fetch_1.fetchApi)(url).then((r) => r.text()); - let loadedCheerio = (0, cheerio_1.load)(body); - let novels = []; - loadedCheerio("#article_list_content > li").each(function () { - var _a; - const novelName = loadedCheerio(this) - .find("h3") - .text() - .replace(/\t+/g, "") - .replace(/\n/g, " "); - const novelCover = loadedCheerio(this).find("img").attr("data-src"); - const novelUrl = baseUrl + ((_a = loadedCheerio(this).find("a").attr("href")) === null || _a === void 0 ? void 0 : _a.slice(1)); - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - }); - return novels; - }); -}; -exports.searchNovels = searchNovels; -const fetchImage = function (url) { - return __awaiter(this, void 0, void 0, function* () { - const headers = { - Referer: baseUrl, - }; - return yield (0, fetch_1.fetchFile)(url, { headers: headers }); - }); -}; -exports.fetchImage = fetchImage; diff --git a/js/plugins/english/novelpub.js b/js/plugins/english/novelpub.js deleted file mode 100644 index 8266f3b..0000000 --- a/js/plugins/english/novelpub.js +++ /dev/null @@ -1,152 +0,0 @@ -"use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.fetchImage = exports.searchNovels = exports.parseChapter = exports.parseNovelAndChapters = exports.popularNovels = exports.icon = exports.version = exports.site = exports.name = exports.id = void 0; -const cheerio_1 = require("cheerio"); -const fetch_1 = require("@libs/fetch"); -exports.id = "novelpub.com"; -exports.name = "NovelPub"; -exports.site = "https://www.novelpub.com/"; -exports.version = "1.0.0"; -exports.icon = "src/en/novelpub/icon.png"; -const baseUrl = exports.site; -const headers = { - Accept: "application/json", - "Content-Type": "application/json", - "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36", -}; -const popularNovels = function (page) { - return __awaiter(this, void 0, void 0, function* () { - let url = baseUrl + "browse/all/popular/all/" + page; - const result = yield (0, fetch_1.fetchApi)(url, { method: "GET", headers }); - const body = yield result.text(); - const loadedCheerio = (0, cheerio_1.load)(body); - let novels = []; - loadedCheerio(".novel-item.ads").remove(); - loadedCheerio(".novel-item").each(function () { - var _a; - const novelName = loadedCheerio(this) - .find(".novel-title") - .text() - .trim(); - const novelCover = loadedCheerio(this).find("img").attr("data-src"); - const novelUrl = baseUrl + - ((_a = loadedCheerio(this) - .find(".novel-title > a") - .attr("href")) === null || _a === void 0 ? void 0 : _a.substring(1)); - const novel = { name: novelName, cover: novelCover, url: novelUrl }; - novels.push(novel); - }); - return novels; - }); -}; -exports.popularNovels = popularNovels; -const parseNovelAndChapters = function (novelUrl) { - var _a, _b; - return __awaiter(this, void 0, void 0, function* () { - const url = novelUrl; - const result = yield (0, fetch_1.fetchApi)(url, { method: "GET", headers }); - const body = yield result.text(); - let loadedCheerio = (0, cheerio_1.load)(body); - let novel = { url, genres: "" }; - novel.name = loadedCheerio("h1.novel-title").text().trim(); - novel.cover = loadedCheerio("figure.cover > img").attr("data-src"); - loadedCheerio("div.categories > ul > li").each(function () { - novel.genres += - loadedCheerio(this) - .text() - .replace(/[\t\n]/g, "") + ","; - }); - loadedCheerio("div.header-stats > span").each(function () { - if (loadedCheerio(this).find("small").text() === "Status") { - novel.status = loadedCheerio(this).find("strong").text(); - } - }); - novel.genres = (_a = novel.genres) === null || _a === void 0 ? void 0 : _a.slice(0, -1); - novel.author = loadedCheerio(".author > a > span").text(); - novel.summary = loadedCheerio(".summary > .content").text().trim(); - const delay = (ms) => new Promise((res) => setTimeout(res, ms)); - let lastPage = 1; - lastPage = parseInt((_b = loadedCheerio("#novel > header > div.header-body.container > div.novel-info > div.header-stats > span:nth-child(1) > strong") - .text()) === null || _b === void 0 ? void 0 : _b.trim()); - lastPage = Math.ceil(lastPage / 100); - const getChapters = () => __awaiter(this, void 0, void 0, function* () { - let novelChapters = []; - for (let i = 1; i <= lastPage; i++) { - const chaptersUrl = `${novelUrl}/chapters/page-${i}`; - const chaptersRequest = yield (0, fetch_1.fetchApi)(chaptersUrl, { - headers, - }); - const chaptersHtml = yield chaptersRequest.text(); - loadedCheerio = (0, cheerio_1.load)(chaptersHtml); - loadedCheerio(".chapter-list li").each(function () { - var _a; - const chapterName = loadedCheerio(this) - .find(".chapter-title") - .text() - .trim(); - const releaseDate = loadedCheerio(this) - .find(".chapter-update") - .text() - .trim(); - const chapterUrl = baseUrl + - ((_a = loadedCheerio(this) - .find("a") - .attr("href")) === null || _a === void 0 ? void 0 : _a.substring(1)); - novelChapters.push({ - name: chapterName, - releaseTime: releaseDate, - url: chapterUrl, - }); - }); - yield delay(1000); - } - return novelChapters; - }); - novel.chapters = yield getChapters(); - return novel; - }); -}; -exports.parseNovelAndChapters = parseNovelAndChapters; -const parseChapter = function (chapterUrl) { - return __awaiter(this, void 0, void 0, function* () { - const url = chapterUrl; - const result = yield (0, fetch_1.fetchApi)(url, { method: "GET", headers }); - const body = yield result.text(); - const loadedCheerio = (0, cheerio_1.load)(body); - const chapterText = loadedCheerio("#chapter-container").html(); - return chapterText; - }); -}; -exports.parseChapter = parseChapter; -// They have API to search, pls update it, im quite lazy xD -const searchNovels = function (searchTerm) { - return __awaiter(this, void 0, void 0, function* () { - const url = `${baseUrl}lnwsearchlive?inputContent=${searchTerm}`; - const result = yield (0, fetch_1.fetchApi)(url, { method: "GET", headers }); - const body = yield result.text(); - let loadedCheerio = (0, cheerio_1.load)(body); - let novels = []; - // let results = JSON.parse(loadedCheerio('body').text()); - // loadedCheerio = load(results.resultview); - // loadedCheerio('.novel-item').each(function () { - // const novelName = loadedCheerio(this).find('.novel-title').text().trim(); - // const novelCover = loadedCheerio(this).find('img').attr('src'); - // const novelUrl = - // baseUrl + loadedCheerio(this).find('a').attr('href').substring(1); - // const novel = { name: novelName, cover: novelCover, url: novelUrl }; - // novels.push(novel); - // }); - return novels; - }); -}; -exports.searchNovels = searchNovels; -exports.fetchImage = fetch_1.fetchFile; diff --git a/js/plugins/english/pandaMTL.js b/js/plugins/english/pandaMTL.js deleted file mode 100644 index 720a6ee..0000000 --- a/js/plugins/english/pandaMTL.js +++ /dev/null @@ -1,220 +0,0 @@ -"use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.filters = exports.fetchImage = exports.searchNovels = exports.parseChapter = exports.parseNovelAndChapters = exports.popularNovels = exports.site = exports.icon = exports.version = exports.name = exports.id = void 0; -const cheerio_1 = require("cheerio"); -const fetch_1 = require("@libs/fetch"); -const filterInputs_1 = require("@libs/filterInputs"); -exports.id = "PandaMTL"; -exports.name = "PandaMTL"; -exports.version = "1.0.0"; -exports.icon = "src/en/wordpress/icon.png"; -exports.site = "https://www.pandamtl.com/"; -const pluginId = exports.id; -const baseUrl = exports.site; -const popularNovels = function (page, { filters }) { - return __awaiter(this, void 0, void 0, function* () { - let link = `${baseUrl}series/?page=${page}`; - if (filters) { - if (Array.isArray(filters.genres) && filters.genres.length) { - link += filters.genres.map((i) => `&genre[]=${i}`).join(""); - } - if (Array.isArray(filters.type) && filters.type.length) { - link += filters.type.map((i) => `&lang[]=${i}`).join(""); - } - } - link += "&status=" + ((filters === null || filters === void 0 ? void 0 : filters.status) ? filters === null || filters === void 0 ? void 0 : filters.status : ""); - link += "&order=" + ((filters === null || filters === void 0 ? void 0 : filters.order) ? filters === null || filters === void 0 ? void 0 : filters.order : "popular"); - const body = yield (0, fetch_1.fetchApi)(link, {}, pluginId).then((result) => result.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - const novels = []; - loadedCheerio("article.maindet").each(function () { - const novelName = loadedCheerio(this).find("h2").text(); - let image = loadedCheerio(this).find("img"); - const novelCover = image.attr("data-src") || image.attr("src"); - const novelUrl = loadedCheerio(this).find("h2 a").attr("href"); - if (!novelUrl) - return; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - }); - return novels; - }); -}; -exports.popularNovels = popularNovels; -const parseNovelAndChapters = function (novelUrl) { - return __awaiter(this, void 0, void 0, function* () { - const url = novelUrl; - const result = yield (0, fetch_1.fetchApi)(url, {}, pluginId); - const body = yield result.text(); - let loadedCheerio = (0, cheerio_1.load)(body); - const novel = { - url, - chapters: [], - }; - novel.name = loadedCheerio("h1.entry-title").text(); - novel.cover = - loadedCheerio("img.wp-post-image").attr("data-src") || - loadedCheerio("img.wp-post-image").attr("src"); - loadedCheerio("div.serl:nth-child(3) > span").each(function () { - const detailName = loadedCheerio(this).text().trim(); - const detail = loadedCheerio(this).next().text().trim(); - switch (detailName) { - case "الكاتب": - case "Author": - novel.author = detail; - break; - } - }); - novel.status = loadedCheerio("div.sertostat > span").attr("class"); - novel.genres = loadedCheerio(".sertogenre") - .children("a") - .map((i, el) => loadedCheerio(el).text()) - .toArray() - .join(","); - novel.summary = loadedCheerio(".sersys") - .find("br") - .replaceWith("\n") - .end() - .text(); - let chapter = []; - loadedCheerio(".eplister") - .find("li") - .each(function () { - const chapterName = loadedCheerio(this).find(".epl-num").text() + - " - " + - loadedCheerio(this).find(".epl-title").text(); - const releaseDate = loadedCheerio(this) - .find(".epl-date") - .text() - .trim(); - const chapterUrl = loadedCheerio(this).find("a").attr("href"); - if (!chapterUrl) - return; - chapter.push({ - name: chapterName, - releaseTime: releaseDate, - url: chapterUrl, - }); - }); - novel.chapters = chapter.reverse(); - return novel; - }); -}; -exports.parseNovelAndChapters = parseNovelAndChapters; -const parseChapter = function (chapterUrl) { - return __awaiter(this, void 0, void 0, function* () { - const result = yield (0, fetch_1.fetchApi)(chapterUrl, {}, pluginId); - const body = yield result.text(); - const loadedCheerio = (0, cheerio_1.load)(body); - let chapterText = loadedCheerio(".epcontent").html(); - return chapterText; - }); -}; -exports.parseChapter = parseChapter; -const searchNovels = function (searchTerm) { - return __awaiter(this, void 0, void 0, function* () { - const url = `${baseUrl}?s=${searchTerm}`; - const result = yield (0, fetch_1.fetchApi)(url, {}, pluginId); - const body = yield result.text(); - const loadedCheerio = (0, cheerio_1.load)(body); - const novels = []; - loadedCheerio("article.maindet").each(function () { - const novelName = loadedCheerio(this).find("h2").text(); - let image = loadedCheerio(this).find("img"); - const novelCover = image.attr("data-src") || image.attr("src"); - const novelUrl = loadedCheerio(this).find("h2 a").attr("href"); - if (!novelUrl) - return; - novels.push({ - name: novelName, - url: novelUrl, - cover: novelCover, - }); - }); - return novels; - }); -}; -exports.searchNovels = searchNovels; -const fetchImage = function (url) { - return __awaiter(this, void 0, void 0, function* () { - const headers = { - Referer: baseUrl, - }; - return yield (0, fetch_1.fetchFile)(url, { headers: headers }); - }); -}; -exports.fetchImage = fetchImage; -exports.filters = [ - { - key: "order", - label: "Sort By", - values: [ - { label: "Default", value: "" }, - { label: "A-Z", value: "title" }, - { label: "Z-A", value: "titlereverse" }, - { label: "Latest Update", value: "update" }, - { label: "Latest Added", value: "latest" }, - { label: "Popular", value: "popular" }, - ], - inputType: filterInputs_1.FilterInputs.Picker, - }, - { - key: "status", - label: "Status", - values: [ - { label: "All", value: "" }, - { label: "Ongoing", value: "ongoing" }, - { label: "Hiatus", value: "hiatus" }, - { label: "Completed", value: "completed" }, - ], - inputType: filterInputs_1.FilterInputs.Picker, - }, - { - key: "type", - label: "Type", - values: [ - { label: "Light Novel (KR)", value: "light-novel-kr" }, - { label: "Web Novel", value: "web-novel" }, - ], - inputType: filterInputs_1.FilterInputs.Checkbox, - }, - { - key: "genres", - label: "Genres", - values: [ - { label: "Action", value: "action" }, - { label: "Adult", value: "adult" }, - { label: "Adventure", value: "adventure" }, - { label: "Comedy", value: "comedy" }, - { label: "Ecchi", value: "ecchi" }, - { label: "Fantasy", value: "fantasy" }, - { label: "Harem", value: "harem" }, - { label: "Josei", value: "josei" }, - { label: "Martial Arts", value: "martial-arts" }, - { label: "Mature", value: "mature" }, - { label: "Romance", value: "romance" }, - { label: "School Life", value: "school-life" }, - { label: "Sci-fi", value: "sci-fi" }, - { label: "Seinen", value: "seinen" }, - { label: "Slice of Life", value: "slice-of-life" }, - { label: "Smut", value: "smut" }, - { label: "Sports", value: "sports" }, - { label: "Supernatural", value: "supernatural" }, - { label: "Tragedy", value: "tragedy" }, - ], - inputType: filterInputs_1.FilterInputs.Checkbox, - }, -]; diff --git a/js/plugins/french/chireads.js b/js/plugins/french/chireads.js deleted file mode 100644 index 9f2e74b..0000000 --- a/js/plugins/french/chireads.js +++ /dev/null @@ -1,113 +0,0 @@ -"use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.fetchImage = exports.searchNovels = exports.parseChapter = exports.parseNovelAndChapters = exports.popularNovels = exports.icon = exports.version = exports.site = exports.name = exports.id = void 0; -const cheerio_1 = require("cheerio"); -const fetch_1 = require("@libs/fetch"); -exports.id = "chireads.com"; -exports.name = "Chireads"; -exports.site = "https://chireads.com/"; -exports.version = "1.0.0"; -exports.icon = "src/fr/chireads/icon.png"; -const baseUrl = exports.site; -const popularNovels = function (page) { - return __awaiter(this, void 0, void 0, function* () { - const url = `${baseUrl}category/translatedtales/page/${page}/`; - const result = yield (0, fetch_1.fetchApi)(url); - const body = yield result.text(); - const loadedCheerio = (0, cheerio_1.load)(body); - let novels = []; - loadedCheerio("#content li").each(function () { - const novelName = loadedCheerio(this).find(".news-list-tit h5").text(); - const novelCover = loadedCheerio(this).find("img").attr("src"); - const novelUrl = loadedCheerio(this) - .find(".news-list-tit h5 a") - .attr("href"); - if (!novelUrl) - return; - const novel = { name: novelName, cover: novelCover, url: novelUrl }; - novels.push(novel); - }); - return novels; - }); -}; -exports.popularNovels = popularNovels; -const parseNovelAndChapters = function (novelUrl) { - return __awaiter(this, void 0, void 0, function* () { - const url = novelUrl; - const result = yield (0, fetch_1.fetchApi)(url); - const body = yield result.text(); - let loadedCheerio = (0, cheerio_1.load)(body); - let novel = { - url, - name: "", - cover: "", - author: "", - status: "", - genres: "", - summary: "", - chapters: [], - }; - novel.name = loadedCheerio(".inform-title").text().trim(); - novel.cover = loadedCheerio(".inform-product img").attr("src"); - novel.summary = loadedCheerio(".inform-inform-txt").text().trim(); - let chapters = []; - loadedCheerio(".chapitre-table a").each(function () { - const chapterName = loadedCheerio(this).text().trim(); - const releaseDate = null; - const chapterUrl = loadedCheerio(this).attr("href"); - if (!chapterUrl) - return; - chapters.push({ - name: chapterName, - releaseTime: releaseDate, - url: chapterUrl, - }); - }); - novel.chapters = chapters; - return novel; - }); -}; -exports.parseNovelAndChapters = parseNovelAndChapters; -const parseChapter = function (chapterUrl) { - return __awaiter(this, void 0, void 0, function* () { - const url = chapterUrl; - const result = yield (0, fetch_1.fetchApi)(url); - const body = yield result.text(); - let loadedCheerio = (0, cheerio_1.load)(body); - const chapterText = loadedCheerio("#content").html(); - return chapterText; - }); -}; -exports.parseChapter = parseChapter; -const searchNovels = function (searchTerm) { - return __awaiter(this, void 0, void 0, function* () { - const url = `${baseUrl}search?x=0&y=0&name=${searchTerm}`; - const result = yield (0, fetch_1.fetchApi)(url); - const body = yield result.text(); - let loadedCheerio = (0, cheerio_1.load)(body); - let novels = []; - loadedCheerio("#content li").each(function () { - const novelName = loadedCheerio(this).find(".news-list-tit h5").text(); - const novelCover = loadedCheerio(this).find("img").attr("src"); - const novelUrl = loadedCheerio(this) - .find(".news-list-tit h5 a") - .attr("href"); - if (!novelUrl) - return; - const novel = { name: novelName, cover: novelCover, url: novelUrl }; - novels.push(novel); - }); - return novels; - }); -}; -exports.searchNovels = searchNovels; -exports.fetchImage = fetch_1.fetchFile; diff --git a/js/plugins/indonesian/MeioNovel[madara].js b/js/plugins/indonesian/MeioNovel[madara].js deleted file mode 100644 index f4823f2..0000000 --- a/js/plugins/indonesian/MeioNovel[madara].js +++ /dev/null @@ -1,179 +0,0 @@ -"use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.filters = exports.fetchImage = exports.searchNovels = exports.parseChapter = exports.parseNovelAndChapters = exports.popularNovels = exports.site = exports.version = exports.icon = exports.name = exports.id = void 0; -const cheerio_1 = require("cheerio"); -const fetch_1 = require("@libs/fetch"); -const filterInputs_1 = require("@libs/filterInputs"); -const defaultCover_1 = require("@libs/defaultCover"); -const novelStatus_1 = require("@libs/novelStatus"); -const parseMadaraDate_1 = require("@libs/parseMadaraDate"); -const dayjs_1 = __importDefault(require("dayjs")); -exports.id = "meionovel"; -exports.name = "MeioNovel [madara]"; -exports.icon = "multisrc/madara/icons/meionovel.png"; -exports.version = "1.0.0"; -exports.site = "https://meionovel.id/"; -const baseUrl = exports.site; -const popularNovels = (pageNo, { filters, showLatestNovels }) => __awaiter(void 0, void 0, void 0, function* () { - const novels = []; - let url = exports.site; - if (filters === null || filters === void 0 ? void 0 : filters.genres) { - url += "novel-genre/" + filters.genres + '/'; - } - else { - url += "novel/"; - } - url += '/page/' + pageNo + '/' + - '?m_orderby=' + (showLatestNovels ? 'latest' : ((filters === null || filters === void 0 ? void 0 : filters.sort) || 'rating')); - const body = yield (0, fetch_1.fetchApi)(url).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.manga-title-badges').remove(); - loadedCheerio('.page-item-detail').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - let novelUrl = loadedCheerio(this).find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - }); - return novels; -}); -exports.popularNovels = popularNovels; -const parseNovelAndChapters = (novelUrl) => __awaiter(void 0, void 0, void 0, function* () { - const novel = { - url: novelUrl, - }; - const body = yield (0, fetch_1.fetchApi)(novelUrl).then(res => res.text()); - let loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.manga-title-badges').remove(); - novel.name = loadedCheerio('.post-title h1').text().trim(); - novel.cover = - loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || - loadedCheerio('.summary_image > a > img').attr('data-src') || - loadedCheerio('.summary_image > a > img').attr('src') || - defaultCover_1.defaultCover; - loadedCheerio('.post-content_item, .post-content').each(function () { - const detailName = loadedCheerio(this).find('h5').text().trim(); - const detail = loadedCheerio(this).find('.summary-content').text().trim(); - switch (detailName) { - case 'Genre(s)': - case 'التصنيفات': - novel.genres = detail.replace(/[\t\n]/g, ','); - break; - case 'Author(s)': - case 'المؤلف': - case 'المؤلف (ين)': - novel.author = detail; - break; - case 'Status': - case 'الحالة': - novel.status = - detail.includes('OnGoing') || detail.includes('مستمرة') - ? novelStatus_1.NovelStatus.Ongoing - : novelStatus_1.NovelStatus.Completed; - break; - } - }); - loadedCheerio('div.summary__content .code-block,script').remove(); - novel.summary = loadedCheerio('div.summary__content').text().trim(); - let html; - if (true) { - const novelId = loadedCheerio('.rating-post-id').attr('value') || - loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; - const body = { - action: "manga_get_chapters", - manga: novelId, - }; - html = yield (0, fetch_1.fetchApi)(baseUrl + 'wp-admin/admin-ajax.php', { - method: 'POST', - body: JSON.stringify(body), - }) - .then(res => res.text()); - } - else { - html = yield (0, fetch_1.fetchApi)(baseUrl + 'ajax/chapters/', { method: 'POST' }) - .then(res => res.text()); - } - if (html !== '0') { - loadedCheerio = (0, cheerio_1.load)(html); - } - const chapters = []; - loadedCheerio('.wp-manga-chapter').each(function () { - const chapterName = loadedCheerio(this).find('a').text().trim(); - let releaseDate = null; - releaseDate = loadedCheerio(this) - .find('span.chapter-release-date') - .text() - .trim(); - if (releaseDate) { - releaseDate = (0, parseMadaraDate_1.parseMadaraDate)(releaseDate); - } - else { - /** - * Insert current date - */ - releaseDate = (0, dayjs_1.default)().format('LL'); - } - let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; - chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); - }); - novel.chapters = chapters.reverse(); - return novel; -}); -exports.parseNovelAndChapters = parseNovelAndChapters; -const parseChapter = (chapterUrl) => __awaiter(void 0, void 0, void 0, function* () { - const url = baseUrl + "/" + "novel" + "/" + chapterUrl; - const body = yield (0, fetch_1.fetchApi)(chapterUrl).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - const chapterText = loadedCheerio('.text-left').html() || - loadedCheerio('.text-right').html() || - loadedCheerio('.entry-content').html(); - return chapterText; -}); -exports.parseChapter = parseChapter; -const searchNovels = (searchTerm) => __awaiter(void 0, void 0, void 0, function* () { - const novels = []; - const url = baseUrl + "?s=" + searchTerm + "&post_type=wp-manga"; - const body = yield (0, fetch_1.fetchApi)(url).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.c-tabs-item__content').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - let novelUrl = loadedCheerio(this) - .find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - }); - return novels; -}); -exports.searchNovels = searchNovels; -const fetchImage = (url) => __awaiter(void 0, void 0, void 0, function* () { - return yield (0, fetch_1.fetchFile)(url); -}); -exports.fetchImage = fetchImage; -exports.filters = [{ "key": "sort", "label": "Order by", "values": [{ "label": "Rating", "value": "rating" }, { "label": "A-Z", "value": "alphabet" }, { "label": "Latest", "value": "latest" }, { "label": "Most Views", "value": "views" }, { "label": "New", "value": "new-manga" }, { "label": "Trending", "value": "trending" }], "inputType": filterInputs_1.FilterInputs.Picker }, { "key": "genres", "label": "GENRES", "values": [{ "label": "Action", "value": "action" }, { "label": "Adventure", "value": "adventure" }, { "label": "Comedy", "value": "comedy" }, { "label": "Cooking", "value": "cooking" }, { "label": "Drama", "value": "drama" }, { "label": "Ecchi", "value": "ecchi" }, { "label": "Fanfiction", "value": "fanfiction" }, { "label": "Fantasy", "value": "fantasy" }, { "label": "Gender Bender", "value": "gender-bender" }, { "label": "Harem", "value": "harem" }, { "label": "Historical", "value": "historical" }, { "label": "Horror", "value": "horror" }, { "label": "Isekai", "value": "isekai" }, { "label": "Josei", "value": "josei" }, { "label": "Magic", "value": "magic" }, { "label": "Martial Arts", "value": "martial-arts" }, { "label": "Mature", "value": "mature" }, { "label": "Mecha", "value": "mecha" }, { "label": "Mystery", "value": "mystery" }, { "label": "One shot", "value": "one-shot" }, { "label": "Psychological", "value": "psychological" }, { "label": "Reverse Harem", "value": "reverse-harem" }, { "label": "Romance", "value": "romance" }, { "label": "School Life", "value": "school-life" }, { "label": "Sci-fi", "value": "sci-fi" }, { "label": "Seinen", "value": "seinen" }, { "label": "Shoujo", "value": "shoujo" }, { "label": "Shoujo Ai", "value": "shoujo-ai" }, { "label": "Shounen", "value": "shounen" }, { "label": "Shounen Ai", "value": "shounen-ai" }, { "label": "Slice of Life", "value": "slice-of-life" }, { "label": "Smut", "value": "smut" }, { "label": "Sports", "value": "sports" }, { "label": "Supernatural", "value": "supernatural" }, { "label": "Tragedy", "value": "tragedy" }, { "label": "Virtual Reality", "value": "virtual-reality" }, { "label": "Wuxia", "value": "wuxia" }, { "label": "Xianxia", "value": "xianxia" }, { "label": "Xuanhuan", "value": "xuanhuan" }, { "label": "Yuri", "value": "yuri" }], "inputType": filterInputs_1.FilterInputs.Picker }]; diff --git a/js/plugins/indonesian/MoreNovel[madara].js b/js/plugins/indonesian/MoreNovel[madara].js deleted file mode 100644 index 47cd615..0000000 --- a/js/plugins/indonesian/MoreNovel[madara].js +++ /dev/null @@ -1,179 +0,0 @@ -"use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.filters = exports.fetchImage = exports.searchNovels = exports.parseChapter = exports.parseNovelAndChapters = exports.popularNovels = exports.site = exports.version = exports.icon = exports.name = exports.id = void 0; -const cheerio_1 = require("cheerio"); -const fetch_1 = require("@libs/fetch"); -const filterInputs_1 = require("@libs/filterInputs"); -const defaultCover_1 = require("@libs/defaultCover"); -const novelStatus_1 = require("@libs/novelStatus"); -const parseMadaraDate_1 = require("@libs/parseMadaraDate"); -const dayjs_1 = __importDefault(require("dayjs")); -exports.id = "morenovel"; -exports.name = "MoreNovel [madara]"; -exports.icon = "multisrc/madara/icons/morenovel.png"; -exports.version = "1.0.0"; -exports.site = "https://morenovel.net/"; -const baseUrl = exports.site; -const popularNovels = (pageNo, { filters, showLatestNovels }) => __awaiter(void 0, void 0, void 0, function* () { - const novels = []; - let url = exports.site; - if (filters === null || filters === void 0 ? void 0 : filters.genres) { - url += "novel-genre/" + filters.genres + '/'; - } - else { - url += "novel/"; - } - url += '/page/' + pageNo + '/' + - '?m_orderby=' + (showLatestNovels ? 'latest' : ((filters === null || filters === void 0 ? void 0 : filters.sort) || 'rating')); - const body = yield (0, fetch_1.fetchApi)(url).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.manga-title-badges').remove(); - loadedCheerio('.page-item-detail').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - let novelUrl = loadedCheerio(this).find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - }); - return novels; -}); -exports.popularNovels = popularNovels; -const parseNovelAndChapters = (novelUrl) => __awaiter(void 0, void 0, void 0, function* () { - const novel = { - url: novelUrl, - }; - const body = yield (0, fetch_1.fetchApi)(novelUrl).then(res => res.text()); - let loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.manga-title-badges').remove(); - novel.name = loadedCheerio('.post-title h1').text().trim(); - novel.cover = - loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || - loadedCheerio('.summary_image > a > img').attr('data-src') || - loadedCheerio('.summary_image > a > img').attr('src') || - defaultCover_1.defaultCover; - loadedCheerio('.post-content_item, .post-content').each(function () { - const detailName = loadedCheerio(this).find('h5').text().trim(); - const detail = loadedCheerio(this).find('.summary-content').text().trim(); - switch (detailName) { - case 'Genre(s)': - case 'التصنيفات': - novel.genres = detail.replace(/[\t\n]/g, ','); - break; - case 'Author(s)': - case 'المؤلف': - case 'المؤلف (ين)': - novel.author = detail; - break; - case 'Status': - case 'الحالة': - novel.status = - detail.includes('OnGoing') || detail.includes('مستمرة') - ? novelStatus_1.NovelStatus.Ongoing - : novelStatus_1.NovelStatus.Completed; - break; - } - }); - loadedCheerio('div.summary__content .code-block,script').remove(); - novel.summary = loadedCheerio('div.summary__content').text().trim(); - let html; - if (true) { - const novelId = loadedCheerio('.rating-post-id').attr('value') || - loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; - const body = { - action: "manga_get_chapters", - manga: novelId, - }; - html = yield (0, fetch_1.fetchApi)(baseUrl + 'wp-admin/admin-ajax.php', { - method: 'POST', - body: JSON.stringify(body), - }) - .then(res => res.text()); - } - else { - html = yield (0, fetch_1.fetchApi)(baseUrl + 'ajax/chapters/', { method: 'POST' }) - .then(res => res.text()); - } - if (html !== '0') { - loadedCheerio = (0, cheerio_1.load)(html); - } - const chapters = []; - loadedCheerio('.wp-manga-chapter').each(function () { - const chapterName = loadedCheerio(this).find('a').text().trim(); - let releaseDate = null; - releaseDate = loadedCheerio(this) - .find('span.chapter-release-date') - .text() - .trim(); - if (releaseDate) { - releaseDate = (0, parseMadaraDate_1.parseMadaraDate)(releaseDate); - } - else { - /** - * Insert current date - */ - releaseDate = (0, dayjs_1.default)().format('LL'); - } - let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; - chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); - }); - novel.chapters = chapters.reverse(); - return novel; -}); -exports.parseNovelAndChapters = parseNovelAndChapters; -const parseChapter = (chapterUrl) => __awaiter(void 0, void 0, void 0, function* () { - const url = baseUrl + "/" + "novel" + "/" + chapterUrl; - const body = yield (0, fetch_1.fetchApi)(chapterUrl).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - const chapterText = loadedCheerio('.text-left').html() || - loadedCheerio('.text-right').html() || - loadedCheerio('.entry-content').html(); - return chapterText; -}); -exports.parseChapter = parseChapter; -const searchNovels = (searchTerm) => __awaiter(void 0, void 0, void 0, function* () { - const novels = []; - const url = baseUrl + "?s=" + searchTerm + "&post_type=wp-manga"; - const body = yield (0, fetch_1.fetchApi)(url).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.c-tabs-item__content').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - let novelUrl = loadedCheerio(this) - .find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - }); - return novels; -}); -exports.searchNovels = searchNovels; -const fetchImage = (url) => __awaiter(void 0, void 0, void 0, function* () { - return yield (0, fetch_1.fetchFile)(url); -}); -exports.fetchImage = fetchImage; -exports.filters = [{ "key": "sort", "label": "Order by", "values": [{ "label": "Rating", "value": "rating" }, { "label": "A-Z", "value": "alphabet" }, { "label": "Latest", "value": "latest" }, { "label": "Most Views", "value": "views" }, { "label": "New", "value": "new-manga" }, { "label": "Trending", "value": "trending" }], "inputType": filterInputs_1.FilterInputs.Picker }, { "key": "genres", "label": "GENRES", "values": [{ "label": "Action", "value": "action" }, { "label": "Adventure", "value": "adventure" }, { "label": "Comedy", "value": "comedy" }, { "label": "Drama", "value": "drama" }, { "label": "Ecchi", "value": "ecchi" }, { "label": "Fantasy", "value": "fantasy" }, { "label": "Gender Bender", "value": "gender-bender" }, { "label": "Harem", "value": "harem" }, { "label": "Historical", "value": "historical" }, { "label": "Horror", "value": "horror" }, { "label": "Josei", "value": "josei" }, { "label": "Martial Arts", "value": "martial-arts" }, { "label": "Mature", "value": "mature" }, { "label": "Mecha", "value": "mecha" }, { "label": "Mystery", "value": "mystery" }, { "label": "Psychological", "value": "psychological" }, { "label": "Romance", "value": "romance" }, { "label": "School Life", "value": "school-life" }, { "label": "Sci-fi", "value": "sci-fi" }, { "label": "Seinen", "value": "seinen" }, { "label": "Shoujo", "value": "shoujo" }, { "label": "Shoujo Ai", "value": "shoujo-ai" }, { "label": "Shounen", "value": "shounen" }, { "label": "Shounen Ai", "value": "shounen-ai" }, { "label": "Slice of Life", "value": "slice-of-life" }, { "label": "Sports", "value": "sports" }, { "label": "Supernatural", "value": "supernatural" }, { "label": "Tragedy", "value": "tragedy" }, { "label": "Wuxia", "value": "wuxia" }, { "label": "Xianxia", "value": "xianxia" }, { "label": "Xuanhuan", "value": "xuanhuan" }, { "label": "Yaoi", "value": "yaoi" }, { "label": "Yuri", "value": "yuri" }], "inputType": filterInputs_1.FilterInputs.Picker }]; diff --git a/js/plugins/indonesian/WBNovel[madara].js b/js/plugins/indonesian/WBNovel[madara].js deleted file mode 100644 index 83bb96e..0000000 --- a/js/plugins/indonesian/WBNovel[madara].js +++ /dev/null @@ -1,179 +0,0 @@ -"use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.filters = exports.fetchImage = exports.searchNovels = exports.parseChapter = exports.parseNovelAndChapters = exports.popularNovels = exports.site = exports.version = exports.icon = exports.name = exports.id = void 0; -const cheerio_1 = require("cheerio"); -const fetch_1 = require("@libs/fetch"); -const filterInputs_1 = require("@libs/filterInputs"); -const defaultCover_1 = require("@libs/defaultCover"); -const novelStatus_1 = require("@libs/novelStatus"); -const parseMadaraDate_1 = require("@libs/parseMadaraDate"); -const dayjs_1 = __importDefault(require("dayjs")); -exports.id = "wbnovel"; -exports.name = "WBNovel [madara]"; -exports.icon = "multisrc/madara/icons/wbnovel.png"; -exports.version = "1.0.0"; -exports.site = "https://wbnovel.com/"; -const baseUrl = exports.site; -const popularNovels = (pageNo, { filters, showLatestNovels }) => __awaiter(void 0, void 0, void 0, function* () { - const novels = []; - let url = exports.site; - if (filters === null || filters === void 0 ? void 0 : filters.genres) { - url += "novel-genre/" + filters.genres + '/'; - } - else { - url += "novel/"; - } - url += '/page/' + pageNo + '/' + - '?m_orderby=' + (showLatestNovels ? 'latest' : ((filters === null || filters === void 0 ? void 0 : filters.sort) || 'rating')); - const body = yield (0, fetch_1.fetchApi)(url).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.manga-title-badges').remove(); - loadedCheerio('.page-item-detail').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - let novelUrl = loadedCheerio(this).find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - }); - return novels; -}); -exports.popularNovels = popularNovels; -const parseNovelAndChapters = (novelUrl) => __awaiter(void 0, void 0, void 0, function* () { - const novel = { - url: novelUrl, - }; - const body = yield (0, fetch_1.fetchApi)(novelUrl).then(res => res.text()); - let loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.manga-title-badges').remove(); - novel.name = loadedCheerio('.post-title h1').text().trim(); - novel.cover = - loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || - loadedCheerio('.summary_image > a > img').attr('data-src') || - loadedCheerio('.summary_image > a > img').attr('src') || - defaultCover_1.defaultCover; - loadedCheerio('.post-content_item, .post-content').each(function () { - const detailName = loadedCheerio(this).find('h5').text().trim(); - const detail = loadedCheerio(this).find('.summary-content').text().trim(); - switch (detailName) { - case 'Genre(s)': - case 'التصنيفات': - novel.genres = detail.replace(/[\t\n]/g, ','); - break; - case 'Author(s)': - case 'المؤلف': - case 'المؤلف (ين)': - novel.author = detail; - break; - case 'Status': - case 'الحالة': - novel.status = - detail.includes('OnGoing') || detail.includes('مستمرة') - ? novelStatus_1.NovelStatus.Ongoing - : novelStatus_1.NovelStatus.Completed; - break; - } - }); - loadedCheerio('div.summary__content .code-block,script').remove(); - novel.summary = loadedCheerio('div.summary__content').text().trim(); - let html; - if (false) { - const novelId = loadedCheerio('.rating-post-id').attr('value') || - loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; - const body = { - action: "manga_get_chapters", - manga: novelId, - }; - html = yield (0, fetch_1.fetchApi)(baseUrl + 'wp-admin/admin-ajax.php', { - method: 'POST', - body: JSON.stringify(body), - }) - .then(res => res.text()); - } - else { - html = yield (0, fetch_1.fetchApi)(baseUrl + 'ajax/chapters/', { method: 'POST' }) - .then(res => res.text()); - } - if (html !== '0') { - loadedCheerio = (0, cheerio_1.load)(html); - } - const chapters = []; - loadedCheerio('.wp-manga-chapter').each(function () { - const chapterName = loadedCheerio(this).find('a').text().trim(); - let releaseDate = null; - releaseDate = loadedCheerio(this) - .find('span.chapter-release-date') - .text() - .trim(); - if (releaseDate) { - releaseDate = (0, parseMadaraDate_1.parseMadaraDate)(releaseDate); - } - else { - /** - * Insert current date - */ - releaseDate = (0, dayjs_1.default)().format('LL'); - } - let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; - chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); - }); - novel.chapters = chapters.reverse(); - return novel; -}); -exports.parseNovelAndChapters = parseNovelAndChapters; -const parseChapter = (chapterUrl) => __awaiter(void 0, void 0, void 0, function* () { - const url = baseUrl + "/" + "novel" + "/" + chapterUrl; - const body = yield (0, fetch_1.fetchApi)(chapterUrl).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - const chapterText = loadedCheerio('.text-left').html() || - loadedCheerio('.text-right').html() || - loadedCheerio('.entry-content').html(); - return chapterText; -}); -exports.parseChapter = parseChapter; -const searchNovels = (searchTerm) => __awaiter(void 0, void 0, void 0, function* () { - const novels = []; - const url = baseUrl + "?s=" + searchTerm + "&post_type=wp-manga"; - const body = yield (0, fetch_1.fetchApi)(url).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.c-tabs-item__content').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - let novelUrl = loadedCheerio(this) - .find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - }); - return novels; -}); -exports.searchNovels = searchNovels; -const fetchImage = (url) => __awaiter(void 0, void 0, void 0, function* () { - return yield (0, fetch_1.fetchFile)(url); -}); -exports.fetchImage = fetchImage; -exports.filters = [{ "key": "sort", "label": "Order by", "values": [{ "label": "Rating", "value": "rating" }, { "label": "A-Z", "value": "alphabet" }, { "label": "Latest", "value": "latest" }, { "label": "Most Views", "value": "views" }, { "label": "New", "value": "new-manga" }, { "label": "Trending", "value": "trending" }], "inputType": filterInputs_1.FilterInputs.Picker }, { "key": "genres", "label": "GENRES", "values": [{ "label": "Action", "value": "action" }, { "label": "Adventure", "value": "adventure" }, { "label": "Alchemy", "value": "alchemy" }, { "label": "Comedy", "value": "comedy" }, { "label": "Crafting", "value": "crafting" }, { "label": "Cultivation", "value": "cultivation" }, { "label": "Drama", "value": "drama" }, { "label": "Dungeon Crawling", "value": "dungeon-crawling" }, { "label": "Eci", "value": "eci" }, { "label": "Fantasy", "value": "fantasy" }, { "label": "Game", "value": "game" }, { "label": "Harem", "value": "harem" }, { "label": "Horror", "value": "horror" }, { "label": "Josei", "value": "josei" }, { "label": "Kingdom Building", "value": "kingdom-building" }, { "label": "Martial Arts", "value": "martial-arts" }, { "label": "Mature", "value": "mature" }, { "label": "Mecha", "value": "mecha" }, { "label": "Modern Setting", "value": "modern-setting" }, { "label": "Mystery", "value": "mystery" }, { "label": "Pets", "value": "pets" }, { "label": "Psychological", "value": "psychological" }, { "label": "Reincarnator", "value": "reincarnator" }, { "label": "Romance", "value": "romance" }, { "label": "School Life", "value": "school-life" }, { "label": "Sci-fi", "value": "sci-fi" }, { "label": "Seinen", "value": "seinen" }, { "label": "Shounen", "value": "shounen" }, { "label": "Slice of Life", "value": "slice-of-life" }, { "label": "Sports", "value": "sports" }, { "label": "Supernatural", "value": "supernatural" }, { "label": "Tragedy", "value": "tragedy" }, { "label": "Transmigration", "value": "transmigration" }, { "label": "Virtual Reality", "value": "virtual-reality" }, { "label": "Wuxia", "value": "wuxia" }, { "label": "Xianxia", "value": "xianxia" }, { "label": "Xuanhuan", "value": "xuanhuan" }], "inputType": filterInputs_1.FilterInputs.Picker }]; diff --git a/js/plugins/indonesian/indowebnovel.js b/js/plugins/indonesian/indowebnovel.js deleted file mode 100644 index 956c892..0000000 --- a/js/plugins/indonesian/indowebnovel.js +++ /dev/null @@ -1,126 +0,0 @@ -"use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.fetchImage = exports.searchNovels = exports.parseChapter = exports.parseNovelAndChapters = exports.popularNovels = exports.version = exports.icon = exports.site = exports.name = exports.id = void 0; -const cheerio_1 = require("cheerio"); -const fetch_1 = require("@libs/fetch"); -const defaultCover_1 = require("@libs/defaultCover"); -exports.id = "IDWN.id"; -exports.name = "IndoWebNovel"; -exports.site = "https://indowebnovel.id/id/"; -exports.icon = "src/id/indowebnovel/icon.png"; -exports.version = "1.0.0"; -const baseUrl = exports.site; -const popularNovels = function (page) { - return __awaiter(this, void 0, void 0, function* () { - const url = `${baseUrl}daftar-novel/`; - const result = yield (0, fetch_1.fetchApi)(url); - const body = yield result.text(); - const loadedCheerio = (0, cheerio_1.load)(body); - let novels = []; - loadedCheerio(".novellist-blc li").each(function () { - const novelName = loadedCheerio(this).find("a").text(); - const novelCover = defaultCover_1.defaultCover; - const novelUrl = loadedCheerio(this).find("a").attr("href"); - if (!novelUrl || !novelName) - return; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - }); - return novels; - }); -}; -exports.popularNovels = popularNovels; -const parseNovelAndChapters = function (novelUrl) { - return __awaiter(this, void 0, void 0, function* () { - const url = novelUrl; - const result = yield (0, fetch_1.fetchApi)(url); - const body = yield result.text(); - let loadedCheerio = (0, cheerio_1.load)(body); - let novel = { - url, - name: "", - cover: "", - author: "", - status: "", - genres: "", - summary: "", - chapters: [], - }; - novel.name = loadedCheerio(".series-title").text().trim(); - novel.cover = loadedCheerio(".series-thumb > img").attr("src"); - novel.summary = loadedCheerio(".series-synops").text().trim(); - novel.status = loadedCheerio(".status").text().trim(); - const genres = []; - loadedCheerio(".series-genres").each(function () { - genres.push(loadedCheerio(this).find("a").text().trim()); - }); - novel.genres = genres.join(","); - let chapters = []; - loadedCheerio(".series-chapterlist li").each(function () { - const chapterName = loadedCheerio(this).find("a").text().trim(); - const releaseDate = null; - const chapterUrl = loadedCheerio(this).find("a").attr("href"); - if (!chapterUrl) - return; - chapters.push({ - name: chapterName, - releaseTime: releaseDate, - url: chapterUrl, - }); - }); - novel.chapters = chapters.reverse(); - return novel; - }); -}; -exports.parseNovelAndChapters = parseNovelAndChapters; -const parseChapter = function (chapterUrl) { - return __awaiter(this, void 0, void 0, function* () { - const url = chapterUrl; - const result = yield (0, fetch_1.fetchApi)(url); - const body = yield result.text(); - let loadedCheerio = (0, cheerio_1.load)(body); - const chapterText = loadedCheerio(".reader").html(); - return chapterText; - }); -}; -exports.parseChapter = parseChapter; -const searchNovels = function (searchTerm) { - return __awaiter(this, void 0, void 0, function* () { - const url = `${baseUrl}daftar-novel/`; - const result = yield (0, fetch_1.fetchApi)(url); - const body = yield result.text(); - const loadedCheerio = (0, cheerio_1.load)(body); - let novels = []; - loadedCheerio(".novellist-blc li").each(function () { - const novelName = loadedCheerio(this).find("a").text(); - const novelCover = defaultCover_1.defaultCover; - const novelUrl = loadedCheerio(this).find("a").attr("href"); - if (!novelUrl) - return; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - if (novelName.toLowerCase().includes(searchTerm.toLowerCase())) { - novels.push(novel); - } - }); - return novels; - }); -}; -exports.searchNovels = searchNovels; -exports.fetchImage = fetch_1.fetchFile; diff --git a/js/plugins/indonesian/novelringan.js b/js/plugins/indonesian/novelringan.js deleted file mode 100644 index 4b84f3a..0000000 --- a/js/plugins/indonesian/novelringan.js +++ /dev/null @@ -1,135 +0,0 @@ -"use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.fetchImage = exports.searchNovels = exports.parseChapter = exports.parseNovelAndChapters = exports.popularNovels = exports.version = exports.icon = exports.site = exports.name = exports.id = void 0; -const cheerio_1 = require("cheerio"); -const fetch_1 = require("@libs/fetch"); -const novelStatus_1 = require("@libs/novelStatus"); -exports.id = "novelringan.com"; -exports.name = "NovelRingan"; -exports.site = "https://novelringan.com/"; -exports.icon = "src/id/novelringan/icon.png"; -exports.version = "1.0.0"; -const baseUrl = exports.site; -const coverUriPrefix = "https://i0.wp.com/novelringan.com/wp-content/uploads/"; -const popularNovels = function (page) { - return __awaiter(this, void 0, void 0, function* () { - const url = `${baseUrl}/top-novel/page/${page}`; - const result = yield (0, fetch_1.fetchApi)(url); - const body = yield result.text(); - const loadedCheerio = (0, cheerio_1.load)(body); - const novels = []; - loadedCheerio("article.post").each(function () { - var _a; - const novelName = (_a = loadedCheerio(this) - .find(".entry-title") - .text()) === null || _a === void 0 ? void 0 : _a.trim(); - const novelCover = coverUriPrefix + loadedCheerio(this).find("img").attr("data-sxrx"); - const novelUrl = loadedCheerio(this).find("h2 > a").attr("href"); - if (!novelUrl) - return; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - }); - return novels; - }); -}; -exports.popularNovels = popularNovels; -const parseNovelAndChapters = function (novelUrl) { - var _a; - return __awaiter(this, void 0, void 0, function* () { - const url = novelUrl; - const result = yield (0, fetch_1.fetchApi)(url); - const body = yield result.text(); - const loadedCheerio = (0, cheerio_1.load)(body); - let novel = { - url, - name: "", - cover: "", - genres: "", - author: "", - status: novelStatus_1.NovelStatus.Unknown, - summary: "", - chapters: [], - }; - novel.name = (_a = loadedCheerio(".entry-title").text()) === null || _a === void 0 ? void 0 : _a.trim(); - novel.cover = - coverUriPrefix + - loadedCheerio("img.ts-post-image").attr("data-sxrx"); - novel.summary = loadedCheerio("body > div.site-container > div > main > article > div > div.maininfo > span > p").text(); - let genreSelector = loadedCheerio("body > div.site-container > div > main > article > div > div.maininfo > span > ul > li:nth-child(4)").text(); - novel.genres = genreSelector.includes("Genre") - ? genreSelector.replace("Genre:", "").trim() - : ""; - let statusSelector = loadedCheerio("body > div.site-container > div > main > article > div > div.maininfo > span > ul > li:nth-child(3)").text(); - novel.status = statusSelector.includes("Status") - ? statusSelector.replace("Status:", "").trim() - : novelStatus_1.NovelStatus.Unknown; - let chapters = []; - loadedCheerio(".bxcl > ul > li").each(function () { - const chapterName = loadedCheerio(this).find("a").text(); - const releaseDate = null; - const chapterUrl = loadedCheerio(this).find("a").attr("href"); - if (!chapterUrl) - return; - const chapter = { - name: chapterName, - releaseTime: releaseDate, - url: chapterUrl, - }; - chapters.push(chapter); - }); - novel.chapters = chapters.reverse(); - return novel; - }); -}; -exports.parseNovelAndChapters = parseNovelAndChapters; -const parseChapter = function (chapterUrl) { - return __awaiter(this, void 0, void 0, function* () { - const url = chapterUrl; - const result = yield (0, fetch_1.fetchApi)(url); - const body = yield result.text(); - const loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.entry-content div[style="display:none"]').remove(); - const chapterText = loadedCheerio(".entry-content").html(); - return chapterText; - }); -}; -exports.parseChapter = parseChapter; -const searchNovels = function (searchTerm) { - return __awaiter(this, void 0, void 0, function* () { - const url = baseUrl + "?s=" + searchTerm; - const result = yield (0, fetch_1.fetchApi)(url); - const body = yield result.text(); - const loadedCheerio = (0, cheerio_1.load)(body); - let novels = []; - loadedCheerio("article.post").each(function () { - const novelName = loadedCheerio(this).find(".entry-title").text(); - const novelCover = coverUriPrefix + loadedCheerio(this).find("img").attr("data-sxrx"); - const novelUrl = loadedCheerio(this).find("h2 > a").attr("href"); - if (!novelUrl) - return; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - }); - return novels; - }); -}; -exports.searchNovels = searchNovels; -exports.fetchImage = fetch_1.fetchFile; diff --git a/js/plugins/indonesian/sakuranovel.js b/js/plugins/indonesian/sakuranovel.js deleted file mode 100644 index 7913db4..0000000 --- a/js/plugins/indonesian/sakuranovel.js +++ /dev/null @@ -1,140 +0,0 @@ -"use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.fetchImage = exports.searchNovels = exports.parseChapter = exports.parseNovelAndChapters = exports.popularNovels = exports.version = exports.icon = exports.site = exports.name = exports.id = void 0; -const cheerio_1 = require("cheerio"); -const fetch_1 = require("@libs/fetch"); -exports.id = "sakura.id"; -exports.name = "SakuraNovel"; -exports.site = "https://sakuranovel.id/"; -exports.icon = "src/id/sakuranovel/icon.png"; -exports.version = "1.0.0"; -const pluginId = exports.id; -const sourceName = exports.name; -const baseUrl = exports.site; -const popularNovels = function (page) { - return __awaiter(this, void 0, void 0, function* () { - const url = `${baseUrl}advanced-search/page/${page}/?title&author&yearx&status&type&order=rating&country%5B0%5D=china&country%5B1%5D=jepang&country%5B2%5D=unknown`; - const result = yield (0, fetch_1.fetchApi)(url, {}, pluginId); - const body = yield result.text(); - const loadedCheerio = (0, cheerio_1.load)(body); - let novels = []; - loadedCheerio(".flexbox2-item").each(function () { - const novelName = loadedCheerio(this) - .find(".flexbox2-title span") - .first() - .text(); - const novelCover = loadedCheerio(this).find("img").attr("src"); - const novelUrl = loadedCheerio(this) - .find(".flexbox2-content > a") - .attr("href"); - if (!novelUrl) - return; - const novel = { name: novelName, cover: novelCover, url: novelUrl }; - novels.push(novel); - }); - return novels; - }); -}; -exports.popularNovels = popularNovels; -const parseNovelAndChapters = function (novelUrl) { - return __awaiter(this, void 0, void 0, function* () { - const result = yield (0, fetch_1.fetchApi)(novelUrl, {}, pluginId); - const body = yield result.text(); - let loadedCheerio = (0, cheerio_1.load)(body); - let novel = { - name: sourceName, - url: novelUrl, - }; - novel.name = loadedCheerio(".series-title h2").text().trim(); - novel.cover = loadedCheerio(".series-thumb img").attr("src"); - loadedCheerio(".series-infolist > li").each(function () { - const detailName = loadedCheerio(this).find("b").text().trim(); - const detail = loadedCheerio(this).find("b").next().text().trim(); - switch (detailName) { - case "Author": - novel.author = detail; - break; - } - }); - novel.status = loadedCheerio(".status").text().trim(); - novel.genres = loadedCheerio(".series-genres") - .children("a") - .map((i, el) => loadedCheerio(el).text()) - .toArray() - .join(","); - loadedCheerio(".series-synops div").remove(); - novel.summary = loadedCheerio(".series-synops").text().trim(); - let chapters = []; - loadedCheerio(".series-chapterlist li").each(function () { - const chapterName = loadedCheerio(this) - .find("a span") - .first() - .text() - .replace(/.*?(Chapter.|[0-9])/g, "$1") - .replace(/Bahasa Indonesia/g, "") - .replace(/\s+/g, " ") - .trim(); - const releaseDate = loadedCheerio(this) - .find("a span") - .first() - .next() - .text(); - const chapterUrl = loadedCheerio(this).find("a").attr("href"); - if (!chapterUrl) - return; - chapters.push({ - name: chapterName, - releaseTime: releaseDate, - url: chapterUrl, - }); - }); - novel.chapters = chapters.reverse(); - return novel; - }); -}; -exports.parseNovelAndChapters = parseNovelAndChapters; -const parseChapter = function (chapterUrl) { - return __awaiter(this, void 0, void 0, function* () { - const result = yield (0, fetch_1.fetchApi)(chapterUrl, {}, pluginId); - const body = yield result.text(); - let loadedCheerio = (0, cheerio_1.load)(body); - const chapterText = loadedCheerio(".readers").html(); - return chapterText; - }); -}; -exports.parseChapter = parseChapter; -const searchNovels = function (searchTerm) { - return __awaiter(this, void 0, void 0, function* () { - const url = `${baseUrl}?s=${searchTerm}`; - const result = yield (0, fetch_1.fetchApi)(url, {}, pluginId); - const body = yield result.text(); - let loadedCheerio = (0, cheerio_1.load)(body); - let novels = []; - loadedCheerio(".flexbox2-item").each(function () { - const novelName = loadedCheerio(this) - .find(".flexbox2-title span") - .first() - .text(); - const novelCover = loadedCheerio(this).find("img").attr("src"); - const novelUrl = loadedCheerio(this) - .find(".flexbox2-content > a") - .attr("href"); - if (!novelUrl) - return; - const novel = { name: novelName, cover: novelCover, url: novelUrl }; - novels.push(novel); - }); - return novels; - }); -}; -exports.searchNovels = searchNovels; -exports.fetchImage = fetch_1.fetchFile; diff --git a/js/plugins/japanese/Syosetu.js b/js/plugins/japanese/Syosetu.js deleted file mode 100644 index 5209189..0000000 --- a/js/plugins/japanese/Syosetu.js +++ /dev/null @@ -1,201 +0,0 @@ -"use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.fetchImage = exports.searchNovels = exports.parseChapter = exports.parseNovelAndChapters = exports.popularNovels = exports.site = exports.version = exports.icon = exports.name = exports.id = void 0; -const cheerio_1 = require("cheerio"); -const fetch_1 = require("@libs/fetch"); -const defaultCover_1 = require("@libs/defaultCover"); -// const novelStatus = require('@libs/novelStatus'); -// const isUrlAbsolute = require('@libs/isAbsoluteUrl'); -// const parseDate = require('@libs/parseDate'); -const pluginId = "yomou.syosetu"; -exports.id = pluginId; -exports.name = "Syosetu"; -exports.icon = "src/jp/syosetu/icon.png"; -exports.version = "1.0.0"; -exports.site = "https//yomou.syosetu.com/"; -const searchUrl = (pagenum, order) => { - return `https://yomou.syosetu.com/search.php?order=${order || "hyoka"}${pagenum !== undefined - ? `&p=${pagenum <= 1 || pagenum > 100 ? "1" : pagenum}` // check if pagenum is between 1 and 100 - : "" // if isn't don't set ?p - }`; -}; -const popularNovels = function (pageNo) { - return __awaiter(this, void 0, void 0, function* () { - function getNovelsFromPage(pagenumber) { - return __awaiter(this, void 0, void 0, function* () { - // load page - const result = yield (0, fetch_1.fetchApi)(searchUrl(pagenumber)); - const body = yield result.text(); - // Cheerio it! - const cheerioQuery = (0, cheerio_1.load)(body, { decodeEntities: false }); - let pageNovels = []; - // find class=searchkekka_box - cheerioQuery(".searchkekka_box").each(function (i, e) { - // get div with link and name - const novelDIV = cheerioQuery(this).find(".novel_h"); - // get link element - const novelA = novelDIV.children()[0]; - // add new novel to array - pageNovels.push({ - name: novelDIV.text(), - url: novelA.attribs.href, - cover: defaultCover_1.defaultCover, - }); - }); - // return all novels from this page - return pageNovels; - }); - } - const novels = yield getNovelsFromPage(pageNo); - return novels; - }); -}; -exports.popularNovels = popularNovels; -const parseNovelAndChapters = function (novelUrl) { - return __awaiter(this, void 0, void 0, function* () { - let chapters = []; - const result = yield (0, fetch_1.fetchApi)(novelUrl); - const body = yield result.text(); - const loadedCheerio = (0, cheerio_1.load)(body, { decodeEntities: false }); - // create novel object - let novel = { - url: novelUrl, - name: loadedCheerio(".novel_title").text(), - author: loadedCheerio(".novel_writername") - .text() - .replace("作者:", ""), - cover: defaultCover_1.defaultCover, - }; - // Get all the chapters - const cqGetChapters = loadedCheerio(".novel_sublist2"); - if (cqGetChapters.length !== 0) { - // has more than 1 chapter - novel.summary = loadedCheerio("#novel_ex") - .text() - .replace(/<\s*br.*?>/g, "\n"); - cqGetChapters.each(function (i, e) { - const chapterA = loadedCheerio(this).find("a"); - const [chapterName, releaseDate, chapterUrl] = [ - // set the variables - chapterA.text(), - loadedCheerio(this) - .find("dt") // get title - .text() // get text - .replace(/(.)/g, "") // remove "(edited)" mark - .trim(), - "https://ncode.syosetu.com" + chapterA.attr("href"), - ]; - chapters.push({ - name: chapterName, - releaseTime: releaseDate, - url: chapterUrl, - }); - }); - } - else { - /** - * Because there are oneshots on the site, they have to be treated with special care - * that's what pisses me off in Shosetsu app. They have this extension, - * but every oneshot is set as "there are no chapters" and all contents are thrown into the description!! - */ - // get summary for oneshot chapter - const nameResult = yield (0, fetch_1.fetchApi)(searchUrl() + `&word=${novel.name}`); - const nameBody = yield nameResult.text(); - const summaryQuery = (0, cheerio_1.load)(nameBody, { - decodeEntities: false, - }); - const foundText = summaryQuery(".searchkekka_box") - .first() - .find(".ex") - .text() - .replace(/\s{2,}/g, "\n"); - novel.summary = foundText; - // add single chapter - chapters.push({ - name: "Oneshot", - releaseTime: loadedCheerio("head") - .find("meta[name='WWWC']") - .attr("content"), - url: novelUrl, // set chapterUrl to oneshot so that chapterScraper knows it's a one-shot, - }); - } - novel.chapters = chapters; - return novel; - }); -}; -exports.parseNovelAndChapters = parseNovelAndChapters; -const parseChapter = function (chapterUrl) { - return __awaiter(this, void 0, void 0, function* () { - const result = yield (0, fetch_1.fetchApi)(chapterUrl); - const body = yield result.text(); - // create cheerioQuery - const cheerioQuery = (0, cheerio_1.load)(body, { - decodeEntities: false, - }); - let chapterText = cheerioQuery("#novel_honbun") // get chapter text - .html(); - return chapterText; - }); -}; -exports.parseChapter = parseChapter; -const searchNovels = function (searchTerm) { - return __awaiter(this, void 0, void 0, function* () { - let novels = []; - // returns list of novels from given page - function getNovelsFromPage(pagenumber) { - return __awaiter(this, void 0, void 0, function* () { - // load page - const result = yield (0, fetch_1.fetchApi)(searchUrl(pagenumber) + `&word=${searchTerm}`); - const body = yield result.text(); - // Cheerio it! - const cheerioQuery = (0, cheerio_1.load)(body, { decodeEntities: false }); - let pageNovels = []; - // find class=searchkekka_box - cheerioQuery(".searchkekka_box").each(function (i, e) { - // get div with link and name - const novelDIV = cheerioQuery(this).find(".novel_h"); - // get link element - const novelA = novelDIV.children()[0]; - // add new novel to array - pageNovels.push({ - name: novelDIV.text(), - url: novelA.attribs.href, - cover: defaultCover_1.defaultCover, - }); - }); - // return all novels from this page - return pageNovels; - }); - } - // counter of loaded pages - // let pagesLoaded = 0; - // do { - // // always load first one - // novels.push(...(await getNovelsFromPage(pagesLoaded + 1))); - // pagesLoaded++; - // } while (pagesLoaded < maxPageLoad && isNext); // check if we should load more - novels = yield getNovelsFromPage(1); - /** Use - * novels.push(...(await getNovelsFromPage(pageNumber))) - * if you want to load more - */ - // respond with novels! - return novels; - }); -}; -exports.searchNovels = searchNovels; -const fetchImage = function (url) { - return __awaiter(this, void 0, void 0, function* () { - return yield (0, fetch_1.fetchFile)(url); - }); -}; -exports.fetchImage = fetchImage; diff --git a/js/plugins/korean/Agitoon.js b/js/plugins/korean/Agitoon.js deleted file mode 100644 index 48513ef..0000000 --- a/js/plugins/korean/Agitoon.js +++ /dev/null @@ -1,141 +0,0 @@ -"use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.fetchImage = exports.searchNovels = exports.parseChapter = exports.parseNovelAndChapters = exports.popularNovels = exports.icon = exports.version = exports.site = exports.name = exports.id = void 0; -const cheerio_1 = require("cheerio"); -const fetch_1 = require("@libs/fetch"); -exports.id = "agit.xyz"; -exports.name = "Agitoon"; -exports.site = "https://agit501.xyz/"; -exports.version = "1.0.0"; -exports.icon = "src/kr/agitoon/agit.png"; -const baseUrl = exports.site; -const popularNovels = function (page) { - var _a; - return __awaiter(this, void 0, void 0, function* () { - const list_limit = 20 * (page - 1); - const day = new Date().getDay(); - const res = yield (0, fetch_1.fetchApi)(baseUrl + "novel/index.update.php", { - headers: { - "content-type": "application/x-www-form-urlencoded; charset=UTF-8", - }, - body: `mode=get_data_novel_list_p&novel_menu=3&np_day=${day}&np_rank=1&np_distributor=0&np_genre=00&np_order=1&np_genre_ex_1=00&np_genre_ex_2=00&list_limit=${list_limit}&is_query_first=true`, - method: "POST", - }); - const resJson = yield res.json(); - const novels = []; - (_a = resJson === null || resJson === void 0 ? void 0 : resJson.list) === null || _a === void 0 ? void 0 : _a.forEach((novel) => { - novels.push({ - url: baseUrl + "novel/list/" + novel.wr_id, - name: novel.wr_subject, - cover: baseUrl + novel.np_dir + "/thumbnail/" + novel.np_thumbnail, - }); - }); - return novels; - }); -}; -exports.popularNovels = popularNovels; -const parseNovelAndChapters = function (novelUrl) { - var _a; - return __awaiter(this, void 0, void 0, function* () { - const novelId = novelUrl.split("/").reverse()[0]; - // cheerio - const result = yield (0, fetch_1.fetchApi)(novelUrl); - const body = yield result.text(); - const loadedCheerio = (0, cheerio_1.load)(body, { decodeEntities: false }); - const name = loadedCheerio("h5.pt-2").text(); - const summary = loadedCheerio(".pt-1.mt-1.pb-1.mb-1").text(); - const author = loadedCheerio(".post-item-list-cate-v") - .first() - .text() - .split(" : ") - .reverse()[0]; - const cover = baseUrl.slice(0, baseUrl.length - 1) + - loadedCheerio("div.col-5.pr-0.pl-0 img").attr("src"); - const genresTag = loadedCheerio(".col-7 > .post-item-list-cate > span"); - let genres = ""; - genresTag.each((_, element) => { - genres += loadedCheerio(element).text(); - genres += ", "; - }); - genres = genres.slice(0, genres.length - 2); - // normal REST HTTP requests - let chapters = []; - const res = yield (0, fetch_1.fetchApi)(baseUrl + "novel/list.update.php", { - headers: { - "content-type": "application/x-www-form-urlencoded; charset=UTF-8", - }, - body: `mode=get_data_novel_list_c&wr_id_p=${novelId}&page_no=1&cnt_list=10000&order_type=Asc`, - method: "POST", - }); - const resJson = yield res.json(); - (_a = resJson === null || resJson === void 0 ? void 0 : resJson.list) === null || _a === void 0 ? void 0 : _a.forEach((chapter) => { - chapters.push({ - name: chapter.wr_subject, - url: baseUrl + `novel/view/${chapter.wr_id}/2`, - releaseTime: chapter.wr_datetime, - }); - }); - const novel = { - url: novelUrl, - name, - cover, - summary, - author, - status: "", - genres: genres, - chapters, - }; - return novel; - }); -}; -exports.parseNovelAndChapters = parseNovelAndChapters; -const parseChapter = function (chapterUrl) { - return __awaiter(this, void 0, void 0, function* () { - const result = yield (0, fetch_1.fetchApi)(chapterUrl); - const body = yield result.text(); - const loadedCheerio = (0, cheerio_1.load)(body); - const contentTag = loadedCheerio("#id_wr_content > p"); - let content = ""; - contentTag.each((_, element) => { - content += loadedCheerio(element).text(); - content += "
"; - }); - // gets rid of the popup thingy - content = content.replace("팝업메뉴는 빈공간을 더치하거나 스크룰시 사라집니다", ""); - return content; - }); -}; -exports.parseChapter = parseChapter; -const searchNovels = function (searchTerm) { - var _a; - return __awaiter(this, void 0, void 0, function* () { - const rawResults = yield (0, fetch_1.fetchApi)("https://agit501.xyz/novel/search.php", { - headers: { - "content-type": "application/x-www-form-urlencoded; charset=UTF-8", - }, - body: `mode=get_data_novel_list_p_sch&search_novel=${searchTerm}&list_limit=0`, - method: "POST", - }); - const resJson = yield rawResults.json(); - const novels = []; - (_a = resJson === null || resJson === void 0 ? void 0 : resJson.list) === null || _a === void 0 ? void 0 : _a.forEach((novel) => { - novels.push({ - url: baseUrl + "novel/list/" + novel.wr_id, - name: novel.wr_subject, - cover: baseUrl + novel.np_dir + "/thumbnail/" + novel.np_thumbnail, - }); - }); - return novels; - }); -}; -exports.searchNovels = searchNovels; -exports.fetchImage = fetch_1.fetchFile; diff --git a/js/plugins/portuguese/lightnovelbrasil.js b/js/plugins/portuguese/lightnovelbrasil.js deleted file mode 100644 index b8f806f..0000000 --- a/js/plugins/portuguese/lightnovelbrasil.js +++ /dev/null @@ -1,300 +0,0 @@ -"use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.filters = exports.fetchImage = exports.searchNovels = exports.parseChapter = exports.parseNovelAndChapters = exports.popularNovels = exports.site = exports.icon = exports.version = exports.name = exports.id = void 0; -const cheerio_1 = require("cheerio"); -const fetch_1 = require("@libs/fetch"); -const filterInputs_1 = require("@libs/filterInputs"); -exports.id = "lightnovelbrasil"; -exports.name = "Light Novel Brasil"; -exports.version = "1.0.0"; -exports.icon = "multisrc/wpmangastream/icons/lightnovelbrasil.png"; -exports.site = "https://lightnovelbrasil.com/"; -const pluginId = exports.id; -const baseUrl = exports.site; -const popularNovels = function (page, { filters }) { - return __awaiter(this, void 0, void 0, function* () { - let link = `${baseUrl}series/?page=${page}`; - if (filters) { - if (Array.isArray(filters.genres) && filters.genres.length) { - link += filters.genres.map((i) => `&genre[]=${i}`).join(""); - } - if (Array.isArray(filters.type) && filters.type.length) { - link += filters.type.map((i) => `&lang[]=${i}`).join(""); - } - } - link += "&status=" + ((filters === null || filters === void 0 ? void 0 : filters.status) ? filters === null || filters === void 0 ? void 0 : filters.status : ""); - link += "&order=" + ((filters === null || filters === void 0 ? void 0 : filters.order) ? filters === null || filters === void 0 ? void 0 : filters.order : "popular"); - const body = yield (0, fetch_1.fetchApi)(link, {}, pluginId).then((result) => result.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - const novels = []; - loadedCheerio("article.bs").each(function () { - const novelName = loadedCheerio(this).find(".ntitle").text().trim(); - let image = loadedCheerio(this).find("img"); - const novelCover = image.attr("data-src") || image.attr("src"); - const novelUrl = loadedCheerio(this).find("a").attr("href"); - if (!novelUrl) - return; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - }); - return novels; - }); -}; -exports.popularNovels = popularNovels; -const parseNovelAndChapters = function (novelUrl) { - return __awaiter(this, void 0, void 0, function* () { - const url = novelUrl; - const result = yield (0, fetch_1.fetchApi)(url, {}, pluginId); - const body = yield result.text(); - let loadedCheerio = (0, cheerio_1.load)(body); - const novel = { - url, - chapters: [], - }; - novel.name = loadedCheerio(".entry-title").text(); - novel.cover = - loadedCheerio("img.wp-post-image").attr("data-src") || - loadedCheerio("img.wp-post-image").attr("src"); - loadedCheerio("div.spe > span").each(function () { - const detailName = loadedCheerio(this).find("b").text().trim(); - const detail = loadedCheerio(this) - .find("b") - .remove() - .end() - .text() - .trim(); - switch (detailName) { - case "المؤلف:": - case "Yazar:": - case "Autor:": - case "Author:": - novel.author = detail; - break; - case "Status:": - case "Seviye:": - novel.status = detail; - break; - } - }); - novel.genres = loadedCheerio(".genxed") - .text() - .trim() - .replace(/\s/g, ","); - loadedCheerio('div[itemprop="description"] h3,p.a,strong').remove(); - novel.summary = loadedCheerio('div[itemprop="description"]') - .find("br") - .replaceWith("\n") - .end() - .text(); - let chapter = []; - loadedCheerio(".eplister") - .find("li") - .each(function () { - const chapterName = loadedCheerio(this).find(".epl-num").text() + - " - " + - loadedCheerio(this).find(".epl-title").text(); - const releaseDate = loadedCheerio(this) - .find(".epl-date") - .text() - .trim(); - const chapterUrl = loadedCheerio(this).find("a").attr("href"); - if (!chapterUrl) - return; - chapter.push({ - name: chapterName, - releaseTime: releaseDate, - url: chapterUrl, - }); - }); - novel.chapters = chapter.reverse(); - return novel; - }); -}; -exports.parseNovelAndChapters = parseNovelAndChapters; -const parseChapter = function (chapterUrl) { - return __awaiter(this, void 0, void 0, function* () { - const result = yield (0, fetch_1.fetchApi)(chapterUrl, {}, pluginId); - const body = yield result.text(); - const loadedCheerio = (0, cheerio_1.load)(body); - let chapterText = loadedCheerio("div.epcontent").html(); - return chapterText; - }); -}; -exports.parseChapter = parseChapter; -const searchNovels = function (searchTerm) { - return __awaiter(this, void 0, void 0, function* () { - const url = `${baseUrl}?s=${searchTerm}`; - const result = yield (0, fetch_1.fetchApi)(url, {}, pluginId); - const body = yield result.text(); - const loadedCheerio = (0, cheerio_1.load)(body); - const novels = []; - loadedCheerio("article.bs").each(function () { - const novelName = loadedCheerio(this).find(".ntitle").text().trim(); - const novelCover = loadedCheerio(this).find("img").attr("src"); - const novelUrl = loadedCheerio(this).find("a").attr("href"); - if (!novelUrl) - return; - novels.push({ - name: novelName, - url: novelUrl, - cover: novelCover, - }); - }); - return novels; - }); -}; -exports.searchNovels = searchNovels; -const fetchImage = function (url) { - return __awaiter(this, void 0, void 0, function* () { - const headers = { - Referer: baseUrl, - }; - return yield (0, fetch_1.fetchFile)(url, { headers: headers }); - }); -}; -exports.fetchImage = fetchImage; -exports.filters = [ - { - key: "order", - label: "Sort By", - values: [ - { label: "Default", value: "" }, - { label: "A-Z", value: "title" }, - { label: "Z-A", value: "titlereverse" }, - { label: "Latest Update", value: "update" }, - { label: "Latest Added", value: "latest" }, - { label: "Popular", value: "popular" }, - ], - inputType: filterInputs_1.FilterInputs.Picker, - }, - { - key: "status", - label: "Status", - values: [ - { label: "All", value: "" }, - { label: "Ongoing", value: "ongoing" }, - { label: "Hiatus", value: "hiatus" }, - { label: "Completed", value: "completed" }, - ], - inputType: filterInputs_1.FilterInputs.Picker, - }, - { - key: "type", - label: "Type", - values: [ - { label: "Chinese novel", value: "chinese-novel" }, - { label: "habyeol", value: "habyeol" }, - { label: "korean novel", value: "korean-novel" }, - { label: "Web Novel", value: "web-novel" }, - { label: "삼심", value: "%ec%82%bc%ec%8b%ac" }, - { label: "호곡", value: "%ed%98%b8%ea%b3%a1" }, - ], - inputType: filterInputs_1.FilterInputs.Checkbox, - }, - { - key: "genres", - label: "Genres", - values: [ - { label: "A.I", value: "a.i" }, - { label: "Academy", value: "academy" }, - { label: "Action", value: "action" }, - { label: "Adult", value: "adult" }, - { label: "Adventure", value: "adventure" }, - { label: "Alternative History", value: "alternative-history" }, - { label: "Another World", value: "another-world" }, - { label: "Apocalypse", value: "apocalypse" }, - { label: "Bromance", value: "bromance" }, - { label: "Comedy", value: "comedy" }, - { label: "Dark fantasy", value: "dark-fantasy" }, - { label: "Demons", value: "demons" }, - { label: "Drama", value: "drama" }, - { label: "Dystopia", value: "dystopia" }, - { label: "Ecchi", value: "ecchi" }, - { label: "Entertainment", value: "entertainment" }, - { label: "Exhaustion", value: "exhaustion" }, - { label: "Fanfiction", value: "fanfiction" }, - { label: "fantasy", value: "fantasy" }, - { label: "finance", value: "finance" }, - { label: "Full color", value: "full-color" }, - { label: "Game", value: "game" }, - { label: "Gender Bender", value: "gender-bender" }, - { label: "Genius", value: "genius" }, - { label: "Harem", value: "harem" }, - { label: "Hero", value: "hero" }, - { label: "Historical", value: "historical" }, - { label: "Hunter", value: "hunter" }, - { label: "korean novel", value: "korean-novel" }, - { label: "Light Novel", value: "light-novel" }, - { - label: "List Adventure Manga Genres", - value: "list-adventure-manga-genres", - }, - { label: "Long Strip", value: "long-strip" }, - { label: "Love comedy", value: "love-comedy" }, - { label: "magic", value: "magic" }, - { label: "Manhua", value: "manhua" }, - { label: "Martial Arts", value: "martial-arts" }, - { label: "Mature", value: "mature" }, - { label: "Medieval", value: "medieval" }, - { label: "Misunderstanding", value: "misunderstanding" }, - { label: "Modern", value: "modern" }, - { label: "modern fantasy", value: "modern-fantasy" }, - { label: "music", value: "music" }, - { label: "Mystery", value: "mystery" }, - { label: "Necromancy", value: "necromancy" }, - { label: "No Romance", value: "no-romance" }, - { label: "NTL", value: "ntl" }, - { label: "o", value: "o" }, - { label: "Obsession", value: "obsession" }, - { label: "Politics", value: "politics" }, - { label: "Possession", value: "possession" }, - { label: "Programming", value: "programming" }, - { label: "Psychological", value: "psychological" }, - { label: "Pure Love", value: "pure-love" }, - { label: "Redemption", value: "redemption" }, - { label: "Regression", value: "regression" }, - { label: "Regret", value: "regret" }, - { label: "Reincarnation", value: "reincarnation" }, - { label: "Revenge", value: "revenge" }, - { label: "Romance", value: "romance" }, - { label: "Romance Fanrasy", value: "romance-fanrasy" }, - { label: "Salvation", value: "salvation" }, - { label: "School Life", value: "school-life" }, - { label: "Sci-fi", value: "sci-fi" }, - { label: "Science fiction", value: "science-fiction" }, - { label: "Seinen", value: "seinen" }, - { label: "Shounen", value: "shounen" }, - { label: "Slice of Life", value: "slice-of-life" }, - { label: "Soft yandere", value: "soft-yandere" }, - { label: "Sports", value: "sports" }, - { label: "Supernatural", value: "supernatural" }, - { label: "Survival", value: "survival" }, - { label: "system", value: "system" }, - { label: "Time limit", value: "time-limit" }, - { label: "Tragedy", value: "tragedy" }, - { label: "Transmigration", value: "transmigration" }, - { label: "TS", value: "ts" }, - { label: "Tsundere", value: "tsundere" }, - { label: "Unique", value: "unique" }, - { label: "Wholesome", value: "wholesome" }, - { label: "Wuxia", value: "wuxia" }, - { label: "Xuanhuan", value: "xuanhuan" }, - { label: "Yandere", value: "yandere" }, - { label: "Yuri", value: "yuri" }, - ], - inputType: filterInputs_1.FilterInputs.Checkbox, - }, -]; diff --git a/js/plugins/russian/Erolate[rulate].js b/js/plugins/russian/Erolate[rulate].js deleted file mode 100644 index f92f504..0000000 --- a/js/plugins/russian/Erolate[rulate].js +++ /dev/null @@ -1,195 +0,0 @@ -"use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.filters = exports.fetchImage = exports.searchNovels = exports.parseChapter = exports.parseNovelAndChapters = exports.popularNovels = exports.site = exports.version = exports.icon = exports.name = exports.id = void 0; -const cheerio_1 = require("cheerio"); -// import dayjs from 'dayjs'; -const fetch_1 = require("@libs/fetch"); -// import { parseMadaraDate } from "@libs/parseMadaraDate"; -// import { isUrlAbsolute } from '@libs/isAbsoluteUrl'; -// import { showToast } from "@libs/showToast"; -const filterInputs_1 = require("@libs/filterInputs"); -const novelStatus_1 = require("@libs/novelStatus"); -// import { defaultCover } from "@libs/defaultCover"; -exports.id = "erolate"; -exports.name = "Erolate"; -exports.icon = "multisrc/rulate/icons/erolate.png"; -exports.version = "1.0.0"; -exports.site = "https://erolate.com"; -const popularNovels = function (page, { filters, showLatestNovels }) { - return __awaiter(this, void 0, void 0, function* () { - let url = exports.site + '/search?t='; - url += '&cat=' + ((filters === null || filters === void 0 ? void 0 : filters.cat) || '0'); - url += '&s_lang=' + ((filters === null || filters === void 0 ? void 0 : filters.s_lang) || '0'); - url += '&t_lang=' + ((filters === null || filters === void 0 ? void 0 : filters.t_lang) || '0'); - url += '&type=' + ((filters === null || filters === void 0 ? void 0 : filters.type) || '0'); - url += '&sort=' + (showLatestNovels ? '4' : ((filters === null || filters === void 0 ? void 0 : filters.sort) || '6')); - url += '&atmosphere=' + ((filters === null || filters === void 0 ? void 0 : filters.atmosphere) || '0'); - url += '&adult=' + ((filters === null || filters === void 0 ? void 0 : filters.adult) || '0'); - if ((filters === null || filters === void 0 ? void 0 : filters.genres) instanceof Array) { - url += filters.genres.map(i => '&genres[]=' + i).join(''); - } - if ((filters === null || filters === void 0 ? void 0 : filters.genres_ex) instanceof Array) { - url += filters.genres_ex.map(i => '&genres_ex[]=' + i).join(''); - } - if ((filters === null || filters === void 0 ? void 0 : filters.tags) instanceof Array) { - url += filters.tags.map(i => '&tags[]=' + i).join(''); - } - if ((filters === null || filters === void 0 ? void 0 : filters.tags_ex) instanceof Array) { - url += filters.tags_ex.map(i => '&tags_ex[]=' + i).join(''); - } - if ((filters === null || filters === void 0 ? void 0 : filters.fandoms) instanceof Array) { - url += filters.fandoms.map(i => '&fandoms[]=' + i).join(''); - } - if ((filters === null || filters === void 0 ? void 0 : filters.fandoms_ex) instanceof Array) { - url += filters.fandoms_ex.map(i => '&fandoms_ex[]=' + i).join(''); - } - if ((filters === null || filters === void 0 ? void 0 : filters.trash) instanceof Array) { - url += filters.trash.map(i => '&' + i + '=1').join(''); - } - url += '&Book_page=' + page; - const result = yield (0, fetch_1.fetchApi)(url); - const body = yield result.text(); - const loadedCheerio = (0, cheerio_1.load)(body); - const novels = []; - loadedCheerio('ul[class="search-results"] > li:not([class="ad_type_catalog"])').each(function () { - novels.push({ - name: loadedCheerio(this).find('p > a').text(), - cover: exports.site + loadedCheerio(this).find('img').attr('src'), - url: exports.site + loadedCheerio(this).find('p > a').attr('href') || '', - }); - }); - return novels; - }); -}; -exports.popularNovels = popularNovels; -const parseNovelAndChapters = function (novelUrl) { - return __awaiter(this, void 0, void 0, function* () { - const novel = { - url: novelUrl, - chapters: [], - }; - let result = yield (0, fetch_1.fetchApi)(novelUrl); - if (result.url.includes('mature?path=')) { - const formData = new FormData(); - formData.append('path', novelUrl); - formData.append('ok', 'Да'); - yield (0, fetch_1.fetchApi)(result.url, { - method: 'POST', - body: formData, - }); - result = yield (0, fetch_1.fetchApi)(novelUrl); - } - const body = yield result.text(); - const loadedCheerio = (0, cheerio_1.load)(body); - novel.name = loadedCheerio('div[class="container"] > div > div > h1, div.span8:nth-child(1) > h1:nth-child(2)') - .text() - .trim(); - novel.cover = - exports.site + loadedCheerio('div[class="images"] > div img').attr('src'); - novel.summary = loadedCheerio('#Info > div:nth-child(3), .book-description').text(); - novel.author = loadedCheerio('.book-stats-icons_author > span:nth-child(2) > a:nth-child(1)').text(); - let genres = []; - loadedCheerio('div.span5 > p, .span5 > div:nth-child(2) > p').each(function () { - switch (loadedCheerio(this).find('strong').text()) { - case 'Автор:': - novel.author = loadedCheerio(this).find('em > a').text().trim(); - break; - case 'Выпуск:': - novel.status = - loadedCheerio(this).find('em').text().trim() === 'продолжается' - ? novelStatus_1.NovelStatus.Ongoing - : novelStatus_1.NovelStatus.Completed; - break; - case 'Тэги:': - loadedCheerio(this) - .find('em > a') - .each(function () { - genres.push(loadedCheerio(this).text()); - }); - break; - case 'Жанры:': - loadedCheerio(this) - .find('em > a') - .each(function () { - genres.push(loadedCheerio(this).text()); - }); - break; - } - }); - if (genres.length > 0) { - novel.genres = genres.reverse().join(','); - } - const chapters = []; - loadedCheerio('table > tbody > tr.chapter_row').each(function () { - var _a; - const chapterName = loadedCheerio(this) - .find('td[class="t"] > a') - .text() - .trim(); - const releaseDate = (_a = loadedCheerio(this) - .find('td > span') - .attr('title')) === null || _a === void 0 ? void 0 : _a.trim(); - const chapterUrl = exports.site + loadedCheerio(this) - .find('td[class="t"] > a') - .attr('href'); - if (loadedCheerio(this).find('td > span[class="disabled"]').length < 1 && - releaseDate) { - chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); - } - }); - novel.chapters = chapters; - return novel; - }); -}; -exports.parseNovelAndChapters = parseNovelAndChapters; -const parseChapter = function (chapterUrl) { - return __awaiter(this, void 0, void 0, function* () { - let result = yield (0, fetch_1.fetchApi)(chapterUrl); - if (result.url.includes('mature?path=')) { - const formData = new FormData(); - formData.append('ok', 'Да'); - yield (0, fetch_1.fetchApi)(result.url, { - method: 'POST', - body: formData, - }); - result = yield (0, fetch_1.fetchApi)(chapterUrl); - } - const body = yield result.text(); - const loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.content-text img').each(function () { - var _a; - if (!((_a = loadedCheerio(this).attr('src')) === null || _a === void 0 ? void 0 : _a.startsWith('http'))) { - const src = loadedCheerio(this).attr('src'); - loadedCheerio(this).attr('src', exports.site + src); - } - }); - const chapterText = loadedCheerio('.content-text').html(); - return chapterText; - }); -}; -exports.parseChapter = parseChapter; -const searchNovels = (searchTerm) => __awaiter(void 0, void 0, void 0, function* () { - const novels = []; - const result = yield (0, fetch_1.fetchApi)(exports.site + '/search/autocomplete?query=' + searchTerm); - let json = yield result.json(); - json.forEach((item) => { - const novelName = item.title_one + ' / ' + item.title_two; - const novelCover = exports.site + item.img; - const novelUrl = exports.site + item.url; - novels.push({ name: novelName, cover: novelCover, url: novelUrl }); - }); - return novels; -}); -exports.searchNovels = searchNovels; -; -exports.fetchImage = fetch_1.fetchFile; -exports.filters = [{ "key": "cat", "label": "Из раздела каталога:", "values": [{ "label": "Неважно", "value": "0" }, { "label": "Авторские", "value": "12" }, { "label": "Авторские", "value": "35" }, { "label": "Английские", "value": "34" }, { "label": "Игры 18+", "value": "3" }, { "label": "Китайские", "value": "31" }, { "label": "Комиксы", "value": "29" }, { "label": "Корейские", "value": "33" }, { "label": "Манга для взрослых", "value": "30" }, { "label": "Машинный перевод", "value": "38" }, { "label": "Переводы", "value": "15" }, { "label": "Фанфики", "value": "16" }, { "label": "Эротические рассказы", "value": "2" }], "inputType": filterInputs_1.FilterInputs.Picker }, { "key": "s_lang", "label": "Язык оригинала:", "values": [{ "label": "Неважно", "value": "0" }, { "label": "Абхазский", "value": "20" }, { "label": "Аварский", "value": "21" }, { "label": "Азербайджанский", "value": "22" }, { "label": "Аймара", "value": "23" }, { "label": "Акан", "value": "24" }, { "label": "Албанский", "value": "25" }, { "label": "Амхарский", "value": "26" }, { "label": "Английский", "value": "2" }, { "label": "Арабский", "value": "27" }, { "label": "Арагонский", "value": "28" }, { "label": "Арберешский", "value": "29" }, { "label": "Армянский", "value": "30" }, { "label": "Ассамский", "value": "31" }, { "label": "Астурийский", "value": "32" }, { "label": "Афарский", "value": "33" }, { "label": "Африкаанс", "value": "34" }, { "label": "Ацтекский", "value": "35" }, { "label": "Баварский", "value": "36" }, { "label": "Бамбарийский", "value": "37" }, { "label": "Баскский", "value": "39" }, { "label": "Башкирский", "value": "40" }, { "label": "Белорусский", "value": "10" }, { "label": "Бенгальский", "value": "41" }, { "label": "Бирманский", "value": "42" }, { "label": "Бислама", "value": "43" }, { "label": "Бихари", "value": "44" }, { "label": "Болгарский", "value": "45" }, { "label": "Боснийский", "value": "234" }, { "label": "Бретонский", "value": "47" }, { "label": "Валенсийский", "value": "48" }, { "label": "Валлийский", "value": "49" }, { "label": "Валлонский", "value": "50" }, { "label": "Венгерский", "value": "51" }, { "label": "Венда", "value": "52" }, { "label": "Венетский", "value": "53" }, { "label": "Верхнелужицкий", "value": "54" }, { "label": "Волоф", "value": "55" }, { "label": "Вьетнамский", "value": "57" }, { "label": "Гавайский", "value": "58" }, { "label": "Гаитянский", "value": "59" }, { "label": "Галисийский", "value": "60" }, { "label": "Гереро", "value": "61" }, { "label": "Голландский", "value": "62" }, { "label": "Греческий", "value": "63" }, { "label": "Грузинский", "value": "64" }, { "label": "Гуарани", "value": "65" }, { "label": "Гуджарати", "value": "66" }, { "label": "Датский", "value": "19" }, { "label": "Дзонг-кэ", "value": "68" }, { "label": "Древнегреческий", "value": "69" }, { "label": "Западно-фламандский", "value": "70" }, { "label": "Зулу", "value": "71" }, { "label": "Иврит", "value": "15" }, { "label": "Игбо", "value": "72" }, { "label": "Идиш", "value": "73" }, { "label": "Илоко", "value": "74" }, { "label": "Индонезийский", "value": "75" }, { "label": "Интерлингва", "value": "76" }, { "label": "Инуктитут", "value": "77" }, { "label": "Инупиак", "value": "78" }, { "label": "Ирландский", "value": "79" }, { "label": "Исландский", "value": "80" }, { "label": "Испанский", "value": "6" }, { "label": "Итальянский", "value": "5" }, { "label": "Йоруба", "value": "81" }, { "label": "Кабильский", "value": "82" }, { "label": "Казахский", "value": "83" }, { "label": "Калмыцкий", "value": "235" }, { "label": "Каннада", "value": "84" }, { "label": "Кантонский юэ", "value": "85" }, { "label": "Канури", "value": "86" }, { "label": "Каталанский", "value": "87" }, { "label": "Кашмири", "value": "88" }, { "label": "Кечуа", "value": "90" }, { "label": "Кикуйю", "value": "91" }, { "label": "Киньяруанда", "value": "92" }, { "label": "Киргизский", "value": "93" }, { "label": "Китайский", "value": "7" }, { "label": "Клингонский", "value": "94" }, { "label": "Коми", "value": "95" }, { "label": "Конго", "value": "96" }, { "label": "Конкани", "value": "97" }, { "label": "Корейский", "value": "98" }, { "label": "Корсиканский", "value": "100" }, { "label": "Котава", "value": "101" }, { "label": "Кри", "value": "102" }, { "label": "Курдский", "value": "105" }, { "label": "Кхмерский", "value": "107" }, { "label": "Лакский", "value": "233" }, { "label": "Лаосский", "value": "109" }, { "label": "Латынь", "value": "110" }, { "label": "Латышский", "value": "111" }, { "label": "Лезгинский", "value": "112" }, { "label": "Лимбургский", "value": "113" }, { "label": "Лингала", "value": "114" }, { "label": "Литовский", "value": "115" }, { "label": "Луба", "value": "118" }, { "label": "Луганда", "value": "119" }, { "label": "Люксембургский", "value": "120" }, { "label": "Македонский", "value": "121" }, { "label": "Малагасийский", "value": "122" }, { "label": "Малайский", "value": "123" }, { "label": "Мальдивский", "value": "125" }, { "label": "Мальтийский", "value": "126" }, { "label": "Маори", "value": "127" }, { "label": "Марийский", "value": "232" }, { "label": "Маршалльский", "value": "130" }, { "label": "Молдавский", "value": "11" }, { "label": "Монгольский", "value": "133" }, { "label": "Мяо (хмонг)", "value": "209" }, { "label": "Навахо", "value": "135" }, { "label": "Неаполитанский", "value": "139" }, { "label": "Немецкий", "value": "3" }, { "label": "Непальский", "value": "140" }, { "label": "Норвежский", "value": "18" }, { "label": "Осетинский", "value": "147" }, { "label": "Пакистанский", "value": "230" }, { "label": "Пенджабский", "value": "149" }, { "label": "Персидский", "value": "151" }, { "label": "Польский", "value": "152" }, { "label": "Португальский", "value": "153" }, { "label": "Румынский", "value": "158" }, { "label": "Русский", "value": "1" }, { "label": "Санскрит", "value": "163" }, { "label": "Сардинский", "value": "164" }, { "label": "Сербохорватский", "value": "166" }, { "label": "Словацкий", "value": "170" }, { "label": "Словенский", "value": "171" }, { "label": "Сомали", "value": "172" }, { "label": "Старотурецкий", "value": "174" }, { "label": "Суахили", "value": "175" }, { "label": "Сунданский", "value": "176" }, { "label": "Тагальский", "value": "177" }, { "label": "Таджикский", "value": "178" }, { "label": "Таитянский", "value": "179" }, { "label": "Тайваньский", "value": "180" }, { "label": "Тайский", "value": "181" }, { "label": "Тамильский", "value": "182" }, { "label": "Татарский", "value": "12" }, { "label": "Телугу", "value": "184" }, { "label": "Тибетский", "value": "185" }, { "label": "Тигринья", "value": "186" }, { "label": "Ток-писин", "value": "187" }, { "label": "Токи пона", "value": "188" }, { "label": "Тонганский", "value": "189" }, { "label": "Тсвана", "value": "191" }, { "label": "Тсонга", "value": "192" }, { "label": "Турецкий", "value": "193" }, { "label": "Туркменский", "value": "194" }, { "label": "Удмуртский", "value": "196" }, { "label": "Узбекский", "value": "197" }, { "label": "Уйгурский", "value": "198" }, { "label": "Украинский", "value": "9" }, { "label": "Фиджийский", "value": "201" }, { "label": "Филиппинский", "value": "229" }, { "label": "Финский", "value": "17" }, { "label": "Французский", "value": "4" }, { "label": "Фризский", "value": "203" }, { "label": "Фулах", "value": "204" }, { "label": "Хауса", "value": "206" }, { "label": "Хинди", "value": "207" }, { "label": "Хири-моту", "value": "208" }, { "label": "Чеченский", "value": "213" }, { "label": "Чешский", "value": "13" }, { "label": "Чувашский", "value": "217" }, { "label": "Шведский", "value": "16" }, { "label": "Швейцарский немецкий", "value": "218" }, { "label": "Шона", "value": "219" }, { "label": "Шотландский", "value": "67" }, { "label": "Эве", "value": "221" }, { "label": "Эскимосский", "value": "223" }, { "label": "Эсперанто", "value": "14" }, { "label": "Эстонский", "value": "224" }, { "label": "Южно-корейский", "value": "231" }, { "label": "Юкатекский", "value": "225" }, { "label": "Яванский", "value": "227" }, { "label": "Японский", "value": "8" }], "inputType": filterInputs_1.FilterInputs.Picker }, { "key": "t_lang", "label": "Язык перевода:", "values": [{ "label": "Неважно", "value": "0" }, { "label": "Абхазский", "value": "20" }, { "label": "Аварский", "value": "21" }, { "label": "Азербайджанский", "value": "22" }, { "label": "Аймара", "value": "23" }, { "label": "Акан", "value": "24" }, { "label": "Албанский", "value": "25" }, { "label": "Амхарский", "value": "26" }, { "label": "Английский", "value": "2" }, { "label": "Арабский", "value": "27" }, { "label": "Арагонский", "value": "28" }, { "label": "Арберешский", "value": "29" }, { "label": "Армянский", "value": "30" }, { "label": "Ассамский", "value": "31" }, { "label": "Астурийский", "value": "32" }, { "label": "Афарский", "value": "33" }, { "label": "Африкаанс", "value": "34" }, { "label": "Ацтекский", "value": "35" }, { "label": "Баварский", "value": "36" }, { "label": "Бамбарийский", "value": "37" }, { "label": "Баскский", "value": "39" }, { "label": "Башкирский", "value": "40" }, { "label": "Белорусский", "value": "10" }, { "label": "Бенгальский", "value": "41" }, { "label": "Бирманский", "value": "42" }, { "label": "Бислама", "value": "43" }, { "label": "Бихари", "value": "44" }, { "label": "Болгарский", "value": "45" }, { "label": "Боснийский", "value": "234" }, { "label": "Бретонский", "value": "47" }, { "label": "Валенсийский", "value": "48" }, { "label": "Валлийский", "value": "49" }, { "label": "Валлонский", "value": "50" }, { "label": "Венгерский", "value": "51" }, { "label": "Венда", "value": "52" }, { "label": "Венетский", "value": "53" }, { "label": "Верхнелужицкий", "value": "54" }, { "label": "Волоф", "value": "55" }, { "label": "Вьетнамский", "value": "57" }, { "label": "Гавайский", "value": "58" }, { "label": "Гаитянский", "value": "59" }, { "label": "Галисийский", "value": "60" }, { "label": "Гереро", "value": "61" }, { "label": "Голландский", "value": "62" }, { "label": "Греческий", "value": "63" }, { "label": "Грузинский", "value": "64" }, { "label": "Гуарани", "value": "65" }, { "label": "Гуджарати", "value": "66" }, { "label": "Датский", "value": "19" }, { "label": "Дзонг-кэ", "value": "68" }, { "label": "Древнегреческий", "value": "69" }, { "label": "Западно-фламандский", "value": "70" }, { "label": "Зулу", "value": "71" }, { "label": "Иврит", "value": "15" }, { "label": "Игбо", "value": "72" }, { "label": "Идиш", "value": "73" }, { "label": "Илоко", "value": "74" }, { "label": "Индонезийский", "value": "75" }, { "label": "Интерлингва", "value": "76" }, { "label": "Инуктитут", "value": "77" }, { "label": "Инупиак", "value": "78" }, { "label": "Ирландский", "value": "79" }, { "label": "Исландский", "value": "80" }, { "label": "Испанский", "value": "6" }, { "label": "Итальянский", "value": "5" }, { "label": "Йоруба", "value": "81" }, { "label": "Кабильский", "value": "82" }, { "label": "Казахский", "value": "83" }, { "label": "Калмыцкий", "value": "235" }, { "label": "Каннада", "value": "84" }, { "label": "Кантонский юэ", "value": "85" }, { "label": "Канури", "value": "86" }, { "label": "Каталанский", "value": "87" }, { "label": "Кашмири", "value": "88" }, { "label": "Кечуа", "value": "90" }, { "label": "Кикуйю", "value": "91" }, { "label": "Киньяруанда", "value": "92" }, { "label": "Киргизский", "value": "93" }, { "label": "Китайский", "value": "7" }, { "label": "Клингонский", "value": "94" }, { "label": "Коми", "value": "95" }, { "label": "Конго", "value": "96" }, { "label": "Конкани", "value": "97" }, { "label": "Корейский", "value": "98" }, { "label": "Корсиканский", "value": "100" }, { "label": "Котава", "value": "101" }, { "label": "Кри", "value": "102" }, { "label": "Курдский", "value": "105" }, { "label": "Кхмерский", "value": "107" }, { "label": "Лакский", "value": "233" }, { "label": "Лаосский", "value": "109" }, { "label": "Латынь", "value": "110" }, { "label": "Латышский", "value": "111" }, { "label": "Лезгинский", "value": "112" }, { "label": "Лимбургский", "value": "113" }, { "label": "Лингала", "value": "114" }, { "label": "Литовский", "value": "115" }, { "label": "Луба", "value": "118" }, { "label": "Луганда", "value": "119" }, { "label": "Люксембургский", "value": "120" }, { "label": "Македонский", "value": "121" }, { "label": "Малагасийский", "value": "122" }, { "label": "Малайский", "value": "123" }, { "label": "Мальдивский", "value": "125" }, { "label": "Мальтийский", "value": "126" }, { "label": "Маори", "value": "127" }, { "label": "Марийский", "value": "232" }, { "label": "Маршалльский", "value": "130" }, { "label": "Молдавский", "value": "11" }, { "label": "Монгольский", "value": "133" }, { "label": "Мяо (хмонг)", "value": "209" }, { "label": "Навахо", "value": "135" }, { "label": "Неаполитанский", "value": "139" }, { "label": "Немецкий", "value": "3" }, { "label": "Непальский", "value": "140" }, { "label": "Норвежский", "value": "18" }, { "label": "Осетинский", "value": "147" }, { "label": "Пакистанский", "value": "230" }, { "label": "Пенджабский", "value": "149" }, { "label": "Персидский", "value": "151" }, { "label": "Польский", "value": "152" }, { "label": "Португальский", "value": "153" }, { "label": "Румынский", "value": "158" }, { "label": "Русский", "value": "1" }, { "label": "Санскрит", "value": "163" }, { "label": "Сардинский", "value": "164" }, { "label": "Сербохорватский", "value": "166" }, { "label": "Словацкий", "value": "170" }, { "label": "Словенский", "value": "171" }, { "label": "Сомали", "value": "172" }, { "label": "Старотурецкий", "value": "174" }, { "label": "Суахили", "value": "175" }, { "label": "Сунданский", "value": "176" }, { "label": "Тагальский", "value": "177" }, { "label": "Таджикский", "value": "178" }, { "label": "Таитянский", "value": "179" }, { "label": "Тайваньский", "value": "180" }, { "label": "Тайский", "value": "181" }, { "label": "Тамильский", "value": "182" }, { "label": "Татарский", "value": "12" }, { "label": "Телугу", "value": "184" }, { "label": "Тибетский", "value": "185" }, { "label": "Тигринья", "value": "186" }, { "label": "Ток-писин", "value": "187" }, { "label": "Токи пона", "value": "188" }, { "label": "Тонганский", "value": "189" }, { "label": "Тсвана", "value": "191" }, { "label": "Тсонга", "value": "192" }, { "label": "Турецкий", "value": "193" }, { "label": "Туркменский", "value": "194" }, { "label": "Удмуртский", "value": "196" }, { "label": "Узбекский", "value": "197" }, { "label": "Уйгурский", "value": "198" }, { "label": "Украинский", "value": "9" }, { "label": "Фиджийский", "value": "201" }, { "label": "Филиппинский", "value": "229" }, { "label": "Финский", "value": "17" }, { "label": "Французский", "value": "4" }, { "label": "Фризский", "value": "203" }, { "label": "Фулах", "value": "204" }, { "label": "Хауса", "value": "206" }, { "label": "Хинди", "value": "207" }, { "label": "Хири-моту", "value": "208" }, { "label": "Чеченский", "value": "213" }, { "label": "Чешский", "value": "13" }, { "label": "Чувашский", "value": "217" }, { "label": "Шведский", "value": "16" }, { "label": "Швейцарский немецкий", "value": "218" }, { "label": "Шона", "value": "219" }, { "label": "Шотландский", "value": "67" }, { "label": "Эве", "value": "221" }, { "label": "Эскимосский", "value": "223" }, { "label": "Эсперанто", "value": "14" }, { "label": "Эстонский", "value": "224" }, { "label": "Южно-корейский", "value": "231" }, { "label": "Юкатекский", "value": "225" }, { "label": "Яванский", "value": "227" }, { "label": "Японский", "value": "8" }], "inputType": filterInputs_1.FilterInputs.Picker }, { "key": "type", "label": "Тип:", "values": [{ "label": "Неважно", "value": "0" }, { "label": "Только авторские", "value": "2" }, { "label": "Только переводы", "value": "1" }], "inputType": filterInputs_1.FilterInputs.Picker }, { "key": "trash", "label": "Другое:", "values": [{ "label": "Без фэндомов", "value": "fandoms_ex_all" }, { "label": "Готовые на 100%", "value": "ready" }, { "label": "Доступные для перевода", "value": "tr" }, { "label": "Доступные для скачивания", "value": "gen" }, { "label": "Завершённые проекты", "value": "wealth" }, { "label": "Распродажа", "value": "discount" }, { "label": "Только онгоинги", "value": "ongoings" }, { "label": "Убрать машинный", "value": "remove_machinelate" }], "inputType": filterInputs_1.FilterInputs.Checkbox }, { "key": "sort", "label": "Сортировка:", "values": [{ "label": "По рейтингу", "value": "6" }, { "label": "По дате последней активности", "value": "4" }, { "label": "По дате создания", "value": "3" }, { "label": "По кол-ву бесплатных глав", "value": "11" }, { "label": "По кол-ву в закладках", "value": "13" }, { "label": "По кол-ву в избранном", "value": "14" }, { "label": "По кол-ву лайков", "value": "8" }, { "label": "По кол-ву переведённых глав", "value": "7" }, { "label": "По кол-ву рецензий", "value": "12" }, { "label": "По кол-ву страниц", "value": "10" }, { "label": "По названию на языке оригинала", "value": "1" }, { "label": "По названию на языке перевода", "value": "2" }, { "label": "По просмотрам", "value": "5" }, { "label": "По степени готовности", "value": "0" }, { "label": "Случайно", "value": "9" }], "inputType": filterInputs_1.FilterInputs.Picker }, { "key": "genres", "label": "Жанры:", "values": [{ "label": "Анал", "value": "2" }, { "label": "Бдсм", "value": "3" }, { "label": "Большая грудь", "value": "5" }, { "label": "Большая попка", "value": "6" }, { "label": "Большой член", "value": "7" }, { "label": "Бондаж", "value": "8" }, { "label": "В первый раз", "value": "9" }, { "label": "В цвете", "value": "10" }, { "label": "Гарем", "value": "11" }, { "label": "Гендарная интрига", "value": "12" }, { "label": "Групповой секс", "value": "13" }, { "label": "Детектив", "value": "39" }, { "label": "Драма", "value": "14" }, { "label": "Зрелые женщины (milf)", "value": "15" }, { "label": "Измена", "value": "16" }, { "label": "Изнасилование", "value": "17" }, { "label": "Инцест", "value": "18" }, { "label": "Исторический", "value": "19" }, { "label": "Комедия", "value": "20" }, { "label": "Контроль над разумом", "value": "35" }, { "label": "Маленькая грудь", "value": "21" }, { "label": "Мистика", "value": "40" }, { "label": "Научная фантастика", "value": "22" }, { "label": "Нетораре", "value": "23" }, { "label": "Оральный секс", "value": "24" }, { "label": "Повседневность", "value": "41" }, { "label": "Приключения", "value": "38" }, { "label": "Публичный секс", "value": "33" }, { "label": "Романтика", "value": "25" }, { "label": "С изображениями", "value": "36" }, { "label": "Сверхъестественное", "value": "34" }, { "label": "Смат", "value": "37" }, { "label": "Тентакли", "value": "26" }, { "label": "Трагедия", "value": "27" }, { "label": "Ужасы", "value": "28" }, { "label": "Фантастика", "value": "32" }, { "label": "Фэнтези", "value": "29" }, { "label": "Чикан", "value": "30" }, { "label": "Этти", "value": "31" }, { "label": "Ahegao", "value": "1" }], "inputType": filterInputs_1.FilterInputs.Checkbox }, { "key": "tags", "label": "Тэги:", "values": [{ "label": "+18", "value": "141" }, { "label": "18+", "value": "200" }, { "label": "21+", "value": "334" }, { "label": "Адекватные главные герои", "value": "253" }, { "label": "Азартные игры", "value": "210" }, { "label": "Айдолы", "value": "364" }, { "label": "Акула", "value": "53" }, { "label": "Альтернативное развитие событий", "value": "338" }, { "label": "Аморальный главный герой", "value": "219" }, { "label": "Анал", "value": "7" }, { "label": "Анальный секс", "value": "67" }, { "label": "Ангелы", "value": "114" }, { "label": "Антигерой", "value": "226" }, { "label": "Аристократия", "value": "260" }, { "label": "Артефакт", "value": "379" }, { "label": "Афродизиак", "value": "276" }, { "label": "Ахегао", "value": "240" }, { "label": "Бабушка беременна от внука", "value": "393" }, { "label": "Бабушка и внук", "value": "380" }, { "label": "Бдсм", "value": "131" }, { "label": "Беременность", "value": "148" }, { "label": "Бесплатно", "value": "79" }, { "label": "Бесстрашные персонажи", "value": "339" }, { "label": "Библиотека", "value": "265" }, { "label": "Бистиалити", "value": "391" }, { "label": "Битва за трон", "value": "404" }, { "label": "Близнецы", "value": "198" }, { "label": "Блондинка", "value": "91" }, { "label": "Богатые персонажи", "value": "248" }, { "label": "Боги", "value": "115" }, { "label": "Боевик", "value": "252" }, { "label": "Большая грудь", "value": "33" }, { "label": "Большая попка", "value": "328" }, { "label": "Большой член", "value": "76" }, { "label": "Большой член сына", "value": "396" }, { "label": "Босс и подчиненный", "value": "330" }, { "label": "Брак", "value": "182" }, { "label": "Брак по расчёту", "value": "346" }, { "label": "Брат", "value": "29" }, { "label": "Брат и сестра", "value": "30" }, { "label": "Брюнетка", "value": "28" }, { "label": "Бэтмен", "value": "369" }, { "label": "Бэтмен", "value": "170" }, { "label": "В первый раз", "value": "179" }, { "label": "Вагинальный секс", "value": "57" }, { "label": "Вагинальный секс", "value": "171" }, { "label": "Вайурист", "value": "9" }, { "label": "Вампиры", "value": "133" }, { "label": "Ван-пис", "value": "335" }, { "label": "Веб камера", "value": "289" }, { "label": "Ведьмы", "value": "232" }, { "label": "Викинги", "value": "307" }, { "label": "Виртуальная реальность", "value": "382" }, { "label": "Вирус", "value": "203" }, { "label": "Внучка", "value": "189" }, { "label": "Война", "value": "387" }, { "label": "Воспоминания из прошлого", "value": "405" }, { "label": "Враги становятся любовниками", "value": "410" }, { "label": "Время", "value": "81" }, { "label": "Второй шанс", "value": "244" }, { "label": "Вуайеризм", "value": "62" }, { "label": "Выживание", "value": "135" }, { "label": "Гарем", "value": "107" }, { "label": "Гарри поттер", "value": "97" }, { "label": "Гвен", "value": "402" }, { "label": "Гг имба", "value": "87" }, { "label": "Генетические модификации", "value": "314" }, { "label": "Гипноз", "value": "143" }, { "label": "Главная героиня девушка", "value": "147" }, { "label": "Главный герой женщина", "value": "213" }, { "label": "Главный герой извращенец", "value": "116" }, { "label": "Главный герой мужчина", "value": "117" }, { "label": "Глубокое горло", "value": "94" }, { "label": "Гоблины", "value": "230" }, { "label": "Город", "value": "139" }, { "label": "Городское фэнтези", "value": "297" }, { "label": "Грудное молоко", "value": "225" }, { "label": "Групповой секс", "value": "72" }, { "label": "Гэнг-бэнг", "value": "235" }, { "label": "Гяру", "value": "222" }, { "label": "Двойное проникновение", "value": "42" }, { "label": "Двойной анал", "value": "47" }, { "label": "Дворяне", "value": "246" }, { "label": "Деамоны старший школы", "value": "291" }, { "label": "Девственница", "value": "119" }, { "label": "Девушки-монстры", "value": "223" }, { "label": "Демоны", "value": "98" }, { "label": "Детектив", "value": "249" }, { "label": "Дзёсэй", "value": "259" }, { "label": "Доктор", "value": "326" }, { "label": "Дом", "value": "138" }, { "label": "Доминирование", "value": "18" }, { "label": "Дочь", "value": "153" }, { "label": "Дочь беременна от отца", "value": "348" }, { "label": "Древние времена", "value": "383" }, { "label": "Древний китай", "value": "261" }, { "label": "Другой мир", "value": "365" }, { "label": "Дружба", "value": "325" }, { "label": "Друзья детства", "value": "183" }, { "label": "Дядя", "value": "160" }, { "label": "Жена", "value": "70" }, { "label": "Жена и муж", "value": "99" }, { "label": "Жена шлюха", "value": "236" }, { "label": "Женское доминирование", "value": "100" }, { "label": "Жесткий секс", "value": "283" }, { "label": "Жёсткий секс", "value": "101" }, { "label": "Жестокие персонажи", "value": "254" }, { "label": "Жестокий мир", "value": "336" }, { "label": "Жестокость", "value": "123" }, { "label": "Заботливый главный герой", "value": "340" }, { "label": "Зависимость", "value": "370" }, { "label": "Заключение", "value": "196" }, { "label": "Заключённые", "value": "384" }, { "label": "Замок", "value": "140" }, { "label": "Запретная любовь", "value": "273" }, { "label": "Заражение", "value": "206" }, { "label": "Звёздные войны", "value": "120" }, { "label": "Зверодевочки", "value": "158" }, { "label": "Зло", "value": "343" }, { "label": "Золовка", "value": "77" }, { "label": "Золотой дождь", "value": "146" }, { "label": "Зомби апокалипсис", "value": "241" }, { "label": "Зоофилия", "value": "144" }, { "label": "Зрелые женщины", "value": "398" }, { "label": "Игровые элементы", "value": "385" }, { "label": "Извращения", "value": "192" }, { "label": "Измена", "value": "71" }, { "label": "Изменения внешности", "value": "315" }, { "label": "Изменения личности", "value": "316" }, { "label": "Изнасилование", "value": "275" }, { "label": "Изуку мидория", "value": "337" }, { "label": "Ино", "value": "127" }, { "label": "Инопланетяне", "value": "304" }, { "label": "Интересный сюжет", "value": "349" }, { "label": "Интимные сцены", "value": "322" }, { "label": "Интриги и заговоры", "value": "262" }, { "label": "Интроверт", "value": "38" }, { "label": "Инфекция", "value": "207" }, { "label": "Инцест", "value": "35" }, { "label": "Исторический роман", "value": "406" }, { "label": "Камера", "value": "92" }, { "label": "Колледж", "value": "82" }, { "label": "Комикс", "value": "286" }, { "label": "Контроль", "value": "19" }, { "label": "Контроль над разумом", "value": "181" }, { "label": "Контроль разума", "value": "65" }, { "label": "Кончил внутрь", "value": "221" }, { "label": "Королевская семья", "value": "358" }, { "label": "Коррупция", "value": "49" }, { "label": "Космос", "value": "204" }, { "label": "Красивая главная героиня", "value": "255" }, { "label": "Красивые женщины", "value": "321" }, { "label": "Красивый главный герой", "value": "266" }, { "label": "Ксенофилия", "value": "386" }, { "label": "Кулинария", "value": "362" }, { "label": "Культвация", "value": "86" }, { "label": "Кунилингус", "value": "152" }, { "label": "Кушина", "value": "399" }, { "label": "Лактация", "value": "11" }, { "label": "Лесби", "value": "408" }, { "label": "Лишение девственности", "value": "212" }, { "label": "Лоли", "value": "218" }, { "label": "Лунатизм", "value": "279" }, { "label": "Любовь", "value": "89" }, { "label": "Магический мир", "value": "357" }, { "label": "Магия", "value": "80" }, { "label": "Мама", "value": "3" }, { "label": "Мама беременна от сына", "value": "274" }, { "label": "Мама и дочь", "value": "163" }, { "label": "Мама и сын", "value": "1" }, { "label": "Мама супермена", "value": "39" }, { "label": "Манипуляция временем", "value": "292" }, { "label": "Марвел", "value": "290" }, { "label": "Марвел", "value": "173" }, { "label": "Марти стью", "value": "102" }, { "label": "Массаж", "value": "224" }, { "label": "Мастурбация", "value": "63" }, { "label": "Мать", "value": "239" }, { "label": "Мать и дочь", "value": "381" }, { "label": "Мать и сын", "value": "237" }, { "label": "Мафия", "value": "256" }, { "label": "Мачеха", "value": "197" }, { "label": "Мачеха беременна от сына", "value": "395" }, { "label": "Мачеха и сын", "value": "394" }, { "label": "Медсестра", "value": "341" }, { "label": "Межрассовый", "value": "54" }, { "label": "Месть", "value": "306" }, { "label": "Меха", "value": "268" }, { "label": "Ми", "value": "243" }, { "label": "Милф", "value": "34" }, { "label": "Милф", "value": "180" }, { "label": "Минет", "value": "52" }, { "label": "Мистика", "value": "250" }, { "label": "Младшая сестра", "value": "154" }, { "label": "Много спермы", "value": "409" }, { "label": "Модель", "value": "324" }, { "label": "Монстры", "value": "333" }, { "label": "Мошеничество", "value": "44" }, { "label": "Мужская беременность", "value": "363" }, { "label": "Мужчина протагонист", "value": "108" }, { "label": "Музыка", "value": "331" }, { "label": "Мэри съюха", "value": "309" }, { "label": "Наруко", "value": "400" }, { "label": "Наруто", "value": "46" }, { "label": "Насилие", "value": "128" }, { "label": "Насилие и жестокость", "value": "193" }, { "label": "Научный эксперимент", "value": "313" }, { "label": "Нежить", "value": "373" }, { "label": "Некромантия", "value": "298" }, { "label": "Ненормативная лексика", "value": "124" }, { "label": "Нетораре", "value": "69" }, { "label": "Нетори", "value": "284" }, { "label": "Нижнее бельё", "value": "392" }, { "label": "Ниндзя", "value": "296" }, { "label": "Ношеные трусики", "value": "166" }, { "label": "Нудизм", "value": "156" }, { "label": "Няня", "value": "88" }, { "label": "Обмен женами", "value": "78" }, { "label": "Оборотни", "value": "136" }, { "label": "Обратный гарем", "value": "214" }, { "label": "Одержимость", "value": "345" }, { "label": "Омегаверс", "value": "368" }, { "label": "Оплодотворение", "value": "157" }, { "label": "Оральный секс", "value": "10" }, { "label": "Оргия", "value": "356" }, { "label": "Орки", "value": "388" }, { "label": "От слабого к сильному", "value": "351" }, { "label": "Отец", "value": "2" }, { "label": "Отец делится с сыном", "value": "6" }, { "label": "Отец и дочь", "value": "205" }, { "label": "Отец куколд", "value": "272" }, { "label": "Офис", "value": "234" }, { "label": "Падчерица", "value": "271" }, { "label": "Пайзури", "value": "195" }, { "label": "Папа и дочь", "value": "360" }, { "label": "Паразиты", "value": "208" }, { "label": "Параллельный мир", "value": "320" }, { "label": "Пародия", "value": "371" }, { "label": "Первый раз", "value": "159" }, { "label": "Перемещение в другой мир", "value": "347" }, { "label": "Перемещение во времени", "value": "245" }, { "label": "Перерождение", "value": "109" }, { "label": "Перерождение в злодея", "value": "202" }, { "label": "Пирсинг", "value": "145" }, { "label": "Писатель", "value": "267" }, { "label": "Планомерное развитие событий", "value": "350" }, { "label": "Повседневность", "value": "247" }, { "label": "Подглядывание", "value": "280" }, { "label": "Подчинение", "value": "106" }, { "label": "Подчинение и унижение", "value": "211" }, { "label": "Поедание киски", "value": "26" }, { "label": "Покемоны", "value": "132" }, { "label": "Покорная", "value": "8" }, { "label": "Полигамия", "value": "352" }, { "label": "Половое воспитание", "value": "37" }, { "label": "Полулюди", "value": "231" }, { "label": "Попаданец", "value": "103" }, { "label": "Попадание в книгу", "value": "361" }, { "label": "Порка", "value": "20" }, { "label": "Порно", "value": "278" }, { "label": "Постапокалипсис", "value": "332" }, { "label": "Потеря девственности", "value": "142" }, { "label": "Похищение", "value": "161" }, { "label": "Преданные любовный интерес", "value": "407" }, { "label": "Призраки", "value": "412" }, { "label": "Приключения", "value": "134" }, { "label": "Принуждение", "value": "66" }, { "label": "Психология", "value": "238" }, { "label": "Публично", "value": "85" }, { "label": "Публичный секс", "value": "233" }, { "label": "Раб", "value": "353" }, { "label": "Рабы", "value": "308" }, { "label": "Разват", "value": "58" }, { "label": "Разврат", "value": "64" }, { "label": "Райзен", "value": "95" }, { "label": "Раса инопланетных космических лесбиянок", "value": "294" }, { "label": "Религия", "value": "403" }, { "label": "Рестленг", "value": "84" }, { "label": "Риас гремори", "value": "389" }, { "label": "Романтика", "value": "178" }, { "label": "Рыжий", "value": "90" }, { "label": "С", "value": "413" }, { "label": "Сакура", "value": "126" }, { "label": "Самолет", "value": "93" }, { "label": "Санса старк", "value": "277" }, { "label": "Санта", "value": "372" }, { "label": "Свадьба", "value": "73" }, { "label": "Сверхсила", "value": "228" }, { "label": "Сверхъестественное", "value": "319" }, { "label": "Свингеры", "value": "201" }, { "label": "Свободные отношения", "value": "186" }, { "label": "Связывание", "value": "137" }, { "label": "Сёдзе", "value": "264" }, { "label": "Секс", "value": "21" }, { "label": "Секс без проникновения", "value": "68" }, { "label": "Секс втроем", "value": "43" }, { "label": "Секс игрушки", "value": "59" }, { "label": "Секс рабыня", "value": "55" }, { "label": "Секс с монстрами", "value": "56" }, { "label": "Секс с учителем", "value": "184" }, { "label": "Секса будет много", "value": "151" }, { "label": "Сексуальное желание", "value": "209" }, { "label": "Селфцест", "value": "397" }, { "label": "Семья", "value": "5" }, { "label": "Сестра", "value": "31" }, { "label": "Сестра беременна от брата", "value": "355" }, { "label": "Сильный с самого начала", "value": "112" }, { "label": "Симбиоз", "value": "50" }, { "label": "Сирена", "value": "51" }, { "label": "Система", "value": "104" }, { "label": "Сиськи", "value": "285" }, { "label": "Сквирт", "value": "164" }, { "label": "Скрытый секс", "value": "287" }, { "label": "Служанка", "value": "215" }, { "label": "Соб", "value": "281" }, { "label": "Соблазнение", "value": "162" }, { "label": "Современность", "value": "217" }, { "label": "Соколиный Глаз", "value": "176" }, { "label": "Соперничество", "value": "216" }, { "label": "Соседи", "value": "61" }, { "label": "Соседка", "value": "312" }, { "label": "Сперма", "value": "229" }, { "label": "Сперма на лицо", "value": "199" }, { "label": "Спящие", "value": "187" }, { "label": "Старшая сестра", "value": "311" }, { "label": "Стеб", "value": "111" }, { "label": "Студенты", "value": "177" }, { "label": "Суккуб", "value": "390" }, { "label": "Супергерои", "value": "305" }, { "label": "Суперспособности", "value": "300" }, { "label": "Сын", "value": "4" }, { "label": "Твинцест", "value": "188" }, { "label": "Темное фэнтези", "value": "293" }, { "label": "Тентакли", "value": "303" }, { "label": "Тетя", "value": "113" }, { "label": "Тетя беременна от племянника", "value": "376" }, { "label": "Тетя и племянник", "value": "377" }, { "label": "Техника", "value": "302" }, { "label": "Технологии", "value": "301" }, { "label": "Тёща", "value": "270" }, { "label": "Тиран", "value": "310" }, { "label": "Трагическое прошлое", "value": "251" }, { "label": "Трансмиграция", "value": "269" }, { "label": "Трансформация", "value": "317" }, { "label": "Триллер", "value": "344" }, { "label": "Трусики", "value": "165" }, { "label": "Убийства", "value": "258" }, { "label": "Удача", "value": "299" }, { "label": "Ужасы", "value": "375" }, { "label": "Улучшение тела", "value": "288" }, { "label": "Умная главная героиня", "value": "242" }, { "label": "Умные персонажи", "value": "257" }, { "label": "Умный главный герой", "value": "354" }, { "label": "Университет", "value": "323" }, { "label": "Ученик", "value": "83" }, { "label": "Ф", "value": "149" }, { "label": "Фанатичная любовь", "value": "366" }, { "label": "Фанаты", "value": "367" }, { "label": "Фантастика", "value": "295" }, { "label": "Фанфик", "value": "40" }, { "label": "Фелляция", "value": "22" }, { "label": "Ферма", "value": "191" }, { "label": "Фетиш", "value": "60" }, { "label": "Флэш", "value": "121" }, { "label": "Футанария", "value": "150" }, { "label": "Фэнтези", "value": "359" }, { "label": "Хентай", "value": "75" }, { "label": "Хината", "value": "110" }, { "label": "Холодная главная героиня", "value": "263" }, { "label": "Черная вдова", "value": "220" }, { "label": "Черная Вдова", "value": "175" }, { "label": "Черный юмор", "value": "374" }, { "label": "Читерство", "value": "45" }, { "label": "Чтение мыслей", "value": "227" }, { "label": "Чудовища", "value": "378" }, { "label": "Шантаж", "value": "129" }, { "label": "Школа", "value": "118" }, { "label": "Школьная жизнь", "value": "318" }, { "label": "Шлюха", "value": "32" }, { "label": "Шоу-бизнес", "value": "329" }, { "label": "Шоу-бизнес", "value": "172" }, { "label": "Эксгибиционизм", "value": "74" }, { "label": "Элементы бдсм", "value": "185" }, { "label": "Эмма уотсон", "value": "342" }, { "label": "Эмма Уотсон", "value": "169" }, { "label": "Эротика", "value": "36" }, { "label": "Этти", "value": "327" }, { "label": "Юмор", "value": "105" }, { "label": "Яндере", "value": "155" }, { "label": "Bl", "value": "125" }, { "label": "Dc", "value": "411" }, { "label": "Gl", "value": "96" }, { "label": "Harry potter", "value": "190" }, { "label": "Harry potter", "value": "168" }, { "label": "Hentai", "value": "282" }, { "label": "Marvel", "value": "194" }, { "label": "Marvel", "value": "174" }, { "label": "Milf", "value": "167" }, { "label": "Mj", "value": "401" }], "inputType": filterInputs_1.FilterInputs.Checkbox }, { "key": "fandoms", "label": "Фэндом:", "values": [{ "label": "Аватар: Легенда о Корре / Avatar legend of Korra", "value": "46" }, { "label": "Аватар: Легенда об Аанге / Avatar: The Legend of Aang / Avatar: The Last Airbender", "value": "45" }, { "label": "Аладдин / Aladdin", "value": "86" }, { "label": "Алиса в Стране чудес / Alice in Wonderland", "value": "90" }, { "label": "Американский папаша / American Dad", "value": "85" }, { "label": "Атака титанов / Атака на титанов / Attack on Titan", "value": "41" }, { "label": "Блич / Bleach", "value": "58" }, { "label": "Боевой континент", "value": "101" }, { "label": "Большой куш / One Piece", "value": "18" }, { "label": "Боруто: Новое поколение Наруто / Boruto: Naruto Next Generations", "value": "9" }, { "label": "Бэтмен / The Batman", "value": "36" }, { "label": "Ведьмак / The Witcher", "value": "53" }, { "label": "Военная хроника маленькой девочки", "value": "100" }, { "label": "Волейбол / Haikyu!!", "value": "37" }, { "label": "Вселенная Марвел / Marvel Universe", "value": "7" }, { "label": "Вселенная Марвел / Marvel Universe / Marvel Comics", "value": "52" }, { "label": "Вселенная Стивена", "value": "61" }, { "label": "Вселенная DC / DC Universe / DC Comics", "value": "48" }, { "label": "Гарри Поттер / Harry Potter", "value": "4" }, { "label": "Гоэтия / Гоетия / Yοητεία / Ars Goetia", "value": "77" }, { "label": "Демоны старшей школы / High School DxD", "value": "10" }, { "label": "День сурка / Groundhog Day", "value": "3" }, { "label": "Джессика Джонс / Marvel's Jessica Jones", "value": "42" }, { "label": "Дисней / The Walt Disney Company", "value": "74" }, { "label": "Древние свитки: Скайрим / TES: Skyrim", "value": "15" }, { "label": "Дэдпул / Deadpool", "value": "22" }, { "label": "Дэнни-призрак / Danny Phantom", "value": "51" }, { "label": "Железный человек / Iron Man", "value": "19" }, { "label": "Звёздная принцесса и силы зла / Стар против сил зла / Star vs. The Forces of Evil", "value": "50" }, { "label": "Звездные Войны / Star Wars", "value": "43" }, { "label": "Звёздные Войны / Star Wars", "value": "16" }, { "label": "Игра престолов", "value": "78" }, { "label": "Касльвания / Castlevania", "value": "29" }, { "label": "Киберпанк 2077 / Cyberpunk 2077", "value": "6" }, { "label": "Код Гиас / Code Geass", "value": "84" }, { "label": "Кольцо Элдена", "value": "60" }, { "label": "Королевства Сердец / Kingdom Hearts", "value": "93" }, { "label": "Красавица и чудовище / Beauty and the Beast", "value": "91" }, { "label": "Красный, Белый, Черный, Желтый / RWBY", "value": "32" }, { "label": "Кунг фу панда", "value": "81" }, { "label": "Лига Легенд / League of Legends", "value": "5" }, { "label": "Люди Икс / X-Men", "value": "25" }, { "label": "Маг на полную ставку / Quanzhi Fashi", "value": "30" }, { "label": "Мастера меча онлайн / Sword Art Online / SAO", "value": "47" }, { "label": "Мир Тьмы / World of Darkness", "value": "28" }, { "label": "Мой маленький пони / My Little Pony", "value": "72" }, { "label": "Мой маленький пони: Дружба — это чудо / My Little Pony: Friendship is Magic", "value": "71" }, { "label": "Моя геройская академия / Boku no Hero Academia", "value": "8" }, { "label": "Мстители / The Avengers", "value": "20" }, { "label": "Мстители. Эра Альтрона / The Avengers. Age of Ultron", "value": "24" }, { "label": "Мулан / Mulan", "value": "94" }, { "label": "Наруто / Naruto", "value": "2" }, { "label": "Овервотч", "value": "79" }, { "label": "Поднятие уровня в одиночку", "value": "87" }, { "label": "Порновселенная / Porn Universe", "value": "31" }, { "label": "Прототип / Prototype", "value": "44" }, { "label": "Рапунцель: Запутанная история / Tangled", "value": "96" }, { "label": "Розовая пора моей школьной жизни сплошной обман / Yahari Ore no Seishun Love Come wa Machigatteiru", "value": "14" }, { "label": "Русалочка / The Little Mermaid", "value": "97" }, { "label": "Сага о Винланде", "value": "66" }, { "label": "Светлячок / Firefly", "value": "76" }, { "label": "Сильнейший в истории ученик Кэнити / Shijou Saikyou no Deshi Kenichi", "value": "13" }, { "label": "Симпсоны / The Simpsons", "value": "73" }, { "label": "Судьба: Великий Приказ / Fate: Grand Order", "value": "54" }, { "label": "Супергёрл(телесериал, 2015) / Supergirl", "value": "95" }, { "label": "Супермен / Superman", "value": "1" }, { "label": "Теория большого взрыва / The Big Bang Theory", "value": "75" }, { "label": "Тор / Thor", "value": "27" }, { "label": "У Коми-сан проблемы с общением / 古見さんは、コミュ症です / Komi Can't Communicate", "value": "11" }, { "label": "Убийца Акаме / Akame ga Kill", "value": "40" }, { "label": "Уэнздей / Wednesday", "value": "26" }, { "label": "Фантастическая четвёрка / Fantastic Four", "value": "21" }, { "label": "Флэш / The Flash", "value": "17" }, { "label": "Хвост Феи / Fairy Tail", "value": "59" }, { "label": "Холодное сердце / Frozen", "value": "92" }, { "label": "Человек одного удара / Ванпанчмен / One Punch-Man", "value": "39" }, { "label": "Человек-паук / Spider-Man", "value": "23" }, { "label": "Чёрный зверь / Чёрный Пёс / Kuroinu", "value": "35" }, { "label": "Чёрный зверь: Развращение Благородных Воительниц / Black Beast: Corruption of the Noble Warriors", "value": "34" }, { "label": "Школа мертвецов", "value": "67" }, { "label": "Школа строгого режима / Prison School", "value": "12" }, { "label": "Эффект Массы / Mass Effect", "value": "57" }, { "label": "Юные Титаны / Teen Titans", "value": "49" }, { "label": "Ars Goetia | Gods and Demons", "value": "69" }, { "label": "Biohazard", "value": "99" }, { "label": "CL", "value": "70" }, { "label": "Daraku Reijou Hakoiri Ojou-sama Netorare Choukyou Kiroku", "value": "55" }, { "label": "Doom", "value": "64" }, { "label": "Granblue fantasy", "value": "88" }, { "label": "Halo", "value": "80" }, { "label": "Highschool of the Dead/Школа мертвецов", "value": "68" }, { "label": "JK Bitch ni Shiboraretai", "value": "56" }, { "label": "Monogatari Series", "value": "65" }, { "label": "Monster girl quest", "value": "62" }, { "label": "Over", "value": "102" }, { "label": "Rapunzel/Рапунцель", "value": "83" }, { "label": "Resident Evil", "value": "98" }, { "label": "Solo leveling", "value": "63" }, { "label": "Tentacle Locker", "value": "89" }, { "label": "X-COM", "value": "82" }], "inputType": filterInputs_1.FilterInputs.Checkbox }, { "key": "genres_ex", "label": "Исключить жанры:", "values": [{ "label": "Анал", "value": "2" }, { "label": "Бдсм", "value": "3" }, { "label": "Большая грудь", "value": "5" }, { "label": "Большая попка", "value": "6" }, { "label": "Большой член", "value": "7" }, { "label": "Бондаж", "value": "8" }, { "label": "В первый раз", "value": "9" }, { "label": "В цвете", "value": "10" }, { "label": "Гарем", "value": "11" }, { "label": "Гендарная интрига", "value": "12" }, { "label": "Групповой секс", "value": "13" }, { "label": "Детектив", "value": "39" }, { "label": "Драма", "value": "14" }, { "label": "Зрелые женщины (milf)", "value": "15" }, { "label": "Измена", "value": "16" }, { "label": "Изнасилование", "value": "17" }, { "label": "Инцест", "value": "18" }, { "label": "Исторический", "value": "19" }, { "label": "Комедия", "value": "20" }, { "label": "Контроль над разумом", "value": "35" }, { "label": "Маленькая грудь", "value": "21" }, { "label": "Мистика", "value": "40" }, { "label": "Научная фантастика", "value": "22" }, { "label": "Нетораре", "value": "23" }, { "label": "Оральный секс", "value": "24" }, { "label": "Повседневность", "value": "41" }, { "label": "Приключения", "value": "38" }, { "label": "Публичный секс", "value": "33" }, { "label": "Романтика", "value": "25" }, { "label": "С изображениями", "value": "36" }, { "label": "Сверхъестественное", "value": "34" }, { "label": "Смат", "value": "37" }, { "label": "Тентакли", "value": "26" }, { "label": "Трагедия", "value": "27" }, { "label": "Ужасы", "value": "28" }, { "label": "Фантастика", "value": "32" }, { "label": "Фэнтези", "value": "29" }, { "label": "Чикан", "value": "30" }, { "label": "Этти", "value": "31" }, { "label": "Ahegao", "value": "1" }], "inputType": filterInputs_1.FilterInputs.Checkbox }, { "key": "tags_ex", "label": "Исключить тэги:", "values": [{ "label": "+18", "value": "141" }, { "label": "18+", "value": "200" }, { "label": "21+", "value": "334" }, { "label": "Адекватные главные герои", "value": "253" }, { "label": "Азартные игры", "value": "210" }, { "label": "Айдолы", "value": "364" }, { "label": "Акула", "value": "53" }, { "label": "Альтернативное развитие событий", "value": "338" }, { "label": "Аморальный главный герой", "value": "219" }, { "label": "Анал", "value": "7" }, { "label": "Анальный секс", "value": "67" }, { "label": "Ангелы", "value": "114" }, { "label": "Антигерой", "value": "226" }, { "label": "Аристократия", "value": "260" }, { "label": "Артефакт", "value": "379" }, { "label": "Афродизиак", "value": "276" }, { "label": "Ахегао", "value": "240" }, { "label": "Бабушка беременна от внука", "value": "393" }, { "label": "Бабушка и внук", "value": "380" }, { "label": "Бдсм", "value": "131" }, { "label": "Беременность", "value": "148" }, { "label": "Бесплатно", "value": "79" }, { "label": "Бесстрашные персонажи", "value": "339" }, { "label": "Библиотека", "value": "265" }, { "label": "Бистиалити", "value": "391" }, { "label": "Битва за трон", "value": "404" }, { "label": "Близнецы", "value": "198" }, { "label": "Блондинка", "value": "91" }, { "label": "Богатые персонажи", "value": "248" }, { "label": "Боги", "value": "115" }, { "label": "Боевик", "value": "252" }, { "label": "Большая грудь", "value": "33" }, { "label": "Большая попка", "value": "328" }, { "label": "Большой член", "value": "76" }, { "label": "Большой член сына", "value": "396" }, { "label": "Босс и подчиненный", "value": "330" }, { "label": "Брак", "value": "182" }, { "label": "Брак по расчёту", "value": "346" }, { "label": "Брат", "value": "29" }, { "label": "Брат и сестра", "value": "30" }, { "label": "Брюнетка", "value": "28" }, { "label": "Бэтмен", "value": "369" }, { "label": "Бэтмен", "value": "170" }, { "label": "В первый раз", "value": "179" }, { "label": "Вагинальный секс", "value": "57" }, { "label": "Вагинальный секс", "value": "171" }, { "label": "Вайурист", "value": "9" }, { "label": "Вампиры", "value": "133" }, { "label": "Ван-пис", "value": "335" }, { "label": "Веб камера", "value": "289" }, { "label": "Ведьмы", "value": "232" }, { "label": "Викинги", "value": "307" }, { "label": "Виртуальная реальность", "value": "382" }, { "label": "Вирус", "value": "203" }, { "label": "Внучка", "value": "189" }, { "label": "Война", "value": "387" }, { "label": "Воспоминания из прошлого", "value": "405" }, { "label": "Враги становятся любовниками", "value": "410" }, { "label": "Время", "value": "81" }, { "label": "Второй шанс", "value": "244" }, { "label": "Вуайеризм", "value": "62" }, { "label": "Выживание", "value": "135" }, { "label": "Гарем", "value": "107" }, { "label": "Гарри поттер", "value": "97" }, { "label": "Гвен", "value": "402" }, { "label": "Гг имба", "value": "87" }, { "label": "Генетические модификации", "value": "314" }, { "label": "Гипноз", "value": "143" }, { "label": "Главная героиня девушка", "value": "147" }, { "label": "Главный герой женщина", "value": "213" }, { "label": "Главный герой извращенец", "value": "116" }, { "label": "Главный герой мужчина", "value": "117" }, { "label": "Глубокое горло", "value": "94" }, { "label": "Гоблины", "value": "230" }, { "label": "Город", "value": "139" }, { "label": "Городское фэнтези", "value": "297" }, { "label": "Грудное молоко", "value": "225" }, { "label": "Групповой секс", "value": "72" }, { "label": "Гэнг-бэнг", "value": "235" }, { "label": "Гяру", "value": "222" }, { "label": "Двойное проникновение", "value": "42" }, { "label": "Двойной анал", "value": "47" }, { "label": "Дворяне", "value": "246" }, { "label": "Деамоны старший школы", "value": "291" }, { "label": "Девственница", "value": "119" }, { "label": "Девушки-монстры", "value": "223" }, { "label": "Демоны", "value": "98" }, { "label": "Детектив", "value": "249" }, { "label": "Дзёсэй", "value": "259" }, { "label": "Доктор", "value": "326" }, { "label": "Дом", "value": "138" }, { "label": "Доминирование", "value": "18" }, { "label": "Дочь", "value": "153" }, { "label": "Дочь беременна от отца", "value": "348" }, { "label": "Древние времена", "value": "383" }, { "label": "Древний китай", "value": "261" }, { "label": "Другой мир", "value": "365" }, { "label": "Дружба", "value": "325" }, { "label": "Друзья детства", "value": "183" }, { "label": "Дядя", "value": "160" }, { "label": "Жена", "value": "70" }, { "label": "Жена и муж", "value": "99" }, { "label": "Жена шлюха", "value": "236" }, { "label": "Женское доминирование", "value": "100" }, { "label": "Жесткий секс", "value": "283" }, { "label": "Жёсткий секс", "value": "101" }, { "label": "Жестокие персонажи", "value": "254" }, { "label": "Жестокий мир", "value": "336" }, { "label": "Жестокость", "value": "123" }, { "label": "Заботливый главный герой", "value": "340" }, { "label": "Зависимость", "value": "370" }, { "label": "Заключение", "value": "196" }, { "label": "Заключённые", "value": "384" }, { "label": "Замок", "value": "140" }, { "label": "Запретная любовь", "value": "273" }, { "label": "Заражение", "value": "206" }, { "label": "Звёздные войны", "value": "120" }, { "label": "Зверодевочки", "value": "158" }, { "label": "Зло", "value": "343" }, { "label": "Золовка", "value": "77" }, { "label": "Золотой дождь", "value": "146" }, { "label": "Зомби апокалипсис", "value": "241" }, { "label": "Зоофилия", "value": "144" }, { "label": "Зрелые женщины", "value": "398" }, { "label": "Игровые элементы", "value": "385" }, { "label": "Извращения", "value": "192" }, { "label": "Измена", "value": "71" }, { "label": "Изменения внешности", "value": "315" }, { "label": "Изменения личности", "value": "316" }, { "label": "Изнасилование", "value": "275" }, { "label": "Изуку мидория", "value": "337" }, { "label": "Ино", "value": "127" }, { "label": "Инопланетяне", "value": "304" }, { "label": "Интересный сюжет", "value": "349" }, { "label": "Интимные сцены", "value": "322" }, { "label": "Интриги и заговоры", "value": "262" }, { "label": "Интроверт", "value": "38" }, { "label": "Инфекция", "value": "207" }, { "label": "Инцест", "value": "35" }, { "label": "Исторический роман", "value": "406" }, { "label": "Камера", "value": "92" }, { "label": "Колледж", "value": "82" }, { "label": "Комикс", "value": "286" }, { "label": "Контроль", "value": "19" }, { "label": "Контроль над разумом", "value": "181" }, { "label": "Контроль разума", "value": "65" }, { "label": "Кончил внутрь", "value": "221" }, { "label": "Королевская семья", "value": "358" }, { "label": "Коррупция", "value": "49" }, { "label": "Космос", "value": "204" }, { "label": "Красивая главная героиня", "value": "255" }, { "label": "Красивые женщины", "value": "321" }, { "label": "Красивый главный герой", "value": "266" }, { "label": "Ксенофилия", "value": "386" }, { "label": "Кулинария", "value": "362" }, { "label": "Культвация", "value": "86" }, { "label": "Кунилингус", "value": "152" }, { "label": "Кушина", "value": "399" }, { "label": "Лактация", "value": "11" }, { "label": "Лесби", "value": "408" }, { "label": "Лишение девственности", "value": "212" }, { "label": "Лоли", "value": "218" }, { "label": "Лунатизм", "value": "279" }, { "label": "Любовь", "value": "89" }, { "label": "Магический мир", "value": "357" }, { "label": "Магия", "value": "80" }, { "label": "Мама", "value": "3" }, { "label": "Мама беременна от сына", "value": "274" }, { "label": "Мама и дочь", "value": "163" }, { "label": "Мама и сын", "value": "1" }, { "label": "Мама супермена", "value": "39" }, { "label": "Манипуляция временем", "value": "292" }, { "label": "Марвел", "value": "290" }, { "label": "Марвел", "value": "173" }, { "label": "Марти стью", "value": "102" }, { "label": "Массаж", "value": "224" }, { "label": "Мастурбация", "value": "63" }, { "label": "Мать", "value": "239" }, { "label": "Мать и дочь", "value": "381" }, { "label": "Мать и сын", "value": "237" }, { "label": "Мафия", "value": "256" }, { "label": "Мачеха", "value": "197" }, { "label": "Мачеха беременна от сына", "value": "395" }, { "label": "Мачеха и сын", "value": "394" }, { "label": "Медсестра", "value": "341" }, { "label": "Межрассовый", "value": "54" }, { "label": "Месть", "value": "306" }, { "label": "Меха", "value": "268" }, { "label": "Ми", "value": "243" }, { "label": "Милф", "value": "34" }, { "label": "Милф", "value": "180" }, { "label": "Минет", "value": "52" }, { "label": "Мистика", "value": "250" }, { "label": "Младшая сестра", "value": "154" }, { "label": "Много спермы", "value": "409" }, { "label": "Модель", "value": "324" }, { "label": "Монстры", "value": "333" }, { "label": "Мошеничество", "value": "44" }, { "label": "Мужская беременность", "value": "363" }, { "label": "Мужчина протагонист", "value": "108" }, { "label": "Музыка", "value": "331" }, { "label": "Мэри съюха", "value": "309" }, { "label": "Наруко", "value": "400" }, { "label": "Наруто", "value": "46" }, { "label": "Насилие", "value": "128" }, { "label": "Насилие и жестокость", "value": "193" }, { "label": "Научный эксперимент", "value": "313" }, { "label": "Нежить", "value": "373" }, { "label": "Некромантия", "value": "298" }, { "label": "Ненормативная лексика", "value": "124" }, { "label": "Нетораре", "value": "69" }, { "label": "Нетори", "value": "284" }, { "label": "Нижнее бельё", "value": "392" }, { "label": "Ниндзя", "value": "296" }, { "label": "Ношеные трусики", "value": "166" }, { "label": "Нудизм", "value": "156" }, { "label": "Няня", "value": "88" }, { "label": "Обмен женами", "value": "78" }, { "label": "Оборотни", "value": "136" }, { "label": "Обратный гарем", "value": "214" }, { "label": "Одержимость", "value": "345" }, { "label": "Омегаверс", "value": "368" }, { "label": "Оплодотворение", "value": "157" }, { "label": "Оральный секс", "value": "10" }, { "label": "Оргия", "value": "356" }, { "label": "Орки", "value": "388" }, { "label": "От слабого к сильному", "value": "351" }, { "label": "Отец", "value": "2" }, { "label": "Отец делится с сыном", "value": "6" }, { "label": "Отец и дочь", "value": "205" }, { "label": "Отец куколд", "value": "272" }, { "label": "Офис", "value": "234" }, { "label": "Падчерица", "value": "271" }, { "label": "Пайзури", "value": "195" }, { "label": "Папа и дочь", "value": "360" }, { "label": "Паразиты", "value": "208" }, { "label": "Параллельный мир", "value": "320" }, { "label": "Пародия", "value": "371" }, { "label": "Первый раз", "value": "159" }, { "label": "Перемещение в другой мир", "value": "347" }, { "label": "Перемещение во времени", "value": "245" }, { "label": "Перерождение", "value": "109" }, { "label": "Перерождение в злодея", "value": "202" }, { "label": "Пирсинг", "value": "145" }, { "label": "Писатель", "value": "267" }, { "label": "Планомерное развитие событий", "value": "350" }, { "label": "Повседневность", "value": "247" }, { "label": "Подглядывание", "value": "280" }, { "label": "Подчинение", "value": "106" }, { "label": "Подчинение и унижение", "value": "211" }, { "label": "Поедание киски", "value": "26" }, { "label": "Покемоны", "value": "132" }, { "label": "Покорная", "value": "8" }, { "label": "Полигамия", "value": "352" }, { "label": "Половое воспитание", "value": "37" }, { "label": "Полулюди", "value": "231" }, { "label": "Попаданец", "value": "103" }, { "label": "Попадание в книгу", "value": "361" }, { "label": "Порка", "value": "20" }, { "label": "Порно", "value": "278" }, { "label": "Постапокалипсис", "value": "332" }, { "label": "Потеря девственности", "value": "142" }, { "label": "Похищение", "value": "161" }, { "label": "Преданные любовный интерес", "value": "407" }, { "label": "Призраки", "value": "412" }, { "label": "Приключения", "value": "134" }, { "label": "Принуждение", "value": "66" }, { "label": "Психология", "value": "238" }, { "label": "Публично", "value": "85" }, { "label": "Публичный секс", "value": "233" }, { "label": "Раб", "value": "353" }, { "label": "Рабы", "value": "308" }, { "label": "Разват", "value": "58" }, { "label": "Разврат", "value": "64" }, { "label": "Райзен", "value": "95" }, { "label": "Раса инопланетных космических лесбиянок", "value": "294" }, { "label": "Религия", "value": "403" }, { "label": "Рестленг", "value": "84" }, { "label": "Риас гремори", "value": "389" }, { "label": "Романтика", "value": "178" }, { "label": "Рыжий", "value": "90" }, { "label": "С", "value": "413" }, { "label": "Сакура", "value": "126" }, { "label": "Самолет", "value": "93" }, { "label": "Санса старк", "value": "277" }, { "label": "Санта", "value": "372" }, { "label": "Свадьба", "value": "73" }, { "label": "Сверхсила", "value": "228" }, { "label": "Сверхъестественное", "value": "319" }, { "label": "Свингеры", "value": "201" }, { "label": "Свободные отношения", "value": "186" }, { "label": "Связывание", "value": "137" }, { "label": "Сёдзе", "value": "264" }, { "label": "Секс", "value": "21" }, { "label": "Секс без проникновения", "value": "68" }, { "label": "Секс втроем", "value": "43" }, { "label": "Секс игрушки", "value": "59" }, { "label": "Секс рабыня", "value": "55" }, { "label": "Секс с монстрами", "value": "56" }, { "label": "Секс с учителем", "value": "184" }, { "label": "Секса будет много", "value": "151" }, { "label": "Сексуальное желание", "value": "209" }, { "label": "Селфцест", "value": "397" }, { "label": "Семья", "value": "5" }, { "label": "Сестра", "value": "31" }, { "label": "Сестра беременна от брата", "value": "355" }, { "label": "Сильный с самого начала", "value": "112" }, { "label": "Симбиоз", "value": "50" }, { "label": "Сирена", "value": "51" }, { "label": "Система", "value": "104" }, { "label": "Сиськи", "value": "285" }, { "label": "Сквирт", "value": "164" }, { "label": "Скрытый секс", "value": "287" }, { "label": "Служанка", "value": "215" }, { "label": "Соб", "value": "281" }, { "label": "Соблазнение", "value": "162" }, { "label": "Современность", "value": "217" }, { "label": "Соколиный Глаз", "value": "176" }, { "label": "Соперничество", "value": "216" }, { "label": "Соседи", "value": "61" }, { "label": "Соседка", "value": "312" }, { "label": "Сперма", "value": "229" }, { "label": "Сперма на лицо", "value": "199" }, { "label": "Спящие", "value": "187" }, { "label": "Старшая сестра", "value": "311" }, { "label": "Стеб", "value": "111" }, { "label": "Студенты", "value": "177" }, { "label": "Суккуб", "value": "390" }, { "label": "Супергерои", "value": "305" }, { "label": "Суперспособности", "value": "300" }, { "label": "Сын", "value": "4" }, { "label": "Твинцест", "value": "188" }, { "label": "Темное фэнтези", "value": "293" }, { "label": "Тентакли", "value": "303" }, { "label": "Тетя", "value": "113" }, { "label": "Тетя беременна от племянника", "value": "376" }, { "label": "Тетя и племянник", "value": "377" }, { "label": "Техника", "value": "302" }, { "label": "Технологии", "value": "301" }, { "label": "Тёща", "value": "270" }, { "label": "Тиран", "value": "310" }, { "label": "Трагическое прошлое", "value": "251" }, { "label": "Трансмиграция", "value": "269" }, { "label": "Трансформация", "value": "317" }, { "label": "Триллер", "value": "344" }, { "label": "Трусики", "value": "165" }, { "label": "Убийства", "value": "258" }, { "label": "Удача", "value": "299" }, { "label": "Ужасы", "value": "375" }, { "label": "Улучшение тела", "value": "288" }, { "label": "Умная главная героиня", "value": "242" }, { "label": "Умные персонажи", "value": "257" }, { "label": "Умный главный герой", "value": "354" }, { "label": "Университет", "value": "323" }, { "label": "Ученик", "value": "83" }, { "label": "Ф", "value": "149" }, { "label": "Фанатичная любовь", "value": "366" }, { "label": "Фанаты", "value": "367" }, { "label": "Фантастика", "value": "295" }, { "label": "Фанфик", "value": "40" }, { "label": "Фелляция", "value": "22" }, { "label": "Ферма", "value": "191" }, { "label": "Фетиш", "value": "60" }, { "label": "Флэш", "value": "121" }, { "label": "Футанария", "value": "150" }, { "label": "Фэнтези", "value": "359" }, { "label": "Хентай", "value": "75" }, { "label": "Хината", "value": "110" }, { "label": "Холодная главная героиня", "value": "263" }, { "label": "Черная вдова", "value": "220" }, { "label": "Черная Вдова", "value": "175" }, { "label": "Черный юмор", "value": "374" }, { "label": "Читерство", "value": "45" }, { "label": "Чтение мыслей", "value": "227" }, { "label": "Чудовища", "value": "378" }, { "label": "Шантаж", "value": "129" }, { "label": "Школа", "value": "118" }, { "label": "Школьная жизнь", "value": "318" }, { "label": "Шлюха", "value": "32" }, { "label": "Шоу-бизнес", "value": "329" }, { "label": "Шоу-бизнес", "value": "172" }, { "label": "Эксгибиционизм", "value": "74" }, { "label": "Элементы бдсм", "value": "185" }, { "label": "Эмма уотсон", "value": "342" }, { "label": "Эмма Уотсон", "value": "169" }, { "label": "Эротика", "value": "36" }, { "label": "Этти", "value": "327" }, { "label": "Юмор", "value": "105" }, { "label": "Яндере", "value": "155" }, { "label": "Bl", "value": "125" }, { "label": "Dc", "value": "411" }, { "label": "Gl", "value": "96" }, { "label": "Harry potter", "value": "190" }, { "label": "Harry potter", "value": "168" }, { "label": "Hentai", "value": "282" }, { "label": "Marvel", "value": "194" }, { "label": "Marvel", "value": "174" }, { "label": "Milf", "value": "167" }, { "label": "Mj", "value": "401" }], "inputType": filterInputs_1.FilterInputs.Checkbox }, { "key": "fandoms_ex", "label": "Исключить фэндомы:", "values": [{ "label": "Аватар: Легенда о Корре / Avatar legend of Korra", "value": "46" }, { "label": "Аватар: Легенда об Аанге / Avatar: The Legend of Aang / Avatar: The Last Airbender", "value": "45" }, { "label": "Аладдин / Aladdin", "value": "86" }, { "label": "Алиса в Стране чудес / Alice in Wonderland", "value": "90" }, { "label": "Американский папаша / American Dad", "value": "85" }, { "label": "Атака титанов / Атака на титанов / Attack on Titan", "value": "41" }, { "label": "Блич / Bleach", "value": "58" }, { "label": "Боевой континент", "value": "101" }, { "label": "Большой куш / One Piece", "value": "18" }, { "label": "Боруто: Новое поколение Наруто / Boruto: Naruto Next Generations", "value": "9" }, { "label": "Бэтмен / The Batman", "value": "36" }, { "label": "Ведьмак / The Witcher", "value": "53" }, { "label": "Военная хроника маленькой девочки", "value": "100" }, { "label": "Волейбол / Haikyu!!", "value": "37" }, { "label": "Вселенная Марвел / Marvel Universe", "value": "7" }, { "label": "Вселенная Марвел / Marvel Universe / Marvel Comics", "value": "52" }, { "label": "Вселенная Стивена", "value": "61" }, { "label": "Вселенная DC / DC Universe / DC Comics", "value": "48" }, { "label": "Гарри Поттер / Harry Potter", "value": "4" }, { "label": "Гоэтия / Гоетия / Yοητεία / Ars Goetia", "value": "77" }, { "label": "Демоны старшей школы / High School DxD", "value": "10" }, { "label": "День сурка / Groundhog Day", "value": "3" }, { "label": "Джессика Джонс / Marvel's Jessica Jones", "value": "42" }, { "label": "Дисней / The Walt Disney Company", "value": "74" }, { "label": "Древние свитки: Скайрим / TES: Skyrim", "value": "15" }, { "label": "Дэдпул / Deadpool", "value": "22" }, { "label": "Дэнни-призрак / Danny Phantom", "value": "51" }, { "label": "Железный человек / Iron Man", "value": "19" }, { "label": "Звёздная принцесса и силы зла / Стар против сил зла / Star vs. The Forces of Evil", "value": "50" }, { "label": "Звездные Войны / Star Wars", "value": "43" }, { "label": "Звёздные Войны / Star Wars", "value": "16" }, { "label": "Игра престолов", "value": "78" }, { "label": "Касльвания / Castlevania", "value": "29" }, { "label": "Киберпанк 2077 / Cyberpunk 2077", "value": "6" }, { "label": "Код Гиас / Code Geass", "value": "84" }, { "label": "Кольцо Элдена", "value": "60" }, { "label": "Королевства Сердец / Kingdom Hearts", "value": "93" }, { "label": "Красавица и чудовище / Beauty and the Beast", "value": "91" }, { "label": "Красный, Белый, Черный, Желтый / RWBY", "value": "32" }, { "label": "Кунг фу панда", "value": "81" }, { "label": "Лига Легенд / League of Legends", "value": "5" }, { "label": "Люди Икс / X-Men", "value": "25" }, { "label": "Маг на полную ставку / Quanzhi Fashi", "value": "30" }, { "label": "Мастера меча онлайн / Sword Art Online / SAO", "value": "47" }, { "label": "Мир Тьмы / World of Darkness", "value": "28" }, { "label": "Мой маленький пони / My Little Pony", "value": "72" }, { "label": "Мой маленький пони: Дружба — это чудо / My Little Pony: Friendship is Magic", "value": "71" }, { "label": "Моя геройская академия / Boku no Hero Academia", "value": "8" }, { "label": "Мстители / The Avengers", "value": "20" }, { "label": "Мстители. Эра Альтрона / The Avengers. Age of Ultron", "value": "24" }, { "label": "Мулан / Mulan", "value": "94" }, { "label": "Наруто / Naruto", "value": "2" }, { "label": "Овервотч", "value": "79" }, { "label": "Поднятие уровня в одиночку", "value": "87" }, { "label": "Порновселенная / Porn Universe", "value": "31" }, { "label": "Прототип / Prototype", "value": "44" }, { "label": "Рапунцель: Запутанная история / Tangled", "value": "96" }, { "label": "Розовая пора моей школьной жизни сплошной обман / Yahari Ore no Seishun Love Come wa Machigatteiru", "value": "14" }, { "label": "Русалочка / The Little Mermaid", "value": "97" }, { "label": "Сага о Винланде", "value": "66" }, { "label": "Светлячок / Firefly", "value": "76" }, { "label": "Сильнейший в истории ученик Кэнити / Shijou Saikyou no Deshi Kenichi", "value": "13" }, { "label": "Симпсоны / The Simpsons", "value": "73" }, { "label": "Судьба: Великий Приказ / Fate: Grand Order", "value": "54" }, { "label": "Супергёрл(телесериал, 2015) / Supergirl", "value": "95" }, { "label": "Супермен / Superman", "value": "1" }, { "label": "Теория большого взрыва / The Big Bang Theory", "value": "75" }, { "label": "Тор / Thor", "value": "27" }, { "label": "У Коми-сан проблемы с общением / 古見さんは、コミュ症です / Komi Can't Communicate", "value": "11" }, { "label": "Убийца Акаме / Akame ga Kill", "value": "40" }, { "label": "Уэнздей / Wednesday", "value": "26" }, { "label": "Фантастическая четвёрка / Fantastic Four", "value": "21" }, { "label": "Флэш / The Flash", "value": "17" }, { "label": "Хвост Феи / Fairy Tail", "value": "59" }, { "label": "Холодное сердце / Frozen", "value": "92" }, { "label": "Человек одного удара / Ванпанчмен / One Punch-Man", "value": "39" }, { "label": "Человек-паук / Spider-Man", "value": "23" }, { "label": "Чёрный зверь / Чёрный Пёс / Kuroinu", "value": "35" }, { "label": "Чёрный зверь: Развращение Благородных Воительниц / Black Beast: Corruption of the Noble Warriors", "value": "34" }, { "label": "Школа мертвецов", "value": "67" }, { "label": "Школа строгого режима / Prison School", "value": "12" }, { "label": "Эффект Массы / Mass Effect", "value": "57" }, { "label": "Юные Титаны / Teen Titans", "value": "49" }, { "label": "Ars Goetia | Gods and Demons", "value": "69" }, { "label": "Biohazard", "value": "99" }, { "label": "CL", "value": "70" }, { "label": "Daraku Reijou Hakoiri Ojou-sama Netorare Choukyou Kiroku", "value": "55" }, { "label": "Doom", "value": "64" }, { "label": "Granblue fantasy", "value": "88" }, { "label": "Halo", "value": "80" }, { "label": "Highschool of the Dead/Школа мертвецов", "value": "68" }, { "label": "JK Bitch ni Shiboraretai", "value": "56" }, { "label": "Monogatari Series", "value": "65" }, { "label": "Monster girl quest", "value": "62" }, { "label": "Over", "value": "102" }, { "label": "Rapunzel/Рапунцель", "value": "83" }, { "label": "Resident Evil", "value": "98" }, { "label": "Solo leveling", "value": "63" }, { "label": "Tentacle Locker", "value": "89" }, { "label": "X-COM", "value": "82" }], "inputType": filterInputs_1.FilterInputs.Checkbox }, { "key": "atmosphere", "label": "Атмосфера:", "values": [{ "label": "Неважно", "value": "0" }, { "label": "Позитивная", "value": "1" }, { "label": "Dark", "value": "2" }], "inputType": filterInputs_1.FilterInputs.Picker }, { "key": "adult", "label": "Возрастные ограничения:", "values": [{ "label": "Все", "value": "0" }, { "label": "Только 18+", "value": "2" }, { "label": "Убрать 18+", "value": "1" }], "inputType": filterInputs_1.FilterInputs.Picker }]; diff --git a/js/plugins/russian/LitSpace.js b/js/plugins/russian/LitSpace.js deleted file mode 100644 index 0f0d226..0000000 --- a/js/plugins/russian/LitSpace.js +++ /dev/null @@ -1,232 +0,0 @@ -"use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.fetchImage = exports.filters = exports.searchNovels = exports.parseChapter = exports.parseNovelAndChapters = exports.popularNovels = exports.icon = exports.version = exports.site = exports.name = exports.id = void 0; -const filterInputs_1 = require("@libs/filterInputs"); -const fetch_1 = require("@libs/fetch"); -const cheerio_1 = require("cheerio"); -exports.id = "freedlit.space"; -exports.name = "LitSpace"; -exports.site = "https://freedlit.space"; -exports.version = "1.0.0"; -exports.icon = "src/ru/freedlit/icon.png"; -const popularNovels = function (page, { showLatestNovels, filters }) { - return __awaiter(this, void 0, void 0, function* () { - let url = exports.site + "/books/"; - url += ((filters === null || filters === void 0 ? void 0 : filters.genre) || "all") + "?sort="; - url += showLatestNovels ? "recent" : (filters === null || filters === void 0 ? void 0 : filters.sort) || "popular"; - url += "&status=" + ((filters === null || filters === void 0 ? void 0 : filters.status) || "all"); - url += "&access=" + ((filters === null || filters === void 0 ? void 0 : filters.access) || "all"); - url += "&adult=" + ((filters === null || filters === void 0 ? void 0 : filters.adult) || "hide"); - url += "&page=" + page; - const result = yield (0, fetch_1.fetchApi)(url); - const body = yield result.text(); - const loadedCheerio = (0, cheerio_1.load)(body); - let novels = []; - loadedCheerio("#bookListBlock > div > div").each(function () { - var _a, _b, _c; - const name = (_a = loadedCheerio(this).find("div > h4 > a").text()) === null || _a === void 0 ? void 0 : _a.trim(); - const cover = (_b = loadedCheerio(this).find("div > a > img").attr("src")) === null || _b === void 0 ? void 0 : _b.trim(); - const url = (_c = loadedCheerio(this).find("div > h4 > a").attr("href")) === null || _c === void 0 ? void 0 : _c.trim(); - if (!name || !url) - return; - novels.push({ name, cover, url }); - }); - return novels; - }); -}; -exports.popularNovels = popularNovels; -const parseNovelAndChapters = function (novelUrl) { - var _a, _b; - return __awaiter(this, void 0, void 0, function* () { - const result = yield (0, fetch_1.fetchApi)(novelUrl); - const body = yield result.text(); - const loadedCheerio = (0, cheerio_1.load)(body); - let novel = { - url: novelUrl, - name: loadedCheerio(".book-info > h4").text(), - cover: (_a = loadedCheerio(".book-cover > div > img").attr("src")) === null || _a === void 0 ? void 0 : _a.trim(), - summary: (_b = loadedCheerio("#nav-home").text()) === null || _b === void 0 ? void 0 : _b.trim(), - author: loadedCheerio(".book-info > h5 > a").text(), - genres: loadedCheerio(".genre-list > a") - .map((index, element) => loadedCheerio(element).text()).get().join(","), - }; - let chapters = []; - loadedCheerio("#nav-contents > div").each(function () { - const name = loadedCheerio(this).find("a").text(); - const releaseTime = loadedCheerio(this).find('span[class="date"]').text(); - const url = loadedCheerio(this).find("a").attr("href"); - if (!name || !url) - return; - chapters.push({ name, releaseTime, url }); - }); - novel.chapters = chapters; - return novel; - }); -}; -exports.parseNovelAndChapters = parseNovelAndChapters; -const parseChapter = function (chapterUrl) { - return __awaiter(this, void 0, void 0, function* () { - const result = yield (0, fetch_1.fetchApi)(chapterUrl); - const body = yield result.text(); - const loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('div[class="standart-block"]').remove(); - loadedCheerio('div[class="mobile-block"]').remove(); - const chapterText = loadedCheerio('div[class="chapter"]').html(); - return chapterText; - }); -}; -exports.parseChapter = parseChapter; -const searchNovels = function (searchTerm) { - return __awaiter(this, void 0, void 0, function* () { - const url = `${exports.site}/search?query=${searchTerm}&type=all`; - const result = yield (0, fetch_1.fetchApi)(url); - const body = yield result.text(); - const loadedCheerio = (0, cheerio_1.load)(body); - let novels = []; - loadedCheerio("#bookListBlock > div").each(function () { - var _a, _b, _c; - const name = (_a = loadedCheerio(this).find("h4 > a").text()) === null || _a === void 0 ? void 0 : _a.trim(); - const cover = (_b = loadedCheerio(this).find("a > img").attr("src")) === null || _b === void 0 ? void 0 : _b.trim(); - const url = (_c = loadedCheerio(this).find("h4 > a").attr("href")) === null || _c === void 0 ? void 0 : _c.trim(); - if (!name || !url) - return; - novels.push({ name, cover, url }); - }); - return novels; - }); -}; -exports.searchNovels = searchNovels; -exports.filters = [ - { - key: "sort", - label: "Сортировка:", - values: [ - { label: "По популярности", value: "popular" }, - { label: "По количеству комментариев", value: "comments" }, - { label: "По количеству лайков", value: "likes" }, - { label: "По новизне", value: "recent" }, - { label: "По просмотрам", value: "views" }, - ], - inputType: filterInputs_1.FilterInputs.Picker, - }, - { - key: "genre", - label: "Жанры:", - values: [ - { label: "Любой жанр", value: "all" }, - { label: "Альтернативная история", value: "alternative-history" }, - { label: "Антиутопия", value: "dystopia" }, - { label: "Бизнес-литература", value: "business-literature" }, - { label: "Боевая фантастика", value: "combat-fiction" }, - { label: "Боевик", value: "action" }, - { label: "Боевое фэнтези", value: "combat-fantasy" }, - { label: "Бояръ-Аниме", value: "boyar-anime" }, - { label: "Героическая фантастика", value: "heroic-fiction" }, - { label: "Героическое фэнтези", value: "heroic-fantasy" }, - { label: "Городское фэнтези", value: "urban-fantasy" }, - { label: "Гримдарк", value: "grimdark" }, - { label: "Детектив", value: "mystery" }, - { label: "Детская литература", value: "kids-literature" }, - { label: "Документальная проза", value: "biography" }, - { label: "Историческая проза", value: "historical-fiction" }, - { label: "Исторический детектив", value: "historical-mystery" }, - { label: "Исторический любовный роман", value: "historical-romantic-novel" }, - { label: "Историческое фэнтези", value: "historical-fantasy" }, - { label: "Киберпанк", value: "cyberpunk" }, - { label: "Космическая фантастика", value: "cosmic-fiction" }, - { label: "ЛитРПГ", value: "litrpg" }, - { label: "Лоу / Низкое фэнтези", value: "low-fantasy" }, - { label: "Любовное фэнтези", value: "romantic-fantasy" }, - { label: "Любовный роман", value: "romantic-novel" }, - { label: "Мистика", value: "mystic" }, - { label: "Мистический детектив", value: "mystic-detective" }, - { label: "Научная фантастика", value: "science-fiction" }, - { label: "Подростковая проза", value: "young-adult" }, - { label: "Политический роман", value: "political-romance" }, - { label: "Попаданцы", value: "accidental-travel" }, - { label: "Попаданцы в магические миры", value: "magic-worlds-travel" }, - { label: "Попаданцы во времени", value: "time-travel" }, - { label: "Порнотика", value: "pornotica" }, - { label: "Постапокалипсис", value: "post-apocalypse" }, - { label: "Поэзия", value: "poetry" }, - { label: "Приключения", value: "adventure" }, - { label: "Публицистика", value: "journalism" }, - { label: "Пьеса", value: "play" }, - { label: "Развитие личности", value: "how-to-book" }, - { label: "Разное", value: "other" }, - { label: "Реализм", value: "Realism" }, - { label: "РеалРПГ", value: "realrpg" }, - { label: "Репликация", value: "replication" }, - { label: "Романтическая эротика", value: "romantic-erotic-fiction" }, - { label: "Сказка", value: "fairy-tale" }, - { label: "Слэш", value: "slash" }, - { label: "Современная проза", value: "modern-prose" }, - { label: "Современный любовный роман", value: "modern-romantic-novel" }, - { label: "Социальная фантастика", value: "social-fiction" }, - { label: "Стимпанк", value: "steampunk" }, - { label: "Сценарий", value: "scenario" }, - { label: "Сюаньхуань", value: "xuanhuan" }, - { label: "Сянься", value: "xianxia" }, - { label: "Тёмное фэнтези", value: "dark-fantasy" }, - { label: "Триллер", value: "thriller" }, - { label: "Уся", value: "wuxia" }, - { label: "Фантастика", value: "fiction" }, - { label: "Фантастический детектив", value: "mystery-fiction" }, - { label: "Фанфик", value: "fan-fiction" }, - { label: "Фемслэш", value: "femslash" }, - { label: "Фэнтези", value: "fantasy" }, - { label: "Хоррор", value: "horror" }, - { label: "Шпионский детектив", value: "spy-crime" }, - { label: "Эпическое фэнтези", value: "epic-fantasy" }, - { label: "Эротика", value: "erotic-fiction" }, - { label: "Эротическая фантастика", value: "erotic-fiction" }, - { label: "Эротический фанфик", value: "erotic-fan-fiction" }, - { label: "Эротическое фэнтези", value: "erotic-fantasy" }, - { label: "Этническое фэнтези", value: "ethnic-fantasy" }, - { label: "Юмор", value: "humor" }, - { label: "Юмористическая фантастика", value: "humor-fiction" }, - { label: "Юмористическое фэнтези", value: "humor-fantasy" }, - { label: "RPS", value: "rps" }, - ], - inputType: filterInputs_1.FilterInputs.Picker, - }, - { - key: "status", - label: "Статус:", - values: [ - { label: "Любой статус", value: "all" }, - { label: "В процессе", value: "in-process" }, - { label: "Завершено", value: "finished" }, - ], - inputType: filterInputs_1.FilterInputs.Picker, - }, - { - key: "access", - label: "Доступ:", - values: [ - { label: "Любой доступ", value: "all" }, - { label: "Бесплатные", value: "free" }, - { label: "Платные", value: "paid" }, - ], - inputType: filterInputs_1.FilterInputs.Picker, - }, - { - key: "adult", - label: "Возрастные ограничения:", - values: [ - { label: "Скрыть 18+", value: "hide" }, - { label: "Показать +18", value: "show" }, - ], - inputType: filterInputs_1.FilterInputs.Picker, - }, -]; -exports.fetchImage = fetch_1.fetchFile; diff --git a/js/plugins/russian/Rulate[rulate].js b/js/plugins/russian/Rulate[rulate].js deleted file mode 100644 index 0743e2c..0000000 --- a/js/plugins/russian/Rulate[rulate].js +++ /dev/null @@ -1,195 +0,0 @@ -"use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.filters = exports.fetchImage = exports.searchNovels = exports.parseChapter = exports.parseNovelAndChapters = exports.popularNovels = exports.site = exports.version = exports.icon = exports.name = exports.id = void 0; -const cheerio_1 = require("cheerio"); -// import dayjs from 'dayjs'; -const fetch_1 = require("@libs/fetch"); -// import { parseMadaraDate } from "@libs/parseMadaraDate"; -// import { isUrlAbsolute } from '@libs/isAbsoluteUrl'; -// import { showToast } from "@libs/showToast"; -const filterInputs_1 = require("@libs/filterInputs"); -const novelStatus_1 = require("@libs/novelStatus"); -// import { defaultCover } from "@libs/defaultCover"; -exports.id = "tl.rulate"; -exports.name = "Rulate"; -exports.icon = "multisrc/rulate/icons/rulate.png"; -exports.version = "1.0.0"; -exports.site = "https://tl.rulate.ru"; -const popularNovels = function (page, { filters, showLatestNovels }) { - return __awaiter(this, void 0, void 0, function* () { - let url = exports.site + '/search?t='; - url += '&cat=' + ((filters === null || filters === void 0 ? void 0 : filters.cat) || '0'); - url += '&s_lang=' + ((filters === null || filters === void 0 ? void 0 : filters.s_lang) || '0'); - url += '&t_lang=' + ((filters === null || filters === void 0 ? void 0 : filters.t_lang) || '0'); - url += '&type=' + ((filters === null || filters === void 0 ? void 0 : filters.type) || '0'); - url += '&sort=' + (showLatestNovels ? '4' : ((filters === null || filters === void 0 ? void 0 : filters.sort) || '6')); - url += '&atmosphere=' + ((filters === null || filters === void 0 ? void 0 : filters.atmosphere) || '0'); - url += '&adult=' + ((filters === null || filters === void 0 ? void 0 : filters.adult) || '0'); - if ((filters === null || filters === void 0 ? void 0 : filters.genres) instanceof Array) { - url += filters.genres.map(i => '&genres[]=' + i).join(''); - } - if ((filters === null || filters === void 0 ? void 0 : filters.genres_ex) instanceof Array) { - url += filters.genres_ex.map(i => '&genres_ex[]=' + i).join(''); - } - if ((filters === null || filters === void 0 ? void 0 : filters.tags) instanceof Array) { - url += filters.tags.map(i => '&tags[]=' + i).join(''); - } - if ((filters === null || filters === void 0 ? void 0 : filters.tags_ex) instanceof Array) { - url += filters.tags_ex.map(i => '&tags_ex[]=' + i).join(''); - } - if ((filters === null || filters === void 0 ? void 0 : filters.fandoms) instanceof Array) { - url += filters.fandoms.map(i => '&fandoms[]=' + i).join(''); - } - if ((filters === null || filters === void 0 ? void 0 : filters.fandoms_ex) instanceof Array) { - url += filters.fandoms_ex.map(i => '&fandoms_ex[]=' + i).join(''); - } - if ((filters === null || filters === void 0 ? void 0 : filters.trash) instanceof Array) { - url += filters.trash.map(i => '&' + i + '=1').join(''); - } - url += '&Book_page=' + page; - const result = yield (0, fetch_1.fetchApi)(url); - const body = yield result.text(); - const loadedCheerio = (0, cheerio_1.load)(body); - const novels = []; - loadedCheerio('ul[class="search-results"] > li:not([class="ad_type_catalog"])').each(function () { - novels.push({ - name: loadedCheerio(this).find('p > a').text(), - cover: exports.site + loadedCheerio(this).find('img').attr('src'), - url: exports.site + loadedCheerio(this).find('p > a').attr('href') || '', - }); - }); - return novels; - }); -}; -exports.popularNovels = popularNovels; -const parseNovelAndChapters = function (novelUrl) { - return __awaiter(this, void 0, void 0, function* () { - const novel = { - url: novelUrl, - chapters: [], - }; - let result = yield (0, fetch_1.fetchApi)(novelUrl); - if (result.url.includes('mature?path=')) { - const formData = new FormData(); - formData.append('path', novelUrl); - formData.append('ok', 'Да'); - yield (0, fetch_1.fetchApi)(result.url, { - method: 'POST', - body: formData, - }); - result = yield (0, fetch_1.fetchApi)(novelUrl); - } - const body = yield result.text(); - const loadedCheerio = (0, cheerio_1.load)(body); - novel.name = loadedCheerio('div[class="container"] > div > div > h1, div.span8:nth-child(1) > h1:nth-child(2)') - .text() - .trim(); - novel.cover = - exports.site + loadedCheerio('div[class="images"] > div img').attr('src'); - novel.summary = loadedCheerio('#Info > div:nth-child(3), .book-description').text(); - novel.author = loadedCheerio('.book-stats-icons_author > span:nth-child(2) > a:nth-child(1)').text(); - let genres = []; - loadedCheerio('div.span5 > p, .span5 > div:nth-child(2) > p').each(function () { - switch (loadedCheerio(this).find('strong').text()) { - case 'Автор:': - novel.author = loadedCheerio(this).find('em > a').text().trim(); - break; - case 'Выпуск:': - novel.status = - loadedCheerio(this).find('em').text().trim() === 'продолжается' - ? novelStatus_1.NovelStatus.Ongoing - : novelStatus_1.NovelStatus.Completed; - break; - case 'Тэги:': - loadedCheerio(this) - .find('em > a') - .each(function () { - genres.push(loadedCheerio(this).text()); - }); - break; - case 'Жанры:': - loadedCheerio(this) - .find('em > a') - .each(function () { - genres.push(loadedCheerio(this).text()); - }); - break; - } - }); - if (genres.length > 0) { - novel.genres = genres.reverse().join(','); - } - const chapters = []; - loadedCheerio('table > tbody > tr.chapter_row').each(function () { - var _a; - const chapterName = loadedCheerio(this) - .find('td[class="t"] > a') - .text() - .trim(); - const releaseDate = (_a = loadedCheerio(this) - .find('td > span') - .attr('title')) === null || _a === void 0 ? void 0 : _a.trim(); - const chapterUrl = exports.site + loadedCheerio(this) - .find('td[class="t"] > a') - .attr('href'); - if (loadedCheerio(this).find('td > span[class="disabled"]').length < 1 && - releaseDate) { - chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); - } - }); - novel.chapters = chapters; - return novel; - }); -}; -exports.parseNovelAndChapters = parseNovelAndChapters; -const parseChapter = function (chapterUrl) { - return __awaiter(this, void 0, void 0, function* () { - let result = yield (0, fetch_1.fetchApi)(chapterUrl); - if (result.url.includes('mature?path=')) { - const formData = new FormData(); - formData.append('ok', 'Да'); - yield (0, fetch_1.fetchApi)(result.url, { - method: 'POST', - body: formData, - }); - result = yield (0, fetch_1.fetchApi)(chapterUrl); - } - const body = yield result.text(); - const loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.content-text img').each(function () { - var _a; - if (!((_a = loadedCheerio(this).attr('src')) === null || _a === void 0 ? void 0 : _a.startsWith('http'))) { - const src = loadedCheerio(this).attr('src'); - loadedCheerio(this).attr('src', exports.site + src); - } - }); - const chapterText = loadedCheerio('.content-text').html(); - return chapterText; - }); -}; -exports.parseChapter = parseChapter; -const searchNovels = (searchTerm) => __awaiter(void 0, void 0, void 0, function* () { - const novels = []; - const result = yield (0, fetch_1.fetchApi)(exports.site + '/search/autocomplete?query=' + searchTerm); - let json = yield result.json(); - json.forEach((item) => { - const novelName = item.title_one + ' / ' + item.title_two; - const novelCover = exports.site + item.img; - const novelUrl = exports.site + item.url; - novels.push({ name: novelName, cover: novelCover, url: novelUrl }); - }); - return novels; -}); -exports.searchNovels = searchNovels; -; -exports.fetchImage = fetch_1.fetchFile; -exports.filters = [{ "key": "cat", "label": "Из раздела каталога:", "values": [{ "label": "Неважно", "value": "0" }, { "label": "Авторские", "value": "18" }, { "label": "Авторские", "value": "35" }, { "label": "Авторские фанфики", "value": "51" }, { "label": "Английские", "value": "28" }, { "label": "Английские", "value": "34" }, { "label": "Английские", "value": "48" }, { "label": "Аниме", "value": "20" }, { "label": "Аудиокниги", "value": "25" }, { "label": "Блич", "value": "42" }, { "label": "Большие игры", "value": "22" }, { "label": "Ван-Пис", "value": "41" }, { "label": "Визуальные новеллы", "value": "8" }, { "label": "Вьетнамские", "value": "39" }, { "label": "Вьетнамские", "value": "49" }, { "label": "Игры", "value": "3" }, { "label": "Китайские", "value": "5" }, { "label": "Китайские", "value": "31" }, { "label": "Китайские", "value": "45" }, { "label": "Книги", "value": "2" }, { "label": "Книги", "value": "14" }, { "label": "Комиксы", "value": "29" }, { "label": "Корейские", "value": "7" }, { "label": "Корейские", "value": "33" }, { "label": "Корейские", "value": "47" }, { "label": "Маленькие игры", "value": "23" }, { "label": "Манга", "value": "16" }, { "label": "Манга", "value": "30" }, { "label": "Марвел", "value": "43" }, { "label": "Машинный перевод", "value": "44" }, { "label": "Наруто", "value": "40" }, { "label": "Новеллы и ранобэ", "value": "12" }, { "label": "Переводы фанфиков", "value": "19" }, { "label": "Психология", "value": "37" }, { "label": "Путешествия", "value": "36" }, { "label": "Статьи", "value": "13" }, { "label": "Субтитры", "value": "15" }, { "label": "Фильмы", "value": "21" }, { "label": "Японские", "value": "6" }, { "label": "Японские", "value": "32" }, { "label": "Японские", "value": "46" }], "inputType": filterInputs_1.FilterInputs.Picker }, { "key": "s_lang", "label": "Язык оригинала:", "values": [{ "label": "Неважно", "value": "0" }, { "label": "Абхазский", "value": "20" }, { "label": "Аварский", "value": "21" }, { "label": "Азербайджанский", "value": "22" }, { "label": "Аймара", "value": "23" }, { "label": "Акан", "value": "24" }, { "label": "Албанский", "value": "25" }, { "label": "Амхарский", "value": "26" }, { "label": "Английский", "value": "2" }, { "label": "Арабский", "value": "27" }, { "label": "Арагонский", "value": "28" }, { "label": "Арберешский", "value": "29" }, { "label": "Армянский", "value": "30" }, { "label": "Ассамский", "value": "31" }, { "label": "Астурийский", "value": "32" }, { "label": "Афарский", "value": "33" }, { "label": "Африкаанс", "value": "34" }, { "label": "Ацтекский", "value": "35" }, { "label": "Баварский", "value": "36" }, { "label": "Бамбарийский", "value": "37" }, { "label": "Баскский", "value": "39" }, { "label": "Башкирский", "value": "40" }, { "label": "Белорусский", "value": "10" }, { "label": "Бенгальский", "value": "41" }, { "label": "Бирманский", "value": "42" }, { "label": "Бислама", "value": "43" }, { "label": "Бихари", "value": "44" }, { "label": "Болгарский", "value": "45" }, { "label": "Боснийский", "value": "234" }, { "label": "Бретонский", "value": "47" }, { "label": "Валенсийский", "value": "48" }, { "label": "Валлийский", "value": "49" }, { "label": "Валлонский", "value": "50" }, { "label": "Венгерский", "value": "51" }, { "label": "Венда", "value": "52" }, { "label": "Венетский", "value": "53" }, { "label": "Верхнелужицкий", "value": "54" }, { "label": "Волоф", "value": "55" }, { "label": "Вьетнамский", "value": "57" }, { "label": "Гавайский", "value": "58" }, { "label": "Гаитянский", "value": "59" }, { "label": "Галисийский", "value": "60" }, { "label": "Гереро", "value": "61" }, { "label": "Голландский", "value": "62" }, { "label": "Греческий", "value": "63" }, { "label": "Грузинский", "value": "64" }, { "label": "Гуарани", "value": "65" }, { "label": "Гуджарати", "value": "66" }, { "label": "Датский", "value": "19" }, { "label": "Дзонг-кэ", "value": "68" }, { "label": "Древнегреческий", "value": "69" }, { "label": "Западно-фламандский", "value": "70" }, { "label": "Зулу", "value": "71" }, { "label": "Иврит", "value": "15" }, { "label": "Игбо", "value": "72" }, { "label": "Идиш", "value": "73" }, { "label": "Илоко", "value": "74" }, { "label": "Индонезийский", "value": "75" }, { "label": "Интерлингва", "value": "76" }, { "label": "Инуктитут", "value": "77" }, { "label": "Инупиак", "value": "78" }, { "label": "Ирландский", "value": "79" }, { "label": "Исландский", "value": "80" }, { "label": "Испанский", "value": "6" }, { "label": "Итальянский", "value": "5" }, { "label": "Йоруба", "value": "81" }, { "label": "Кабильский", "value": "82" }, { "label": "Казахский", "value": "83" }, { "label": "Калмыцкий", "value": "235" }, { "label": "Каннада", "value": "84" }, { "label": "Кантонский юэ", "value": "85" }, { "label": "Канури", "value": "86" }, { "label": "Каталанский", "value": "87" }, { "label": "Кашмири", "value": "88" }, { "label": "Кечуа", "value": "90" }, { "label": "Кикуйю", "value": "91" }, { "label": "Киньяруанда", "value": "92" }, { "label": "Киргизский", "value": "93" }, { "label": "Китайский", "value": "7" }, { "label": "Клингонский", "value": "94" }, { "label": "Коми", "value": "95" }, { "label": "Конго", "value": "96" }, { "label": "Конкани", "value": "97" }, { "label": "Корейский", "value": "98" }, { "label": "Корсиканский", "value": "100" }, { "label": "Котава", "value": "101" }, { "label": "Кри", "value": "102" }, { "label": "Курдский", "value": "105" }, { "label": "Кхмерский", "value": "107" }, { "label": "Лакский", "value": "233" }, { "label": "Лаосский", "value": "109" }, { "label": "Латынь", "value": "110" }, { "label": "Латышский", "value": "111" }, { "label": "Лезгинский", "value": "112" }, { "label": "Лимбургский", "value": "113" }, { "label": "Лингала", "value": "114" }, { "label": "Литовский", "value": "115" }, { "label": "Луба", "value": "118" }, { "label": "Луганда", "value": "119" }, { "label": "Люксембургский", "value": "120" }, { "label": "Македонский", "value": "121" }, { "label": "Малагасийский", "value": "122" }, { "label": "Малайский", "value": "123" }, { "label": "Мальдивский", "value": "125" }, { "label": "Мальтийский", "value": "126" }, { "label": "Маори", "value": "127" }, { "label": "Марийский", "value": "232" }, { "label": "Маршалльский", "value": "130" }, { "label": "Молдавский", "value": "11" }, { "label": "Монгольский", "value": "133" }, { "label": "Мяо (хмонг)", "value": "209" }, { "label": "Навахо", "value": "135" }, { "label": "Неаполитанский", "value": "139" }, { "label": "Немецкий", "value": "3" }, { "label": "Непальский", "value": "140" }, { "label": "Норвежский", "value": "18" }, { "label": "Осетинский", "value": "147" }, { "label": "Пакистанский", "value": "230" }, { "label": "Пенджабский", "value": "149" }, { "label": "Персидский", "value": "151" }, { "label": "Польский", "value": "152" }, { "label": "Португальский", "value": "153" }, { "label": "Румынский", "value": "158" }, { "label": "Русский", "value": "1" }, { "label": "Санскрит", "value": "163" }, { "label": "Сардинский", "value": "164" }, { "label": "Сербохорватский", "value": "166" }, { "label": "Словацкий", "value": "170" }, { "label": "Словенский", "value": "171" }, { "label": "Сомали", "value": "172" }, { "label": "Старотурецкий", "value": "174" }, { "label": "Суахили", "value": "175" }, { "label": "Сунданский", "value": "176" }, { "label": "Тагальский", "value": "177" }, { "label": "Таджикский", "value": "178" }, { "label": "Таитянский", "value": "179" }, { "label": "Тайваньский", "value": "180" }, { "label": "Тайский", "value": "181" }, { "label": "Тамильский", "value": "182" }, { "label": "Татарский", "value": "12" }, { "label": "Телугу", "value": "184" }, { "label": "Тибетский", "value": "185" }, { "label": "Тигринья", "value": "186" }, { "label": "Ток-писин", "value": "187" }, { "label": "Токи пона", "value": "188" }, { "label": "Тонганский", "value": "189" }, { "label": "Тсвана", "value": "191" }, { "label": "Тсонга", "value": "192" }, { "label": "Турецкий", "value": "193" }, { "label": "Туркменский", "value": "194" }, { "label": "Удмуртский", "value": "196" }, { "label": "Узбекский", "value": "197" }, { "label": "Уйгурский", "value": "198" }, { "label": "Украинский", "value": "9" }, { "label": "Фиджийский", "value": "201" }, { "label": "Филиппинский", "value": "229" }, { "label": "Финский", "value": "17" }, { "label": "Французский", "value": "4" }, { "label": "Фризский", "value": "203" }, { "label": "Фулах", "value": "204" }, { "label": "Хауса", "value": "206" }, { "label": "Хинди", "value": "207" }, { "label": "Хири-моту", "value": "208" }, { "label": "Чеченский", "value": "213" }, { "label": "Чешский", "value": "13" }, { "label": "Чувашский", "value": "217" }, { "label": "Шведский", "value": "16" }, { "label": "Швейцарский немецкий", "value": "218" }, { "label": "Шона", "value": "219" }, { "label": "Шотландский", "value": "67" }, { "label": "Эве", "value": "221" }, { "label": "Эскимосский", "value": "223" }, { "label": "Эсперанто", "value": "14" }, { "label": "Эстонский", "value": "224" }, { "label": "Южно-корейский", "value": "231" }, { "label": "Юкатекский", "value": "225" }, { "label": "Яванский", "value": "227" }, { "label": "Японский", "value": "8" }], "inputType": filterInputs_1.FilterInputs.Picker }, { "key": "t_lang", "label": "Язык перевода:", "values": [{ "label": "Неважно", "value": "0" }, { "label": "Абхазский", "value": "20" }, { "label": "Аварский", "value": "21" }, { "label": "Азербайджанский", "value": "22" }, { "label": "Аймара", "value": "23" }, { "label": "Акан", "value": "24" }, { "label": "Албанский", "value": "25" }, { "label": "Амхарский", "value": "26" }, { "label": "Английский", "value": "2" }, { "label": "Арабский", "value": "27" }, { "label": "Арагонский", "value": "28" }, { "label": "Арберешский", "value": "29" }, { "label": "Армянский", "value": "30" }, { "label": "Ассамский", "value": "31" }, { "label": "Астурийский", "value": "32" }, { "label": "Афарский", "value": "33" }, { "label": "Африкаанс", "value": "34" }, { "label": "Ацтекский", "value": "35" }, { "label": "Баварский", "value": "36" }, { "label": "Бамбарийский", "value": "37" }, { "label": "Баскский", "value": "39" }, { "label": "Башкирский", "value": "40" }, { "label": "Белорусский", "value": "10" }, { "label": "Бенгальский", "value": "41" }, { "label": "Бирманский", "value": "42" }, { "label": "Бислама", "value": "43" }, { "label": "Бихари", "value": "44" }, { "label": "Болгарский", "value": "45" }, { "label": "Боснийский", "value": "234" }, { "label": "Бретонский", "value": "47" }, { "label": "Валенсийский", "value": "48" }, { "label": "Валлийский", "value": "49" }, { "label": "Валлонский", "value": "50" }, { "label": "Венгерский", "value": "51" }, { "label": "Венда", "value": "52" }, { "label": "Венетский", "value": "53" }, { "label": "Верхнелужицкий", "value": "54" }, { "label": "Волоф", "value": "55" }, { "label": "Вьетнамский", "value": "57" }, { "label": "Гавайский", "value": "58" }, { "label": "Гаитянский", "value": "59" }, { "label": "Галисийский", "value": "60" }, { "label": "Гереро", "value": "61" }, { "label": "Голландский", "value": "62" }, { "label": "Греческий", "value": "63" }, { "label": "Грузинский", "value": "64" }, { "label": "Гуарани", "value": "65" }, { "label": "Гуджарати", "value": "66" }, { "label": "Датский", "value": "19" }, { "label": "Дзонг-кэ", "value": "68" }, { "label": "Древнегреческий", "value": "69" }, { "label": "Западно-фламандский", "value": "70" }, { "label": "Зулу", "value": "71" }, { "label": "Иврит", "value": "15" }, { "label": "Игбо", "value": "72" }, { "label": "Идиш", "value": "73" }, { "label": "Илоко", "value": "74" }, { "label": "Индонезийский", "value": "75" }, { "label": "Интерлингва", "value": "76" }, { "label": "Инуктитут", "value": "77" }, { "label": "Инупиак", "value": "78" }, { "label": "Ирландский", "value": "79" }, { "label": "Исландский", "value": "80" }, { "label": "Испанский", "value": "6" }, { "label": "Итальянский", "value": "5" }, { "label": "Йоруба", "value": "81" }, { "label": "Кабильский", "value": "82" }, { "label": "Казахский", "value": "83" }, { "label": "Калмыцкий", "value": "235" }, { "label": "Каннада", "value": "84" }, { "label": "Кантонский юэ", "value": "85" }, { "label": "Канури", "value": "86" }, { "label": "Каталанский", "value": "87" }, { "label": "Кашмири", "value": "88" }, { "label": "Кечуа", "value": "90" }, { "label": "Кикуйю", "value": "91" }, { "label": "Киньяруанда", "value": "92" }, { "label": "Киргизский", "value": "93" }, { "label": "Китайский", "value": "7" }, { "label": "Клингонский", "value": "94" }, { "label": "Коми", "value": "95" }, { "label": "Конго", "value": "96" }, { "label": "Конкани", "value": "97" }, { "label": "Корейский", "value": "98" }, { "label": "Корсиканский", "value": "100" }, { "label": "Котава", "value": "101" }, { "label": "Кри", "value": "102" }, { "label": "Курдский", "value": "105" }, { "label": "Кхмерский", "value": "107" }, { "label": "Лакский", "value": "233" }, { "label": "Лаосский", "value": "109" }, { "label": "Латынь", "value": "110" }, { "label": "Латышский", "value": "111" }, { "label": "Лезгинский", "value": "112" }, { "label": "Лимбургский", "value": "113" }, { "label": "Лингала", "value": "114" }, { "label": "Литовский", "value": "115" }, { "label": "Луба", "value": "118" }, { "label": "Луганда", "value": "119" }, { "label": "Люксембургский", "value": "120" }, { "label": "Македонский", "value": "121" }, { "label": "Малагасийский", "value": "122" }, { "label": "Малайский", "value": "123" }, { "label": "Мальдивский", "value": "125" }, { "label": "Мальтийский", "value": "126" }, { "label": "Маори", "value": "127" }, { "label": "Марийский", "value": "232" }, { "label": "Маршалльский", "value": "130" }, { "label": "Молдавский", "value": "11" }, { "label": "Монгольский", "value": "133" }, { "label": "Мяо (хмонг)", "value": "209" }, { "label": "Навахо", "value": "135" }, { "label": "Неаполитанский", "value": "139" }, { "label": "Немецкий", "value": "3" }, { "label": "Непальский", "value": "140" }, { "label": "Норвежский", "value": "18" }, { "label": "Осетинский", "value": "147" }, { "label": "Пакистанский", "value": "230" }, { "label": "Пенджабский", "value": "149" }, { "label": "Персидский", "value": "151" }, { "label": "Польский", "value": "152" }, { "label": "Португальский", "value": "153" }, { "label": "Румынский", "value": "158" }, { "label": "Русский", "value": "1" }, { "label": "Санскрит", "value": "163" }, { "label": "Сардинский", "value": "164" }, { "label": "Сербохорватский", "value": "166" }, { "label": "Словацкий", "value": "170" }, { "label": "Словенский", "value": "171" }, { "label": "Сомали", "value": "172" }, { "label": "Старотурецкий", "value": "174" }, { "label": "Суахили", "value": "175" }, { "label": "Сунданский", "value": "176" }, { "label": "Тагальский", "value": "177" }, { "label": "Таджикский", "value": "178" }, { "label": "Таитянский", "value": "179" }, { "label": "Тайваньский", "value": "180" }, { "label": "Тайский", "value": "181" }, { "label": "Тамильский", "value": "182" }, { "label": "Татарский", "value": "12" }, { "label": "Телугу", "value": "184" }, { "label": "Тибетский", "value": "185" }, { "label": "Тигринья", "value": "186" }, { "label": "Ток-писин", "value": "187" }, { "label": "Токи пона", "value": "188" }, { "label": "Тонганский", "value": "189" }, { "label": "Тсвана", "value": "191" }, { "label": "Тсонга", "value": "192" }, { "label": "Турецкий", "value": "193" }, { "label": "Туркменский", "value": "194" }, { "label": "Удмуртский", "value": "196" }, { "label": "Узбекский", "value": "197" }, { "label": "Уйгурский", "value": "198" }, { "label": "Украинский", "value": "9" }, { "label": "Фиджийский", "value": "201" }, { "label": "Филиппинский", "value": "229" }, { "label": "Финский", "value": "17" }, { "label": "Французский", "value": "4" }, { "label": "Фризский", "value": "203" }, { "label": "Фулах", "value": "204" }, { "label": "Хауса", "value": "206" }, { "label": "Хинди", "value": "207" }, { "label": "Хири-моту", "value": "208" }, { "label": "Чеченский", "value": "213" }, { "label": "Чешский", "value": "13" }, { "label": "Чувашский", "value": "217" }, { "label": "Шведский", "value": "16" }, { "label": "Швейцарский немецкий", "value": "218" }, { "label": "Шона", "value": "219" }, { "label": "Шотландский", "value": "67" }, { "label": "Эве", "value": "221" }, { "label": "Эскимосский", "value": "223" }, { "label": "Эсперанто", "value": "14" }, { "label": "Эстонский", "value": "224" }, { "label": "Южно-корейский", "value": "231" }, { "label": "Юкатекский", "value": "225" }, { "label": "Яванский", "value": "227" }, { "label": "Японский", "value": "8" }], "inputType": filterInputs_1.FilterInputs.Picker }, { "key": "type", "label": "Тип:", "values": [{ "label": "Неважно", "value": "0" }, { "label": "Только авторские", "value": "2" }, { "label": "Только переводы", "value": "1" }], "inputType": filterInputs_1.FilterInputs.Picker }, { "key": "trash", "label": "Другое:", "values": [{ "label": "Без фэндомов", "value": "fandoms_ex_all" }, { "label": "Готовые на 100%", "value": "ready" }, { "label": "Доступные для перевода", "value": "tr" }, { "label": "Доступные для скачивания", "value": "gen" }, { "label": "Завершённые проекты", "value": "wealth" }, { "label": "Распродажа", "value": "discount" }, { "label": "Только онгоинги", "value": "ongoings" }, { "label": "Убрать машинный", "value": "remove_machinelate" }], "inputType": filterInputs_1.FilterInputs.Checkbox }, { "key": "sort", "label": "Сортировка:", "values": [{ "label": "По рейтингу", "value": "6" }, { "label": "По дате последней активности", "value": "4" }, { "label": "По дате создания", "value": "3" }, { "label": "По кол-ву бесплатных глав", "value": "11" }, { "label": "По кол-ву в закладках", "value": "13" }, { "label": "По кол-ву в избранном", "value": "14" }, { "label": "По кол-ву лайков", "value": "8" }, { "label": "По кол-ву переведённых глав", "value": "7" }, { "label": "По кол-ву рецензий", "value": "12" }, { "label": "По кол-ву страниц", "value": "10" }, { "label": "По названию на языке оригинала", "value": "1" }, { "label": "По названию на языке перевода", "value": "2" }, { "label": "По просмотрам", "value": "5" }, { "label": "По степени готовности", "value": "0" }, { "label": "Случайно", "value": "9" }], "inputType": filterInputs_1.FilterInputs.Picker }, { "key": "genres", "label": "Жанры:", "values": [{ "label": "18+", "value": "52" }, { "label": "Арт", "value": "1" }, { "label": "Боевик", "value": "2" }, { "label": "Боевые искусства", "value": "3" }, { "label": "Гаремник", "value": "5" }, { "label": "Героическое фэнтези", "value": "7" }, { "label": "Детектив", "value": "8" }, { "label": "Дзёсэй", "value": "9" }, { "label": "Додзинси", "value": "10" }, { "label": "Драма", "value": "11" }, { "label": "История", "value": "13" }, { "label": "Киберпанк", "value": "46" }, { "label": "Кодомо", "value": "14" }, { "label": "Комедия", "value": "15" }, { "label": "Литрпг", "value": "48" }, { "label": "Махо-сёдзё", "value": "16" }, { "label": "Мелодрама", "value": "49" }, { "label": "Меха", "value": "17" }, { "label": "Мистика", "value": "18" }, { "label": "Научная фантастика", "value": "19" }, { "label": "Повседневность", "value": "20" }, { "label": "Постапокалиптика", "value": "21" }, { "label": "Приключения", "value": "22" }, { "label": "Психология", "value": "23" }, { "label": "Романтика", "value": "24" }, { "label": "Самурайский боевик", "value": "25" }, { "label": "Сверхъестественное", "value": "26" }, { "label": "Сёдзё", "value": "27" }, { "label": "Сёнэн", "value": "29" }, { "label": "Смат", "value": "45" }, { "label": "Спорт", "value": "31" }, { "label": "Сэйнэн", "value": "32" }, { "label": "Сюаньхуа", "value": "44" }, { "label": "Сюаньхуань", "value": "47" }, { "label": "Сянься (XianXia)", "value": "42" }, { "label": "Трагедия", "value": "33" }, { "label": "Триллер", "value": "34" }, { "label": "Ужасы", "value": "35" }, { "label": "Уся (wuxia)", "value": "41" }, { "label": "Фантастика", "value": "36" }, { "label": "Фанфик", "value": "50" }, { "label": "Фэнтези", "value": "37" }, { "label": "Школа", "value": "38" }, { "label": "Этти", "value": "39" }, { "label": "Bl", "value": "43" }, { "label": "Gl", "value": "40" }], "inputType": filterInputs_1.FilterInputs.Checkbox }, { "key": "tags", "label": "Тэги:", "values": [{ "label": "12+", "value": "3316" }, { "label": "16+", "value": "83" }, { "label": "Абсурд", "value": "7973" }, { "label": "Авантюристы", "value": "222" }, { "label": "Автомат", "value": "5272" }, { "label": "Авторский мир", "value": "1062" }, { "label": "Агрессивные персонажи", "value": "3249" }, { "label": "Ад", "value": "2623" }, { "label": "Ад и рай", "value": "817" }, { "label": "Адам дженсен", "value": "1649" }, { "label": "Адаптация произведения", "value": "192" }, { "label": "Адвокат", "value": "6340" }, { "label": "Адекватные главные герои", "value": "1953" }, { "label": "Азартные игры", "value": "5301" }, { "label": "Азгард", "value": "3494" }, { "label": "Азула", "value": "5550" }, { "label": "Аид", "value": "7641" }, { "label": "Айдолы", "value": "4081" }, { "label": "Академия", "value": "316" }, { "label": "Акамэ", "value": "5059" }, { "label": "Аквакинез", "value": "5952" }, { "label": "Акира", "value": "2639" }, { "label": "Акнология", "value": "4634" }, { "label": "Актерское мастерство", "value": "4798" }, { "label": "Актёры", "value": "7506" }, { "label": "Активные герои", "value": "6376" }, { "label": "Акутагава рюноске", "value": "4113" }, { "label": "Аладдин", "value": "6489" }, { "label": "Алая ведьма", "value": "4767" }, { "label": "Алиса", "value": "4761" }, { "label": "Алкоголь", "value": "5508" }, { "label": "Аллегория", "value": "271" }, { "label": "Алукард", "value": "4914" }, { "label": "Алхимики", "value": "1164" }, { "label": "Алхимия", "value": "1473" }, { "label": "Алчность", "value": "6897" }, { "label": "Альбус дамблдор", "value": "5784" }, { "label": "Альтернативное развитие событий", "value": "5330" }, { "label": "Альянсы", "value": "328" }, { "label": "Амбициозный главный герой", "value": "3751" }, { "label": "Америка", "value": "4082" }, { "label": "Амнезия", "value": "2207" }, { "label": "Аморальный герой", "value": "18" }, { "label": "Анбу", "value": "8129" }, { "label": "Ангелы", "value": "857" }, { "label": "Ангелы и демоны", "value": "1327" }, { "label": "Ангст", "value": "4638" }, { "label": "Андроиды", "value": "1993" }, { "label": "Анимализм", "value": "5249" }, { "label": "Аниме", "value": "1294" }, { "label": "Анко митараши", "value": "5768" }, { "label": "Антагонист", "value": "2144" }, { "label": "Антигерой", "value": "7725" }, { "label": "Антиквариат", "value": "3552" }, { "label": "Антимаг", "value": "1348" }, { "label": "Антиутопия", "value": "662" }, { "label": "Апокалипсис", "value": "1498" }, { "label": "Аристократия", "value": "371" }, { "label": "Аристократы", "value": "7338" }, { "label": "Армия", "value": "1723" }, { "label": "Артас", "value": "6700" }, { "label": "Артефакты", "value": "2296" }, { "label": "Археология", "value": "6523" }, { "label": "Асгард", "value": "3635" }, { "label": "Ассасин", "value": "1415" }, { "label": "Асуна", "value": "5044" }, { "label": "Аугментации", "value": "7751" }, { "label": "Ацуши накаджима", "value": "4109" }, { "label": "Аянокоджи киетака", "value": "6862" }, { "label": "Бандиты", "value": "2188" }, { "label": "Басейн", "value": "6847" }, { "label": "Баскетбол", "value": "7933" }, { "label": "Бастарды", "value": "76" }, { "label": "Бедность", "value": "1207" }, { "label": "Без культивации", "value": "668" }, { "label": "Без любовной линий", "value": "2225" }, { "label": "Без перерождений", "value": "262" }, { "label": "Без попаданца", "value": "8065" }, { "label": "Без системы", "value": "747" }, { "label": "Без юмора", "value": "763" }, { "label": "Бездна", "value": "1026" }, { "label": "Безжалостное домашнее животное", "value": "1245" }, { "label": "Безжалостные персонажи", "value": "2986" }, { "label": "Беззаботные персонажи", "value": "3123" }, { "label": "Безответная любовь", "value": "7815" }, { "label": "Безработный", "value": "2202" }, { "label": "Безумие", "value": "37" }, { "label": "Безумные персонажи", "value": "2049" }, { "label": "Бейсбол", "value": "7623" }, { "label": "Беременность", "value": "2122" }, { "label": "Бесконечный поток", "value": "7556" }, { "label": "Беспечные персонажи", "value": "742" }, { "label": "Бесплатно", "value": "8403" }, { "label": "Бессмертные персонажи", "value": "566" }, { "label": "Бесстрашные персонажи", "value": "6921" }, { "label": "Бесстыдные персонажи", "value": "1257" }, { "label": "Бесстыдный главный герой", "value": "8190" }, { "label": "Библиотека", "value": "4210" }, { "label": "Библия", "value": "488" }, { "label": "Бизнес", "value": "704" }, { "label": "Биология", "value": "2220" }, { "label": "Биомехи", "value": "1968" }, { "label": "Биседзе", "value": "777" }, { "label": "Битва за веру", "value": "721" }, { "label": "Битва за трон", "value": "7211" }, { "label": "Битва королевств", "value": "1151" }, { "label": "Битва рас", "value": "6989" }, { "label": "Битвы", "value": "1740" }, { "label": "Благородные персонажи", "value": "2201" }, { "label": "Близнецы", "value": "2931" }, { "label": "Богатство", "value": "6522" }, { "label": "Богатые персонажи", "value": "520" }, { "label": "Боги", "value": "173" }, { "label": "Богини", "value": "30" }, { "label": "Богиня", "value": "8324" }, { "label": "Богоубийца", "value": "1253" }, { "label": "Богохульство", "value": "95" }, { "label": "Боевая академия", "value": "2108" }, { "label": "Большая грудь", "value": "4717" }, { "label": "Борос", "value": "6533" }, { "label": "Борьба", "value": "1925" }, { "label": "Борьба за власть", "value": "8072" }, { "label": "Босс и подчиненный", "value": "7157" }, { "label": "Бояръ", "value": "2307" }, { "label": "Брак", "value": "1558" }, { "label": "Брак по расчету", "value": "1389" }, { "label": "Брат и сестра", "value": "615" }, { "label": "Братский комплекс", "value": "2321" }, { "label": "Броманс", "value": "1103" }, { "label": "Брошенные дети", "value": "2846" }, { "label": "Буддизм", "value": "1871" }, { "label": "Будущее", "value": "1820" }, { "label": "Бывший муж", "value": "8080" }, { "label": "Быстрое развитие", "value": "1443" }, { "label": "Бэтгерл", "value": "2584" }, { "label": "Бэтмен", "value": "4668" }, { "label": "В первый раз", "value": "6212" }, { "label": "В этот же мир", "value": "49" }, { "label": "Ваканда", "value": "8331" }, { "label": "Валькирии", "value": "4047" }, { "label": "Вампиры", "value": "2206" }, { "label": "Веб камера", "value": "5664" }, { "label": "Веб новелла", "value": "2349" }, { "label": "Ведьмак", "value": "843" }, { "label": "Ведьмы", "value": "643" }, { "label": "Везучие персонажи", "value": "1879" }, { "label": "Веном", "value": "3994" }, { "label": "Вестерн", "value": "2131" }, { "label": "Вестерос", "value": "8171" }, { "label": "Взросление", "value": "624" }, { "label": "Взрослый главный герой", "value": "2416" }, { "label": "Видео игры", "value": "2630" }, { "label": "Викинги", "value": "267" }, { "label": "Вино", "value": "6972" }, { "label": "Вирт", "value": "6213" }, { "label": "Виртуальная реальность", "value": "325" }, { "label": "Вирусы", "value": "3327" }, { "label": "Владыка демонов", "value": "555" }, { "label": "Власть", "value": "756" }, { "label": "Влюбленность", "value": "6132" }, { "label": "Внешний вид отличается от личности", "value": "1938" }, { "label": "Внучка", "value": "8399" }, { "label": "Военные", "value": "1096" }, { "label": "Возрождение", "value": "1160" }, { "label": "Воины", "value": "287" }, { "label": "Война", "value": "443" }, { "label": "Войны", "value": "2431" }, { "label": "Воландеморт", "value": "4278" }, { "label": "Волейбол", "value": "6415" }, { "label": "Волки", "value": "1166" }, { "label": "Волшебники", "value": "122" }, { "label": "Волшебные существа", "value": "1689" }, { "label": "Волшебство", "value": "719" }, { "label": "Вор", "value": "1399" }, { "label": "Воровка", "value": "6948" }, { "label": "Ворон", "value": "848" }, { "label": "Воскрешение", "value": "6915" }, { "label": "Воспоминания из другого мира", "value": "1366" }, { "label": "Воспоминания из прошлого", "value": "1372" }, { "label": "Воссоединие семьи", "value": "8130" }, { "label": "Восхождение", "value": "380" }, { "label": "Враги становятся любовниками", "value": "978" }, { "label": "Врата", "value": "40" }, { "label": "Врата в другой мир", "value": "1957" }, { "label": "Врач", "value": "1243" }, { "label": "Временная петля", "value": "2852" }, { "label": "Врмморпг", "value": "2043" }, { "label": "Все дозволено", "value": "96" }, { "label": "Всемогущий главный герой", "value": "1414" }, { "label": "Второй шанс", "value": "2372" }, { "label": "Вуайеризм", "value": "2498" }, { "label": "Выживание", "value": "501" }, { "label": "Вымышленные существа", "value": "3466" }, { "label": "Вынужденный брак", "value": "7705" }, { "label": "Высокие технологии", "value": "653" }, { "label": "Высокомерные персонажи", "value": "3250" }, { "label": "Галустян", "value": "5199" }, { "label": "Гангстеры", "value": "7704" }, { "label": "Гарем", "value": "440" }, { "label": "Гарри поттер", "value": "226" }, { "label": "Геймеры", "value": "2130" }, { "label": "Генетические модификации", "value": "1750" }, { "label": "Гениальный главный герой", "value": "1500" }, { "label": "Гений", "value": "1650" }, { "label": "Гермиона грейнджер", "value": "4280" }, { "label": "Герои", "value": "185" }, { "label": "Гигаполис", "value": "8393" }, { "label": "Гильгамеш", "value": "6031" }, { "label": "Гильдии", "value": "900" }, { "label": "Гильдия авантюристов", "value": "1858" }, { "label": "Гинтама", "value": "4544" }, { "label": "Гипноз", "value": "358" }, { "label": "Главная героиня влюбляется первой", "value": "973" }, { "label": "Главный герой бог", "value": "164" }, { "label": "Главный герой влюбляется первым", "value": "3629" }, { "label": "Главный герой выживальщик", "value": "120" }, { "label": "Главный герой гонг", "value": "7877" }, { "label": "Главный герой девушка", "value": "257" }, { "label": "Главный герой демон", "value": "136" }, { "label": "Главный герой женщина", "value": "7329" }, { "label": "Главный герой жестокий", "value": "1553" }, { "label": "Главный герой извращенец", "value": "94" }, { "label": "Главный герой имба", "value": "2421" }, { "label": "Главный герой киборг", "value": "7780" }, { "label": "Главный герой монстр", "value": "869" }, { "label": "Главный герой мужчина", "value": "1997" }, { "label": "Главный герой на стороне сил зла", "value": "1514" }, { "label": "Главный герой не адекватный", "value": "5" }, { "label": "Главный герой не психопат", "value": "7804" }, { "label": "Главный герой не человек", "value": "2172" }, { "label": "Главный герой не эмоционален", "value": "1150" }, { "label": "Главный герой подросток", "value": "2215" }, { "label": "Главный герой позитивный", "value": "7787" }, { "label": "Главный герой психопат", "value": "7803" }, { "label": "Главный герой ребенок", "value": "2347" }, { "label": "Главный герой русский", "value": "2417" }, { "label": "Главный герой сильный с самого начала", "value": "88" }, { "label": "Главный герой скрывает свою силу", "value": "1059" }, { "label": "Главный герой эгоист", "value": "8326" }, { "label": "Гномы", "value": "1870" }, { "label": "Гоблины", "value": "2029" }, { "label": "Годзилла", "value": "6990" }, { "label": "Големы", "value": "1690" }, { "label": "Голливуд", "value": "7754" }, { "label": "Головоломка", "value": "1697" }, { "label": "Горничные", "value": "8091" }, { "label": "Гробница", "value": "388" }, { "label": "Дазай осаму", "value": "4112" }, { "label": "Даньмэй", "value": "3411" }, { "label": "Даосизм", "value": "258" }, { "label": "Дарк соулс", "value": "6057" }, { "label": "Дарт вейдер", "value": "6826" }, { "label": "Дафна гринграсс", "value": "5192" }, { "label": "Дворяне", "value": "7204" }, { "label": "Девушки", "value": "7668" }, { "label": "Девушки монстры", "value": "2231" }, { "label": "Дедушка и внучка", "value": "8400" }, { "label": "Дейви джонс", "value": "8061" }, { "label": "Действие", "value": "1425" }, { "label": "Демон лорд", "value": "153" }, { "label": "Демонология", "value": "2024" }, { "label": "Демоны", "value": "1406" }, { "label": "Дети", "value": "580" }, { "label": "Джарвис", "value": "933" }, { "label": "Джедай", "value": "4442" }, { "label": "Джин", "value": "4024" }, { "label": "Джокер", "value": "3351" }, { "label": "Джон сноу", "value": "7412" }, { "label": "Джоффри баратеон", "value": "3936" }, { "label": "Дзесэй", "value": "678" }, { "label": "Дин винчестер", "value": "6953" }, { "label": "Династии", "value": "2982" }, { "label": "Динозавры", "value": "3666" }, { "label": "Директор", "value": "1417" }, { "label": "Для девушек", "value": "1441" }, { "label": "Дневник", "value": "298" }, { "label": "Добби", "value": "6762" }, { "label": "Добрый мир", "value": "1685" }, { "label": "Договоры с богами", "value": "2152" }, { "label": "Договоры с демонами", "value": "1922" }, { "label": "Доктор", "value": "1991" }, { "label": "Доктор стрэндж", "value": "7634" }, { "label": "Доминирование", "value": "2054" }, { "label": "Дота", "value": "6965" }, { "label": "Доудзюцу", "value": "7133" }, { "label": "Дочь", "value": "3291" }, { "label": "Драко малфой", "value": "46" }, { "label": "Драконы", "value": "282" }, { "label": "Драконы оборотни", "value": "8082" }, { "label": "Древние времена", "value": "7781" }, { "label": "Древний египет", "value": "7614" }, { "label": "Древний китай", "value": "473" }, { "label": "Древний мир", "value": "4" }, { "label": "Другая вселенная", "value": "39" }, { "label": "Другие планеты", "value": "2371" }, { "label": "Другой мир", "value": "2248" }, { "label": "Дружба", "value": "1903" }, { "label": "Друзья детства", "value": "1153" }, { "label": "Духи", "value": "114" }, { "label": "Духовные силы", "value": "1955" }, { "label": "Души", "value": "1212" }, { "label": "Дьявол", "value": "1094" }, { "label": "Дьявольские фрукты", "value": "1564" }, { "label": "Дэдпул", "value": "4399" }, { "label": "Евнух", "value": "6293" }, { "label": "Европейская атмосфера", "value": "5837" }, { "label": "Египет", "value": "528" }, { "label": "Еда", "value": "2056" }, { "label": "Единороги", "value": "437" }, { "label": "Екаи", "value": "655" }, { "label": "Жалкий главный герой", "value": "97" }, { "label": "Жена", "value": "5729" }, { "label": "Женское доминирование", "value": "4622" }, { "label": "Женщина в теле мужчины", "value": "2748" }, { "label": "Женщина кошка", "value": "7513" }, { "label": "Жестокие персонажи", "value": "3153" }, { "label": "Жестокий мир", "value": "1532" }, { "label": "Жестокость", "value": "7880" }, { "label": "Животные", "value": "7488" }, { "label": "Животные компаньоны", "value": "2061" }, { "label": "Жизнь и смерть", "value": "2014" }, { "label": "Жнец", "value": "6288" }, { "label": "Жойен рид", "value": "3926" }, { "label": "Заботливый главный герой", "value": "338" }, { "label": "Закалка тела", "value": "148" }, { "label": "Заклинания", "value": "558" }, { "label": "Заключенные", "value": "3052" }, { "label": "Занпакто", "value": "1102" }, { "label": "Запретная любовь", "value": "8033" }, { "label": "Запутанный сюжет", "value": "1041" }, { "label": "Захват мира", "value": "315" }, { "label": "Зачарованные", "value": "4169" }, { "label": "Звери", "value": "1638" }, { "label": "Зверодевочки", "value": "2006" }, { "label": "Зверолюди", "value": "1018" }, { "label": "Земля", "value": "82" }, { "label": "Злая организация", "value": "7768" }, { "label": "Зло", "value": "1512" }, { "label": "Злодей", "value": "1060" }, { "label": "Злодейка", "value": "2376" }, { "label": "Злой главный герой", "value": "616" }, { "label": "Злые боги", "value": "7109" }, { "label": "Злые персонажи", "value": "3243" }, { "label": "Змей", "value": "5721" }, { "label": "Знаменитости", "value": "1341" }, { "label": "Знание медицины", "value": "1411" }, { "label": "Золушка", "value": "2980" }, { "label": "Зомби", "value": "1743" }, { "label": "Зомби апокалипсис", "value": "912" }, { "label": "Зона 51", "value": "3051" }, { "label": "Зооморфы", "value": "375" }, { "label": "Зорро", "value": "6736" }, { "label": "Зрелые женщины", "value": "1458" }, { "label": "Игра", "value": "663" }, { "label": "Игра на выживание", "value": "2182" }, { "label": "Игровая система", "value": "384" }, { "label": "Игровые элементы", "value": "720" }, { "label": "Извращения", "value": "651" }, { "label": "Измена", "value": "1874" }, { "label": "Изменение характера", "value": "1113" }, { "label": "Изменения внешности", "value": "259" }, { "label": "Изменения личности", "value": "1080" }, { "label": "Изобретения", "value": "126" }, { "label": "Изуку мидория", "value": "6967" }, { "label": "Император", "value": "867" }, { "label": "Империи", "value": "712" }, { "label": "Империя", "value": "1716" }, { "label": "Инвалидность", "value": "2073" }, { "label": "Инквизитор", "value": "143" }, { "label": "Инкуб", "value": "3264" }, { "label": "Инопланетное вторжение", "value": "209" }, { "label": "Инопланетяне", "value": "866" }, { "label": "Интерактив с читателями", "value": "472" }, { "label": "Интересный сюжет", "value": "7374" }, { "label": "Интернет", "value": "739" }, { "label": "Интимные сцены", "value": "3450" }, { "label": "Интрига", "value": "317" }, { "label": "Интриги и заговоры", "value": "1009" }, { "label": "Иные миры", "value": "35" }, { "label": "Исекай", "value": "2979" }, { "label": "Искусственный интеллект", "value": "1900" }, { "label": "Исследование", "value": "1626" }, { "label": "Исторический роман", "value": "573" }, { "label": "Итачи учиха", "value": "4556" }, { "label": "Ичиго", "value": "7254" }, { "label": "Йода", "value": "6829" }, { "label": "Йоруичи", "value": "6755" }, { "label": "Калипсо", "value": "8062" }, { "label": "Каннибализм", "value": "2249" }, { "label": "Капитан америка", "value": "6301" }, { "label": "Каракура", "value": "7473" }, { "label": "Карточная игра", "value": "1557" }, { "label": "Кастиэль", "value": "6954" }, { "label": "Кафе", "value": "3934" }, { "label": "Кацуки бакуго", "value": "7696" }, { "label": "Квесты", "value": "1707" }, { "label": "Киберспорт", "value": "1984" }, { "label": "Кино", "value": "7126" }, { "label": "Китай", "value": "3762" }, { "label": "Кицунэ", "value": "241" }, { "label": "Кланы", "value": "834" }, { "label": "Клоны", "value": "1624" }, { "label": "Книги", "value": "1068" }, { "label": "Книжный червь", "value": "521" }, { "label": "Колдовство", "value": "2681" }, { "label": "колледж", "value": "5058" }, { "label": "Коллекционер", "value": "2588" }, { "label": "Кольцо", "value": "1628" }, { "label": "Коммунисты", "value": "1042" }, { "label": "Коноха", "value": "2827" }, { "label": "Контракт", "value": "4304" }, { "label": "Контроль разума", "value": "485" }, { "label": "Конфеты", "value": "341" }, { "label": "Корейцы", "value": "6535" }, { "label": "Корея", "value": "2443" }, { "label": "Королевская власть", "value": "55" }, { "label": "Королевская семья", "value": "276" }, { "label": "Королевство", "value": "1695" }, { "label": "Короткий рассказ", "value": "239" }, { "label": "Коррупция", "value": "831" }, { "label": "Космическая опера", "value": "2245" }, { "label": "Космические рейнджеры", "value": "5860" }, { "label": "Космос", "value": "329" }, { "label": "Кот", "value": "5171" }, { "label": "Кража навыков", "value": "1159" }, { "label": "Красивая главная героиня", "value": "186" }, { "label": "Красивые женщины", "value": "66" }, { "label": "Красивые персонажи", "value": "5787" }, { "label": "Красивый главный герой", "value": "895" }, { "label": "Крафт", "value": "1599" }, { "label": "Кроссовер", "value": "75" }, { "label": "Ктулху", "value": "920" }, { "label": "Кузнец", "value": "853" }, { "label": "Кукла", "value": "3085" }, { "label": "Кулинария", "value": "2230" }, { "label": "Культивация", "value": "1901" }, { "label": "Культивирование", "value": "1860" }, { "label": "Курама", "value": "5709" }, { "label": "Курилин", "value": "6134" }, { "label": "Кушина узумаки", "value": "5222" }, { "label": "Лавкрафт", "value": "6063" }, { "label": "Лара крофт", "value": "6435" }, { "label": "Легенда о зельде", "value": "5707" }, { "label": "Ленивый главный герой", "value": "1516" }, { "label": "Леон золдик", "value": "7469" }, { "label": "Лес", "value": "6645" }, { "label": "Лечебная магия", "value": "562" }, { "label": "Локи", "value": "1725" }, { "label": "Лоли", "value": "1576" }, { "label": "Лопата", "value": "4989" }, { "label": "Лорд", "value": "8404" }, { "label": "Лориен", "value": "7397" }, { "label": "Лошади", "value": "6110" }, { "label": "Лунатизм", "value": "3520" }, { "label": "Луффи", "value": "274" }, { "label": "Лучник", "value": "1038" }, { "label": "Любовный интерес влюбляется первым", "value": "7753" }, { "label": "Любовный треугольник", "value": "2109" }, { "label": "Любовь", "value": "2297" }, { "label": "Любовь с первого взгляда", "value": "7748" }, { "label": "Любящие родители", "value": "2699" }, { "label": "Люди", "value": "3572" }, { "label": "Люцифер", "value": "5883" }, { "label": "Маг", "value": "780" }, { "label": "Магазин", "value": "4762" }, { "label": "Маги", "value": "58" }, { "label": "Магическая академия", "value": "6788" }, { "label": "Магические звери", "value": "684" }, { "label": "Магические предметы", "value": "1648" }, { "label": "Магический мир", "value": "578" }, { "label": "Магия", "value": "150" }, { "label": "Магия воды", "value": "6450" }, { "label": "Магия воздуха", "value": "7627" }, { "label": "Магия земли", "value": "7626" }, { "label": "Магия и технология", "value": "107" }, { "label": "Магия крови", "value": "7976" }, { "label": "Магия льда", "value": "1379" }, { "label": "Магия огня", "value": "7625" }, { "label": "Магия призыва", "value": "885" }, { "label": "Магия природы", "value": "6226" }, { "label": "Магия стихий", "value": "7673" }, { "label": "Магия тьмы", "value": "3596" }, { "label": "Мадара", "value": "2929" }, { "label": "Мазохизм", "value": "1961" }, { "label": "Мама", "value": "12" }, { "label": "Мама и дочь", "value": "7894" }, { "label": "Мама и сын", "value": "7895" }, { "label": "Манга", "value": "2464" }, { "label": "Манипуляция временем", "value": "932" }, { "label": "Маньяк", "value": "2026" }, { "label": "Маргери тирелл", "value": "3935" }, { "label": "Марионетки", "value": "3175" }, { "label": "Марс", "value": "4013" }, { "label": "Марти стью", "value": "594" }, { "label": "Мастер на все руки", "value": "3189" }, { "label": "Матриархат", "value": "7197" }, { "label": "Мать и сестры", "value": "7946" }, { "label": "Мафия", "value": "353" }, { "label": "Мачеха", "value": "4664" }, { "label": "Мегаполис", "value": "3322" }, { "label": "Медицина", "value": "441" }, { "label": "Медленная романтика", "value": "8383" }, { "label": "Медленное развитие истории", "value": "7462" }, { "label": "Мелиодас", "value": "7224" }, { "label": "Мелодрама", "value": "1507" }, { "label": "Менеджмент", "value": "368" }, { "label": "Мерлин", "value": "3977" }, { "label": "Месть", "value": "1218" }, { "label": "Меч", "value": "48" }, { "label": "Мечники", "value": "969" }, { "label": "Мечта", "value": "527" }, { "label": "Мизуки", "value": "4269" }, { "label": "Микото", "value": "3862" }, { "label": "Милая главная героиня", "value": "134" }, { "label": "Милф", "value": "1987" }, { "label": "Милый главный герой", "value": "2678" }, { "label": "Мимик", "value": "5706" }, { "label": "Мина ашидо", "value": "7695" }, { "label": "Минато намикадзе", "value": "5223" }, { "label": "Мир будущего", "value": "1770" }, { "label": "Мир земли", "value": "8394" }, { "label": "Мир меча и магии", "value": "1271" }, { "label": "Мистер пропер", "value": "565" }, { "label": "Мифические существа", "value": "1878" }, { "label": "Мифы и легенды", "value": "4463" }, { "label": "Младшая сестра", "value": "1523" }, { "label": "Мморпг", "value": "620" }, { "label": "Много главных героев", "value": "1191" }, { "label": "Много крови", "value": "5318" }, { "label": "Много персонажей", "value": "1539" }, { "label": "Множество королевств", "value": "32" }, { "label": "Модерн", "value": "5457" }, { "label": "Мокутон", "value": "4438" }, { "label": "Молоко", "value": "5469" }, { "label": "Монархия", "value": "3590" }, { "label": "Монстры", "value": "307" }, { "label": "Море", "value": "922" }, { "label": "Моритика ринносукэ", "value": "1142" }, { "label": "Мортал комбат", "value": "5861" }, { "label": "Мошенник", "value": "959" }, { "label": "Мрачный мир", "value": "1" }, { "label": "Мужчина в женском теле", "value": "8405" }, { "label": "Музыка", "value": "1183" }, { "label": "Мультивселенная", "value": "7410" }, { "label": "Мурим", "value": "7342" }, { "label": "Мутанты", "value": "2392" }, { "label": "Мутация", "value": "29" }, { "label": "Мясо", "value": "1503" }, { "label": "На реальных событиях", "value": "26" }, { "label": "Навыки", "value": "415" }, { "label": "Нагато узумаки", "value": "5221" }, { "label": "Наемники", "value": "1668" }, { "label": "Назарик", "value": "5369" }, { "label": "Наивный главный герой", "value": "159" }, { "label": "Наложница", "value": "4867" }, { "label": "Наноботы", "value": "2332" }, { "label": "Наруто", "value": "7177" }, { "label": "Наруто и хината", "value": "5766" }, { "label": "Насилие и жестокость", "value": "1440" }, { "label": "Наука", "value": "2150" }, { "label": "Национализм", "value": "5556" }, { "label": "Нацу", "value": "5826" }, { "label": "Нацуки субару", "value": "6656" }, { "label": "Начальная школа", "value": "3920" }, { "label": "Наши дни", "value": "1814" }, { "label": "Не всесильный главный герой", "value": "42" }, { "label": "Не по канону", "value": "1611" }, { "label": "Неверность", "value": "5735" }, { "label": "Невеста", "value": "6011" }, { "label": "Неджи хьюга", "value": "3099" }, { "label": "Недооценённый главный герой", "value": "43" }, { "label": "Нежить", "value": "1949" }, { "label": "Некромаг", "value": "7441" }, { "label": "Некромант", "value": "1914" }, { "label": "Некромантия", "value": "754" }, { "label": "Ненормативная лексика", "value": "160" }, { "label": "Необычные герои", "value": "67" }, { "label": "Нет людей", "value": "7486" }, { "label": "Нетораре", "value": "403" }, { "label": "Нетори", "value": "5393" }, { "label": "Нефилимы", "value": "7764" }, { "label": "Нецензурная лексика", "value": "4912" }, { "label": "Нечисть", "value": "4559" }, { "label": "Ник фьюри", "value": "6304" }, { "label": "Ниндзюцу", "value": "2354" }, { "label": "Ниндзя", "value": "1330" }, { "label": "Новелла", "value": "2105" }, { "label": "Нэко", "value": "147" }, { "label": "Оби ван кеноби", "value": "6830" }, { "label": "Обито учиха", "value": "2814" }, { "label": "Оборотни", "value": "53" }, { "label": "Обратный гарем", "value": "3303" }, { "label": "Овощ", "value": "6098" }, { "label": "Огнестрельное оружие", "value": "3155" }, { "label": "Одержимость", "value": "708" }, { "label": "Один в поле воин", "value": "6498" }, { "label": "Онлайн игра", "value": "1565" }, { "label": "Ооками теппей", "value": "849" }, { "label": "Оригинальные персонажи", "value": "7741" }, { "label": "Орки", "value": "1597" }, { "label": "Оружие", "value": "125" }, { "label": "Основано на видео игре", "value": "602" }, { "label": "Особые способности", "value": "2904" }, { "label": "От бедности к богатству", "value": "901" }, { "label": "От слабого до сильного", "value": "118" }, { "label": "Отель", "value": "2879" }, { "label": "Отец", "value": "3290" }, { "label": "Отношения", "value": "398" }, { "label": "Отношения человек/нечеловек", "value": "7406" }, { "label": "Офис", "value": "3460" }, { "label": "Охотники", "value": "2263" }, { "label": "Оцуцуки", "value": "5101" }, { "label": "Ошейник", "value": "2362" }, { "label": "Ояш", "value": "8048" }, { "label": "Падчерица", "value": "7023" }, { "label": "Падший ангел", "value": "184" }, { "label": "Палач", "value": "852" }, { "label": "Палочка", "value": "2682" }, { "label": "Пандорум", "value": "4360" }, { "label": "Папа и дочь", "value": "7647" }, { "label": "Паразит", "value": "1213" }, { "label": "Параллельный мир", "value": "2092" }, { "label": "Парень", "value": "619" }, { "label": "Паркур", "value": "3391" }, { "label": "Пародия", "value": "898" }, { "label": "Пасхалки", "value": "455" }, { "label": "Паук", "value": "2209" }, { "label": "Пекарь", "value": "5073" }, { "label": "Первая книга", "value": "269" }, { "label": "Первая любовь", "value": "640" }, { "label": "Первый раз", "value": "1465" }, { "label": "Переводы", "value": "24" }, { "label": "Перевоплощение", "value": "1596" }, { "label": "Перевоплощение в игровом мире", "value": "92" }, { "label": "Перемещение в другой мир", "value": "1288" }, { "label": "Перемещение во времени", "value": "146" }, { "label": "Перерождение", "value": "894" }, { "label": "Перерождение в демона", "value": "1111" }, { "label": "Перерождение в дракона", "value": "6867" }, { "label": "Перерождение в злодейку", "value": "5619" }, { "label": "Перерождение в злодея", "value": "749" }, { "label": "Перерождение в ином мире", "value": "109" }, { "label": "Перерождение в монстра", "value": "917" }, { "label": "Перерождений", "value": "335" }, { "label": "Переселение", "value": "813" }, { "label": "Переселение души", "value": "1864" }, { "label": "Перси джексон", "value": "6329" }, { "label": "Пилот", "value": "5521" }, { "label": "Пилюли", "value": "1531" }, { "label": "Пират", "value": "1579" }, { "label": "Пирог", "value": "80" }, { "label": "Писатель", "value": "734" }, { "label": "Пистолеты", "value": "4916" }, { "label": "Письмо", "value": "840" }, { "label": "Питомцы", "value": "3122" }, { "label": "Планомерное развитие событий", "value": "62" }, { "label": "Племянник", "value": "8303" }, { "label": "Пленница", "value": "4897" }, { "label": "Плети", "value": "4839" }, { "label": "Пляж", "value": "4243" }, { "label": "Повар", "value": "658" }, { "label": "Повествование от первого лица", "value": "1054" }, { "label": "Повествование от разных лиц", "value": "600" }, { "label": "Повествование от третьего лица", "value": "2116" }, { "label": "Подавитель", "value": "497" }, { "label": "Подземелье", "value": "798" }, { "label": "Подростки", "value": "636" }, { "label": "Подруга", "value": "5804" }, { "label": "Подчинение", "value": "8343" }, { "label": "Подчинение и унижение", "value": "4500" }, { "label": "Покемоны", "value": "2840" }, { "label": "Полиамория", "value": "1300" }, { "label": "Полигамия", "value": "1336" }, { "label": "Политика", "value": "1313" }, { "label": "Полицейский", "value": "1907" }, { "label": "Полубог", "value": "7170" }, { "label": "Полукровка", "value": "999" }, { "label": "Полулюди", "value": "2273" }, { "label": "Поношенные трусики", "value": "1204" }, { "label": "Попаданец", "value": "2396" }, { "label": "Попаданец в другой мир", "value": "685" }, { "label": "Попаданец в игру", "value": "6466" }, { "label": "Попадание в книгу", "value": "6957" }, { "label": "Постапокалипсис", "value": "1079" }, { "label": "Похищение", "value": "7452" }, { "label": "Поэзия", "value": "1120" }, { "label": "Правитель", "value": "2261" }, { "label": "Превращения в животных", "value": "3410" }, { "label": "Преданный любовный интерес", "value": "2055" }, { "label": "Предательство", "value": "70" }, { "label": "Президент", "value": "4334" }, { "label": "Преступник", "value": "4049" }, { "label": "Преступный мир", "value": "965" }, { "label": "Призрак", "value": "511" }, { "label": "Призыв", "value": "332" }, { "label": "Призыв в другой мир", "value": "781" }, { "label": "Призыв существ", "value": "412" }, { "label": "Приложение на телефоне", "value": "5345" }, { "label": "Принудительный брак", "value": "2954" }, { "label": "Принуждение", "value": "1442" }, { "label": "Принц", "value": "362" }, { "label": "Принцесса", "value": "2403" }, { "label": "Приручение мостров", "value": "2338" }, { "label": "Прислуга", "value": "5185" }, { "label": "Пришельцы", "value": "273" }, { "label": "Проза", "value": "2012" }, { "label": "Прокачка", "value": "1070" }, { "label": "Проклятия", "value": "1347" }, { "label": "Проработанный мир", "value": "1711" }, { "label": "Пророчество", "value": "7762" }, { "label": "Против наркотиков", "value": "8406" }, { "label": "Псайкеры", "value": "3659" }, { "label": "Псионика", "value": "5216" }, { "label": "Психбольница", "value": "6969" }, { "label": "Психические расстройства", "value": "2445" }, { "label": "Психологические травмы", "value": "3418" }, { "label": "Публичный дом", "value": "7860" }, { "label": "Путешествие в другой мир", "value": "10" }, { "label": "Пух", "value": "4286" }, { "label": "Пушечное мясо", "value": "7234" }, { "label": "Пытки", "value": "1756" }, { "label": "Пьяный мастер", "value": "1655" }, { "label": "Пэнси паркинсон", "value": "7411" }, { "label": "Раб", "value": "977" }, { "label": "Рабы", "value": "1240" }, { "label": "Разведение животных", "value": "3990" }, { "label": "Развитие", "value": "208" }, { "label": "Развитие персонажа", "value": "1780" }, { "label": "Развитие поселения", "value": "7203" }, { "label": "Развитие технологий", "value": "1875" }, { "label": "Раздвоение личности", "value": "2062" }, { "label": "Разные расы", "value": "1188" }, { "label": "Разорванная помолвка", "value": "2057" }, { "label": "Разработчик", "value": "2333" }, { "label": "Ранги", "value": "1568" }, { "label": "Ранобэ", "value": "1764" }, { "label": "Расизм", "value": "3554" }, { "label": "Растение", "value": "407" }, { "label": "Реализм", "value": "1180" }, { "label": "Ребенок", "value": "2881" }, { "label": "Ревность", "value": "293" }, { "label": "Революция", "value": "3996" }, { "label": "Реинкарнация", "value": "1302" }, { "label": "Реинкарнация в другом мире", "value": "2180" }, { "label": "Реинкарнация в игровой мир", "value": "304" }, { "label": "Рейджер", "value": "5147" }, { "label": "Религия", "value": "2184" }, { "label": "Рем", "value": "6655" }, { "label": "Ремесленник", "value": "1483" }, { "label": "Ремонт", "value": "5703" }, { "label": "Репликаторы", "value": "3495" }, { "label": "Ресторан", "value": "7519" }, { "label": "Риас гремори", "value": "6950" }, { "label": "Рим", "value": "612" }, { "label": "Риннеган", "value": "4230" }, { "label": "Ритуал", "value": "1233" }, { "label": "Робот", "value": "4011" }, { "label": "Роботы", "value": "467" }, { "label": "Рок ли", "value": "7002" }, { "label": "Рокси", "value": "7380" }, { "label": "Рон уизли", "value": "4279" }, { "label": "Ророноа зоро", "value": "1590" }, { "label": "Росомаха", "value": "1035" }, { "label": "Российская империя", "value": "2146" }, { "label": "Россия", "value": "4246" }, { "label": "Рудеус", "value": "7379" }, { "label": "Руны", "value": "2393" }, { "label": "Русалки", "value": "3127" }, { "label": "Русь", "value": "2016" }, { "label": "Рыцари", "value": "1902" }, { "label": "Рэо хатаке", "value": "2823" }, { "label": "Сабли", "value": "6136" }, { "label": "Сайян", "value": "6802" }, { "label": "Сакура", "value": "2515" }, { "label": "Самец", "value": "1592" }, { "label": "Самураи", "value": "576" }, { "label": "Санса старк", "value": "3925" }, { "label": "Сарказм", "value": "4658" }, { "label": "Саске", "value": "7237" }, { "label": "Сатира", "value": "215" }, { "label": "Сборник", "value": "7367" }, { "label": "Свадьба", "value": "1524" }, { "label": "Сверхсила", "value": "1055" }, { "label": "Свинцовые книги", "value": "5322" }, { "label": "Связывание", "value": "4506" }, { "label": "Священик", "value": "61" }, { "label": "Северус снейп", "value": "5783" }, { "label": "Сёдзе", "value": "2219" }, { "label": "Секты", "value": "1234" }, { "label": "Сельское хозяйство", "value": "787" }, { "label": "Семейный конфликт", "value": "935" }, { "label": "Семья", "value": "728" }, { "label": "Сенджу", "value": "6069" }, { "label": "Серийный убийца", "value": "261" }, { "label": "Сестра", "value": "2342" }, { "label": "Сила глаза", "value": "1019" }, { "label": "Сильная героиня", "value": "7292" }, { "label": "Сильная главная героиня", "value": "1994" }, { "label": "Сильный главный герой", "value": "570" }, { "label": "Сильфиетта", "value": "7381" }, { "label": "Симбиот", "value": "2648" }, { "label": "Сириус блэк", "value": "7655" }, { "label": "Сирота", "value": "297" }, { "label": "Система", "value": "251" }, { "label": "Система уровней", "value": "2174" }, { "label": "Ситх", "value": "1618" }, { "label": "Сказка", "value": "3570" }, { "label": "Скайрим", "value": "4032" }, { "label": "Скайуокер", "value": "6828" }, { "label": "Сквиб", "value": "4101" }, { "label": "Скелет", "value": "1315" }, { "label": "Скрытые способности", "value": "3417" }, { "label": "Скульптор", "value": "1178" }, { "label": "Слабая главная героиня", "value": "5805" }, { "label": "Слабый главный герой", "value": "731" }, { "label": "Славяне", "value": "2168" }, { "label": "Слизерин", "value": "6979" }, { "label": "Слизь", "value": "1095" }, { "label": "Сломанная игрушка", "value": "8396" }, { "label": "Служанка", "value": "3486" }, { "label": "Смартфон", "value": "457" }, { "label": "Смена сущности", "value": "8391" }, { "label": "Смерть", "value": "1779" }, { "label": "Смерть основного персонажа", "value": "1530" }, { "label": "Собаки", "value": "6109" }, { "label": "Соблазн", "value": "7994" }, { "label": "Соблазнение", "value": "2290" }, { "label": "Современность", "value": "568" }, { "label": "Современные знания", "value": "988" }, { "label": "Сожительство", "value": "3026" }, { "label": "Создание армии", "value": "1992" }, { "label": "Создание королевства", "value": "1497" }, { "label": "Создание пилюль", "value": "816" }, { "label": "Создатель", "value": "1045" }, { "label": "Сокровища", "value": "6521" }, { "label": "Сокрытие истинной личности", "value": "2894" }, { "label": "Сома и эрина", "value": "5737" }, { "label": "Соперничество", "value": "7699" }, { "label": "Соседи", "value": "4075" }, { "label": "Сотрудник", "value": "6339" }, { "label": "Социология", "value": "7618" }, { "label": "Спокойная главная героиня", "value": "236" }, { "label": "Спокойный главный герой", "value": "1656" }, { "label": "Спор", "value": "3484" }, { "label": "Спортивное тело", "value": "8317" }, { "label": "Способность кражи", "value": "7784" }, { "label": "Сражения", "value": "23" }, { "label": "Средневековье", "value": "1022" }, { "label": "Сталкер", "value": "1932" }, { "label": "Становление государства", "value": "111" }, { "label": "Старшая школа", "value": "1658" }, { "label": "Стёб", "value": "454" }, { "label": "Стекло", "value": "7453" }, { "label": "Стеснительный персонаж", "value": "152" }, { "label": "Стимпанк", "value": "1894" }, { "label": "Стихи", "value": "1309" }, { "label": "Стратегия", "value": "569" }, { "label": "Строительство", "value": "921" }, { "label": "Студент", "value": "1464" }, { "label": "Студентка", "value": "7518" }, { "label": "Суккубы", "value": "2662" }, { "label": "Супер зрение", "value": "6574" }, { "label": "Супер удача", "value": "489" }, { "label": "Супергерои", "value": "1481" }, { "label": "Суперзлодеи", "value": "2125" }, { "label": "Супермен", "value": "6997" }, { "label": "Суперсилы", "value": "2276" }, { "label": "Существа", "value": "6033" }, { "label": "Сферы", "value": "1077" }, { "label": "Схемы и заговоры", "value": "7116" }, { "label": "Сценарий", "value": "7489" }, { "label": "Счастливый конец", "value": "3293" }, { "label": "Сын", "value": "3297" }, { "label": "Сэм винчестер", "value": "7461" }, { "label": "Сюаньхуа", "value": "2560" }, { "label": "Сюжетные повороты", "value": "7202" }, { "label": "Таблетки для развития", "value": "589" }, { "label": "Таинственное прошлое", "value": "769" }, { "label": "Тайная личность", "value": "8096" }, { "label": "Тайная любовь", "value": "113" }, { "label": "Тайны", "value": "7481" }, { "label": "Тайные отношения", "value": "7450" }, { "label": "Тайцы", "value": "6413" }, { "label": "Танки", "value": "1787" }, { "label": "Творчество", "value": "20" }, { "label": "Тейлор эберт", "value": "3526" }, { "label": "Телекинез", "value": "2203" }, { "label": "Телепортация", "value": "914" }, { "label": "Телохранитель", "value": "723" }, { "label": "Темари", "value": "4810" }, { "label": "Темная магия", "value": "4788" }, { "label": "Темное фэнтези", "value": "1675" }, { "label": "Темные эльфы", "value": "7198" }, { "label": "Тенсейган", "value": "4367" }, { "label": "Тетя", "value": "4194" }, { "label": "Техномагия", "value": "508" }, { "label": "Тиран", "value": "1174" }, { "label": "Титаны", "value": "3308" }, { "label": "Тодороки шото", "value": "5105" }, { "label": "Токио", "value": "5791" }, { "label": "Том реддл", "value": "6652" }, { "label": "Тони старк", "value": "1338" }, { "label": "Тор", "value": "1800" }, { "label": "Тор и локи", "value": "2645" }, { "label": "Торговля", "value": "1637" }, { "label": "Травничество", "value": "221" }, { "label": "Трагическое прошлое", "value": "644" }, { "label": "Трактир", "value": "1918" }, { "label": "Трансмиграция", "value": "1071" }, { "label": "Трансформация", "value": "156" }, { "label": "Трансформеры", "value": "4616" }, { "label": "Тревор филипс", "value": "5427" }, { "label": "Тройняшки", "value": "7169" }, { "label": "Троли", "value": "4250" }, { "label": "Трудолюбивый главный герой", "value": "248" }, { "label": "Тупой главный герой", "value": "3710" }, { "label": "Тьма", "value": "1919" }, { "label": "Тюрьма", "value": "5597" }, { "label": "Тяжёлое детство", "value": "2253" }, { "label": "Убийства", "value": "378" }, { "label": "Убийцы", "value": "1766" }, { "label": "Убийцы драконов", "value": "1484" }, { "label": "Увечья", "value": "3266" }, { "label": "Удача", "value": "6575" }, { "label": "Узумаки", "value": "7579" }, { "label": "Укротитель", "value": "367" }, { "label": "Умения", "value": "531" }, { "label": "Умная главная героиня", "value": "1381" }, { "label": "Умные персонажи", "value": "2756" }, { "label": "Умный главный герой", "value": "2093" }, { "label": "Университет", "value": "2102" }, { "label": "Унижение", "value": "8342" }, { "label": "Уничтожение мира", "value": "81" }, { "label": "Управление временем", "value": "5648" }, { "label": "Уровни", "value": "8" }, { "label": "Усиление", "value": "3549" }, { "label": "Усопп", "value": "6737" }, { "label": "Устроенный брак", "value": "2223" }, { "label": "Усыновление", "value": "395" }, { "label": "Утопия", "value": "4677" }, { "label": "Уход за детьми", "value": "7609" }, { "label": "Учеба в университете", "value": "2797" }, { "label": "Учебное заведение", "value": "1817" }, { "label": "Ученые", "value": "1843" }, { "label": "Учитель", "value": "845" }, { "label": "Учиха", "value": "5348" }, { "label": "Фамильяры", "value": "1471" }, { "label": "Фанатичная любовь", "value": "6721" }, { "label": "Фанаты", "value": "7739" }, { "label": "Фантастический мир", "value": "2414" }, { "label": "Фармацевт", "value": "1706" }, { "label": "Фашисты", "value": "3118" }, { "label": "Феи", "value": "7185" }, { "label": "Фелляция", "value": "5880" }, { "label": "Феминизм", "value": "6527" }, { "label": "Феникс", "value": "2413" }, { "label": "Фенрир", "value": "2740" }, { "label": "Феодализм", "value": "280" }, { "label": "Ферма", "value": "285" }, { "label": "Фехтовальщик", "value": "4685" }, { "label": "Филиппины", "value": "128" }, { "label": "Философия", "value": "1859" }, { "label": "Флафф", "value": "5048" }, { "label": "Флер делакур", "value": "5191" }, { "label": "Флэш", "value": "4667" }, { "label": "Фокусник", "value": "7602" }, { "label": "Фольклор", "value": "4086" }, { "label": "Фугаку", "value": "6161" }, { "label": "Фурри", "value": "6631" }, { "label": "Футбол", "value": "1121" }, { "label": "Фэнтезийный мир", "value": "1556" }, { "label": "Хакер", "value": "475" }, { "label": "Халк", "value": "1196" }, { "label": "Хан нуньен синг", "value": "4817" }, { "label": "Ханма юджиро", "value": "4369" }, { "label": "Хаос", "value": "3117" }, { "label": "Харизматичный главный герой", "value": "2350" }, { "label": "Хатаке какаши", "value": "2820" }, { "label": "Хиддлстон", "value": "5903" }, { "label": "Химавари", "value": "2583" }, { "label": "Хината", "value": "2513" }, { "label": "Хитрый главный герой", "value": "2036" }, { "label": "Хоббит", "value": "6698" }, { "label": "Хогвартс", "value": "5954" }, { "label": "Холодная главная героиня", "value": "6507" }, { "label": "Холодное оружие", "value": "4889" }, { "label": "Холодный главный герой", "value": "2686" }, { "label": "Храм", "value": "2135" }, { "label": "Христианство", "value": "877" }, { "label": "Художественная литература", "value": "2380" }, { "label": "Художница", "value": "518" }, { "label": "Хулиганы", "value": "854" }, { "label": "Цветок", "value": "902" }, { "label": "Цезарь", "value": "1705" }, { "label": "Целители", "value": "4523" }, { "label": "Церковь", "value": "1980" }, { "label": "Цундере", "value": "1078" }, { "label": "Чакра", "value": "1393" }, { "label": "Чат-система", "value": "8407" }, { "label": "Черный юмор", "value": "2868" }, { "label": "Честная главная героиня", "value": "5855" }, { "label": "Честный главный герой", "value": "129" }, { "label": "Читы", "value": "451" }, { "label": "Шантаж", "value": "7175" }, { "label": "Шаринган", "value": "5165" }, { "label": "Шинигами", "value": "4661" }, { "label": "Шиноби", "value": "1227" }, { "label": "Школьная жизнь", "value": "284" }, { "label": "Школьники", "value": "218" }, { "label": "Школьницы", "value": "5946" }, { "label": "Шлюха", "value": "5822" }, { "label": "Шоу-бизнес", "value": "7119" }, { "label": "Шпионы", "value": "4262" }, { "label": "Эволюция", "value": "2040" }, { "label": "Экзорцизм", "value": "676" }, { "label": "Экономика", "value": "121" }, { "label": "Экспансия", "value": "110" }, { "label": "Эксперименты над людьми", "value": "7408" }, { "label": "Элементальная магия", "value": "1264" }, { "label": "Эльфы", "value": "1362" }, { "label": "Эротика", "value": "2053" }, { "label": "Юмор", "value": "7360" }, { "label": "Яды", "value": "201" }, { "label": "Якудза", "value": "4599" }, { "label": "Яндере", "value": "7111" }, { "label": "Rpg", "value": "90" }, { "label": "Star wars", "value": "1985" }, { "label": "Time skip", "value": "824" }, { "label": "Warrior of light", "value": "5289" }], "inputType": filterInputs_1.FilterInputs.Checkbox }, { "key": "fandoms", "label": "Фэндом:", "values": [{ "label": "19 Дней - Один день / 19 Days - One Day", "value": "838" }, { "label": "47-й / Хитмэн: Агент 47 / Наёмный убийца / Hitman", "value": "589" }, { "label": "Абсолютный дуэт / Absolute Duo", "value": "1029" }, { "label": "Аватар (Короля; об Аанге; об Корре) / Avatar", "value": "1889" }, { "label": "Аватар: Легенда о Корре / Avatar legend of Korra", "value": "351" }, { "label": "Аватар: Легенда об Аанге / Avatar: The Legend of Aang / Avatar: The Last Airbender", "value": "303" }, { "label": "Аватар(Фильм, 2009) / Avatar", "value": "19" }, { "label": "Ад Данте(Данте Алигьери) / Dante's Inferno(Dante Alighieri)", "value": "1502" }, { "label": "Азур Лейн / Azur Lane", "value": "1009" }, { "label": "Айон / Aion", "value": "1005" }, { "label": "Аладдин / Aladdin", "value": "502" }, { "label": "Алиса в Стране чудес / Alice in Wonderland", "value": "616" }, { "label": "Альдноа.Зеро / Aldnoah.Zero", "value": "1799" }, { "label": "Амагами СС / Amagami SS", "value": "900" }, { "label": "Амано Мегуми полна любви! / Amano Megumi wa Sukidarake!", "value": "991" }, { "label": "Американские боги / American Gods", "value": "1843" }, { "label": "Американский папаша! / American Dad", "value": "348" }, { "label": "Ангельские ритмы! / Angel Beats!", "value": "880" }, { "label": "Анлимитед: Хёбу Кёске / Zettai Karen Children: The Unlimited - Hyoubu Kyousuke", "value": "74" }, { "label": "Апостол карточек / The Apostle of Cards", "value": "1504" }, { "label": "Арифурэта: сильнейший ремесленник в мире / Arifureta: From Commonplace to World's Strongest", "value": "62" }, { "label": "Аркан: О Паровых Заводах и Магии Обскуры / Arcanum: Of Steamworks and Magick Obscura", "value": "1495" }, { "label": "Аркейн / Arcane: League of Legends", "value": "1154" }, { "label": "Аркнайтс(Games) / Arknights", "value": "1210" }, { "label": "Армелло(Games) / Armello", "value": "1846" }, { "label": "Астра, затерянная в космосе / Kanata no Astra", "value": "1851" }, { "label": "Атака титанов / Атака на титанов / Attack on Titan", "value": "106" }, { "label": "Атлантида: Затерянный мир / Atlantis: The Lost Empire", "value": "985" }, { "label": "Бакуган Отчаянные бойцы / Bakugan Battle Brawlers", "value": "1069" }, { "label": "Банановая рыба / Banana Fish", "value": "1685" }, { "label": "Баскетбол Куроко / Kuroko no basuke", "value": "582" }, { "label": "Баффи - Истребительница вампиров / Buffy the Vampire Slayer", "value": "115" }, { "label": "Башня Бога / Tower of God", "value": "58" }, { "label": "Бездарная Нана / Munou na Nana", "value": "954" }, { "label": "Бездомный бог / Норагами / Noragami", "value": "1014" }, { "label": "Безумные Мотивы / Looney Tunes", "value": "1140" }, { "label": "Безумный азарт / Kakegurui", "value": "334" }, { "label": "Бейблэйд / Beyblade", "value": "921" }, { "label": "Бен - 10 / Ben 10", "value": "475" }, { "label": "Берсерк / Berserk", "value": "479" }, { "label": "Бесконечное лето / Everlasting Summer", "value": "966" }, { "label": "Бесконечный ужас / Terror Infinity", "value": "381" }, { "label": "Бесподобный Воинственный Бог / Peerless Martial God", "value": "419" }, { "label": "Бессмертный Деревенщина(Games) / Immortal Redneck", "value": "1524" }, { "label": "Бесстыжие / Shameless", "value": "1759" }, { "label": "Био шок(Games) / BioShock", "value": "1095" }, { "label": "Блейд / Blade", "value": "1479" }, { "label": "Блич / Bleach", "value": "7" }, { "label": "Бог войны / God Of War", "value": "352" }, { "label": "Бог из машины / Deus Ex", "value": "612" }, { "label": "Боги поступают плохо / Игры богов / Gods Behaving Badly", "value": "301" }, { "label": "Боевая академия города Астериск / Gakusen Toshi Asterisk", "value": "884" }, { "label": "Боевой континент / Combat Continent / Douluo Dalu", "value": "739" }, { "label": "Боевой молот 40-го тысячелетия / WH40K / Warhammer 40,000", "value": "341" }, { "label": "Боевой молот Фэнтезийная битва / Warhammer Fantasy Battles", "value": "1742" }, { "label": "Боевые машины(Games) / BattleTech", "value": "1667" }, { "label": "Боец Баки / Baki the Grappler", "value": "821" }, { "label": "Божественность II: Эго Дракона(Games) / Divinity II: Ego Draconis", "value": "1538" }, { "label": "Божественные Врата / Divine Gate", "value": "1490" }, { "label": "Большая автомобильная кража 5 / GTA V / Grand Theft Auto V", "value": "1139" }, { "label": "Большая автомобильная кража: Сан-Андреас / GTA: SA / Grand Theft Auto: San Andreas", "value": "820" }, { "label": "Большая разница / Far Cry", "value": "939" }, { "label": "Большой куш / Ван Пис / One Piece", "value": "25" }, { "label": "Боруто: Следующие поколения Наруто / Boruto: Naruto Next Generations", "value": "602" }, { "label": "Брак по договоренности с принцессой красных скорпионов / Arranged marriage to the princess of the Red Scorpions", "value": "1386" }, { "label": "Бэтмен за гранью: Наследие / Batman Beyond: Legacy", "value": "1380" }, { "label": "В другом мире со смартфоном / Isekai wa Smartphone to Tomo ni", "value": "947" }, { "label": "В объятиях шлюхи / JK Bitch ni Shiboraretai", "value": "1283" }, { "label": "В ожидании бедности, я собираюсь стать кузнецом / Expecting to Fall into Ruin, I Aim to Become a Blacksmith", "value": "1475" }, { "label": "В Повелителе как Довакин / In Overlord as a Dovahkiin", "value": "1816" }, { "label": "Вакфу / Wakfu", "value": "814" }, { "label": "ВАЛЛ-И / Wally", "value": "801" }, { "label": "Вампир: Маскарад - Родословные / Vampire: The Masquerade Bloodline", "value": "1212" }, { "label": "Вампирелла / Vampirella", "value": "1214" }, { "label": "Варфрейм / Warframe", "value": "967" }, { "label": "Ведьмак / The Witcher", "value": "278" }, { "label": "Великий из бродячих псов / Bungou Stray Dogs", "value": "75" }, { "label": "Великолепный парк Амаги / Amagi Brilliant Park", "value": "813" }, { "label": "Вельзепуз / Вельзевул / Beelzebub", "value": "765" }, { "label": "Веном / Venom", "value": "978" }, { "label": "Веселая ферма / Fun Farm", "value": "1124" }, { "label": "Вечная история / The Neverending Story", "value": "547" }, { "label": "Вечные(Фильм, 2021) / Eternal", "value": "1234" }, { "label": "Виви: Песнь флюоритового глаза / Vivy: Fluorite Eye's Song", "value": "1819" }, { "label": "Викинги / Vikings", "value": "369" }, { "label": "Владелец ранчо со слизью(Games) / Ранчо слизи / Slime Rancher", "value": "1529" }, { "label": "Властелин колец / Lord of the Ring", "value": "254" }, { "label": "Власть книжного червя / Honzuki no Gekokujou", "value": "1399" }, { "label": "Внук Мудрец / Kenjo no Mago", "value": "1260" }, { "label": "Внук Нурарихёна / Nurarihyon no Mago", "value": "66" }, { "label": "Во всеоружии / Overgeared", "value": "1021" }, { "label": "Во тьме(Games) / The Darkness", "value": "938" }, { "label": "Военная хроника маленькой девочки / Сага о злой Тане / The Saga of Tanya the Evil / \tGekijouban Youjo Senki", "value": "1726" }, { "label": "Возвращение в детские годы / Gaki ni Modotte Yarinaoshi!!!", "value": "1031" }, { "label": "Возрождение Серийного Убийцы / Rebirth Of A Serial Killer", "value": "1358" }, { "label": "Воинственный Бог Асура / Martial God Asura", "value": "771" }, { "label": "Война будущего / The Tomorrow War", "value": "1174" }, { "label": "Война Любовь Снег / War Love Snow", "value": "1417" }, { "label": "Волейбол! / Haikyuu!!", "value": "697" }, { "label": "Волчонок / Teen Wolf", "value": "795" }, { "label": "Волшебная Девушка Спецоперация Аска / Magical Girl Spec-Ops Asuka", "value": "1470" }, { "label": "Волшебник-воин Орфен / Majutsushi Orphen Hagure Tabi: Kimluck-hen", "value": "1128" }, { "label": "Волшебники / The Magicians", "value": "1314" }, { "label": "Волшебный учитель Нэгима! / Negima!: Magister Negi Mag", "value": "1777" }, { "label": "Воля второго цикла мироздания. / Will of the second cycle of the Worldifice.", "value": "1036" }, { "label": "Воспитание хозяина / Yours to Claim", "value": "839" }, { "label": "Восставший против неба / Against the Gods", "value": "957" }, { "label": "Восстание стражей / Хранители снов / Rise of the Guardians", "value": "1488" }, { "label": "Восхождение в Голливуде / I'm in Hollywood", "value": "1237" }, { "label": "Восхождение героя щита / The Rising of the Shield Hero", "value": "103" }, { "label": "Врата Штейна / Steins: Gate", "value": "1044" }, { "label": "Врата: там бьются наши воины / Gate: Jieitai Kanochi nite, Kaku Tatakaeri", "value": "727" }, { "label": "Время / In Time", "value": "542" }, { "label": "Всегда вялый Танака-кун / Tanaka-kun wa Itsumo Kedaruge", "value": "1082" }, { "label": "Всего лишь восьмой сын? Я с этим не смирюсь! / Hachinan tte, Sore wa Nai Deshou! / Eighth son, I don’t think so!", "value": "1473" }, { "label": "Вселенная Марвел / Marvel Universe / Marvel Comics", "value": "6" }, { "label": "Вселенная монстров / Monsterverse / Monster Verse", "value": "905" }, { "label": "Вселенная Стивена / Steven universe", "value": "573" }, { "label": "Вселенная Стрелы / Arrowverse", "value": "488" }, { "label": "Вселенная Тип Луны(Игровая компания) / Universe Type Moon", "value": "1221" }, { "label": "Вселенная DC / DC Universe / DC Comics", "value": "36" }, { "label": "Выпадение радиоактивных осадков / Fallout", "value": "55" }, { "label": "Выращивание онлайн / Cultivation Online", "value": "1252" }, { "label": "Галактическая секс-звезда / Galaxy Sex Star", "value": "1539" }, { "label": "Гало(Games) / Halo", "value": "1338" }, { "label": "Ганц / Gantz", "value": "256" }, { "label": "Гарем рабов в лабиринте другого мира / Slave Harem in the Labyrinth of the Other World", "value": "1853" }, { "label": "Гарри Поттер / Harry Potter", "value": "1" }, { "label": "Гвен-паук / Spider-Gwen", "value": "920" }, { "label": "Генерал маньяк с его сумасшедшей системой / The Maniacal General with his Crazy System", "value": "1356" }, { "label": "Генерал, вы вправе уйти. / General, You May Leave Now", "value": "1385" }, { "label": "Геншин Импакт / Genshin Impact", "value": "689" }, { "label": "Геркулес / Hercules", "value": "721" }, { "label": "Герои и замки / Heroes & Castles", "value": "940" }, { "label": "Герои меча и магии / Heroes of Might and Magic", "value": "1002" }, { "label": "Герои(телесериал) / Heroes", "value": "864" }, { "label": "Гильгамеш / Gilgamesh", "value": "1143" }, { "label": "Гинтама / Gintama", "value": "129" }, { "label": "Глубина(Фильм, 2002) / Below", "value": "1186" }, { "label": "Гнев Асуры / Asura's wrath", "value": "100" }, { "label": "Годзилла / Godzilla", "value": "922" }, { "label": "Голодные игры / The Hunger Games", "value": "859" }, { "label": "Горец / Highlander", "value": "1761" }, { "label": "Горожане(Games) / Townsmen", "value": "1599" }, { "label": "Госпожа Кагуя: в любви как на войне / Kaguya sama: Love is war", "value": "533" }, { "label": "Готика / Gothic", "value": "418" }, { "label": "Готов ли ты влюбиться в извращенку до тех пор, пока она милая? / Hentai demo Suki ni Natte Kuremasu ka", "value": "1383" }, { "label": "Гоэтия / Гоетия / Yοητεία / Ars Goetia", "value": "772" }, { "label": "Гравити Фолз / Gravity Falls", "value": "491" }, { "label": "Граница пустоты / Kara no Kyoukai", "value": "1101" }, { "label": "Гриффины / Family Guy", "value": "349" }, { "label": "Гром над небом / Thunder over the sky", "value": "793" }, { "label": "Гуррен-Лаганн / Tengen Toppa Gurren Lagann", "value": "719" }, { "label": "Да будет благословенен этот прекрасный мир! / Konosuba / Kono Subarashii Sekai ni Shukufuku wo!", "value": "82" }, { "label": "Да Здравствует Призыв! / Long Live Summons!", "value": "948" }, { "label": "Да, я паук, и что с того? / So I'm a Spider, So What? / Kumo Desu ga, Nani ka?", "value": "910" }, { "label": "Данганронпа / Danganronpa", "value": "972" }, { "label": "Две звезды Онмёджи / Sousei no Onmyouji", "value": "1108" }, { "label": "Дворянство / Благородство / Noblesse", "value": "636" }, { "label": "Девочка-волшебница Мадока Магика / Mahou Shoujo Madoka Magica", "value": "1412" }, { "label": "Девочка, которая видит это / Mieruko-chan", "value": "1645" }, { "label": "Декстер(телесериал) / Dexter", "value": "1543" }, { "label": "Демон Бездны всех царств / Abyss Demon of All Realms", "value": "1419" }, { "label": "Демоны старшей школы / High School DxD", "value": "8" }, { "label": "День независимости(Фильм, 1996) / Independence Day", "value": "850" }, { "label": "Детектив Конан / Detective Conan", "value": "1554" }, { "label": "Дети индиго из другого мира / Mondaiji-tachi ga isekai kara kuru sô desu yo", "value": "1484" }, { "label": "Джаггед Альянс 2: Агония Власти(Games) / Jagged Alliance 2", "value": "1668" }, { "label": "Джессика Джонс / Marvel's Jessica Jones", "value": "1817" }, { "label": "Джон Уик / John Wick", "value": "388" }, { "label": "Дисней / The Walt Disney Company", "value": "503" }, { "label": "Для тебя, Бессмертный / Fumetsu no Anata e / To Your Eternity", "value": "1802" }, { "label": "Дневник Будущего / Mirai Nikki", "value": "368" }, { "label": "Дневники вампира / The Vampire Diaries", "value": "160" }, { "label": "Доблесть рыцаря-неудачника / Chivalry of a Failed Knight", "value": "1462" }, { "label": "Добро пожаловать в ад, Ирума / Welcome to Demon School! Iruma-kun", "value": "261" }, { "label": "Добро пожаловать в класс превосходства / Classroom of the Elite", "value": "122" }, { "label": "Добро пожаловать! В лес похотливых эльфов! / Youkoso! Sukebe Elf no Mori e", "value": "1034" }, { "label": "Добывать ремесло / Майнкрафт / Minecraft", "value": "102" }, { "label": "Доктор Кто / Doctor Who", "value": "277" }, { "label": "Доктор Стоун / Dr. Stone", "value": "720" }, { "label": "Доля секунды: скорость / Split - second: velocity", "value": "890" }, { "label": "Дом кролика / Кофейня "Кроличий домик" / Gochuumon wa Usagi Desu ka?", "value": "642" }, { "label": "Домашний очаг / Hearthstone: Heroes of Warcraft / Hearthstone", "value": "934" }, { "label": "Домекано / Domestic Na Kanojo", "value": "632" }, { "label": "Дорогой звёзд / Звёздное преобразование / Stellar Transformation / Xing Chen Bian", "value": "1155" }, { "label": "Доспехи Бога 2: Операция Кондор / Armour of God II: Operation Condor", "value": "1829" }, { "label": "Дота 2 / Dota 2", "value": "1105" }, { "label": "Дофус / Dofus", "value": "817" }, { "label": "Дракенгард / Drakengard / Drag-On Dragoon", "value": "919" }, { "label": "Дракон-горничная госпожи Кобаяси / Kobayashi-san Chi no Maid Dragon", "value": "673" }, { "label": "Дракон-сама из семьи Касумигаока / Dragon-sama of the Kasumigaoka Family", "value": "1458" }, { "label": "Драконий жемчуг Зет / Dragon Ball Z", "value": "307" }, { "label": "Дракониум Онлайн / Draconic Online", "value": "1360" }, { "label": "Дракула / Dracula", "value": "709" }, { "label": "Древнегреческая мифология / Ancient Greek mythology", "value": "1159" }, { "label": "Дре́вние / Первородные / The Originals", "value": "863" }, { "label": "Древние свитки / The Elder Scrolls", "value": "428" }, { "label": "Древние свитки: Скайрим / TES: Skyrim", "value": "337" }, { "label": "Другой мир / Underworld", "value": "480" }, { "label": "Друид с Сеульской станции / Seoul Station Druid", "value": "1178" }, { "label": "Дьявол / Диабло / Diablo", "value": "1787" }, { "label": "Дьявол может плакать / Devil May Cry / DMC", "value": "339" }, { "label": "Дьявол Юраги-су / The Devil of Yuragi-sou", "value": "431" }, { "label": "Дьявол II(Games) / Диабло II / Diablo II", "value": "1055" }, { "label": "Дэдпул / Deadpool", "value": "810" }, { "label": "Дэнни-призрак / Danny Phantom", "value": "109" }, { "label": "Евангелион / Neon Genesis Evangelion", "value": "583" }, { "label": "Единство семи магов / Тринити: Семь Магов / Trinity Seven", "value": "442" }, { "label": "Еженедельный прыжок сёнэн / Weekly Shōnen Jump", "value": "1629" }, { "label": "Ёрмунганд / Jormungand", "value": "77" }, { "label": "Жажда скорости / Need For Speed", "value": "1493" }, { "label": "Железный человек / Iron Man", "value": "710" }, { "label": "Жемчуг дракона / Dragon Ball", "value": "309" }, { "label": "Женщина-Халк(телесериал) / She-Hulk: Attorney at Law", "value": "1593" }, { "label": "Жизнь девушки в игровом мире / A Girl’s Life In A Gaming World", "value": "1406" }, { "label": "Жизнь после / Days Gone", "value": "1279" }, { "label": "За гранью / Beyond the Boundary", "value": "357" }, { "label": "Загипнотизировать Семью / Kyonyuu Kazoku Saimin", "value": "1032" }, { "label": "Закон Уэки / The Law of Ueki", "value": "790" }, { "label": "Закулисье / Backrooms", "value": "1827" }, { "label": "Зачарованные / Charmed", "value": "113" }, { "label": "Защитники / Defenders", "value": "1832" }, { "label": "Защитница Химари / Omamori Himari", "value": "279" }, { "label": "Звёздная принцесса и силы зла\t / Стар против сил зла / Star vs. The Forces of Evil", "value": "782" }, { "label": "Звёздное дитя / Oshi no Ko", "value": "1903" }, { "label": "Звёздное ремесло / StarCraft", "value": "386" }, { "label": "Звездные Войны / Star Wars", "value": "40" }, { "label": "Звёздные войны: Войны клонов - Все типы носителей(мультсериал, 2008) / Star Wars: The Clone Wars", "value": "1182" }, { "label": "Звёздные врата / Stargate", "value": "770" }, { "label": "Звёздные врата: Атлантида / Stargate: Atlantis", "value": "1097" }, { "label": "Звездный путь / Стартрек / Star Trek", "value": "849" }, { "label": "Зверополис / Zootopia", "value": "1449" }, { "label": "Зеленая Жизнь / Green Life", "value": "1196" }, { "label": "Зеленый фонарь / The Green Lantern", "value": "1222" }, { "label": "Зетмен / Zetman", "value": "1191" }, { "label": "Игра в кальмара(телесериал) / Squid game", "value": "1065" }, { "label": "Игра престолов / Game of Thrones", "value": "22" }, { "label": "Игрок / The Gamer", "value": "126" }, { "label": "Идеальная судьба / The Perfect Destiny", "value": "781" }, { "label": "Идолмастер / The Idolmaster", "value": "807" }, { "label": "Иерихон Клайва Баркера / Иерихон / Clive Barker’s Jericho /Jericho", "value": "320" }, { "label": "Извивающийся дракон / Coiling Dragon", "value": "692" }, { "label": "Изгнаные королевства РПГ / Exiled Kingdoms RPG", "value": "1375" }, { "label": "Импульс Валькирии: Сирена / Варукири Дораиву: Сирена / Valkyrie Drive: Mermaid", "value": "1736" }, { "label": "Индекс волшебства / A Certain Magical Index", "value": "68" }, { "label": "Инуяша - Пес-демон / InuYasha", "value": "481" }, { "label": "Искусственный отбор / Triage X", "value": "1037" }, { "label": "Истинный мир боевых искусств / Zhenwu Shijie / True Martial World", "value": "867" }, { "label": "История монстров / Monogatari", "value": "911" }, { "label": "История о второстепенном персонаже который стал игроком в другой игре. / The story is about a minor character who became a player in another game.", "value": "868" }, { "label": "Кабанери железной крепости / Koutetsujou no Kabaneri", "value": "1494" }, { "label": "Каждый раз, когда я сплю, моя душа покидает мое тело / Every Day I Sleep, My Soul Goes Out of My Body", "value": "1048" }, { "label": "Как воспитать героиню из обычной девушки / Saenai Heroine no Sodatekata", "value": "1637" }, { "label": "Как игрок глупой FPS попал в иной мир / Как дурачок из стрелялки в другой мир попал / Manuke na FPS Player ga Isekai e Ochita Baai", "value": "746" }, { "label": "Как приручить дракона / How to Train Your Dragon", "value": "687" }, { "label": "Капитан Америка / Captain America", "value": "1425" }, { "label": "Капитан Марвел(Фильм, 2019) / Captain Marvel", "value": "1594" }, { "label": "Каратель / The Punisher", "value": "387" }, { "label": "Касл / Castle", "value": "389" }, { "label": "Касльвания / Castlevania", "value": "1215" }, { "label": "Катаклизм: Тёмные дни впереди / DDA / Cataclysm: Dark Days Ahead", "value": "680" }, { "label": "Квайзер со Стигматом / Адепт Святого Знака / The Qwaser of Stigmata", "value": "72" }, { "label": "Квартет из альтернативного мира / Isekai Quartet", "value": "1801" }, { "label": "Квест Девушки-монстра / Monster Girl Questt", "value": "928" }, { "label": "Квест титана(Games) / Титанический квест / Titan Quest", "value": "1483" }, { "label": "Кенши(Games) / Kenshi", "value": "1230" }, { "label": "Киберпанк 2077 / Cyberpunk 2077", "value": "416" }, { "label": "Ким Пять-с-плюсом / Kim Possible", "value": "436" }, { "label": "Киру ра Киру / Круши Кромсай / Убей или умри / Kill la Kill", "value": "763" }, { "label": "Класс убийц / Assassination classroom", "value": "610" }, { "label": "Клеймор / Claymore", "value": "110" }, { "label": "Клинок зла / Evil Blade / Übel Blatt", "value": "722" }, { "label": "Клинок королевы / Queen’s Blade", "value": "757" }, { "label": "Клинок Маню: Тайна сисечного свитка / Manyuu Hiken-chou", "value": "501" }, { "label": "Клинок рассекающий демонов / Demon Slayer: Kimetsu no Yaiba", "value": "21" }, { "label": "Клуб Винкс / Winx Club", "value": "397" }, { "label": "Книга джунглей / The Jungle Book", "value": "1688" }, { "label": "Князь тьмы с задней парты / Demon King Daimao / Ichiban Ushiro no Daimaou", "value": "1207" }, { "label": "Код Гиас / Code Geass", "value": "340" }, { "label": "Код Квалидеи / Qualidea Code", "value": "76" }, { "label": "Кольцо Элдена / Elden Ring", "value": "1408" }, { "label": "Комната / The Room", "value": "889" }, { "label": "Конь и клинок: Боевой отряд(Games) / Mount and Blade:Warband", "value": "1477" }, { "label": "Королевства Сердец / Kingdom Hearts", "value": "407" }, { "label": "Короли крестоносцев / Crusader kings", "value": "572" }, { "label": "Король бойцов / The King of Fighters", "value": "1378" }, { "label": "Король лев / The Lion king", "value": "1705" }, { "label": "Король Шаманов / Shaman King", "value": "744" }, { "label": "Корона греха / Guilty Crown", "value": "1007" }, { "label": "Корпорация лоботомии / Lobotomy corporation", "value": "852" }, { "label": "Космические рейнджеры(Games) / Space Rangers", "value": "1508" }, { "label": "Кошечка из Сакурасо / Sakurasou no Pet na Kanojo", "value": "605" }, { "label": "Красавица и чудовище / Beauty and the Beast", "value": "1765" }, { "label": "Красная угроза 3 / Command & Conquer: Red Alert 3", "value": "742" }, { "label": "Красный, Белый, Черный, Желтый / RWBY", "value": "131" }, { "label": "Кредо убийцы / Assassin's Creed", "value": "690" }, { "label": "Кризис / Crysis", "value": "1734" }, { "label": "Крушитель / The Breaker", "value": "1080" }, { "label": "Кунг-фу панда / Kung Fu Panda", "value": "831" }, { "label": "Кэйон! / K-On!", "value": "1785" }, { "label": "Кэнган Асура / Kengan Asura", "value": "726" }, { "label": "Лаборатория Декстера / Dexter Lab", "value": "639" }, { "label": "Лавкрафт / Говард Филлипс Лавкрафт / Howard Phillips Lovecraft", "value": "1259" }, { "label": "Легенда о восьми псах востока / Hakkenden: Touhou Hakken Ibun", "value": "1699" }, { "label": "Легенда о Зельде / The Legend of Zelda", "value": "870" }, { "label": "Легенда о Короле Драконов / Legend of the Dragon King", "value": "623" }, { "label": "Легенда о Легендарных Героях / Densetsu no Yuusha no Densetsu", "value": "193" }, { "label": "Легион Супергероев / The Legion of Super-Heroes", "value": "450" }, { "label": "Леди Баг и Супер-Кот / Miraculous Ladybug", "value": "327" }, { "label": "Летняя сага / Summertime Saga", "value": "1441" }, { "label": "Лига Легенд / League of Legends", "value": "65" }, { "label": "Линия фронта для девочек / Girls' Frontline", "value": "1686" }, { "label": "Литературный клуб Доки Доки / Литературный клуб / Doki Doki literature club!", "value": "819" }, { "label": "Лорд героев(Games) / Lord of Heroes", "value": "1771" }, { "label": "Лорд человечества / Lord of the People", "value": "1896" }, { "label": "Лориенская Сага / Lorien Legacies", "value": "521" }, { "label": "Любимая жена господина генерального директора / Mr.CEO's Beloved Wife", "value": "1389" }, { "label": "Любовные неприятности / To love ru", "value": "353" }, { "label": "Любовь, Деньги, Рок-н-Ролл / Love, Money, Rock'n'Roll", "value": "1890" }, { "label": "Люди в чёрном(Фильм) / Men in Black", "value": "1193" }, { "label": "Люди Икс / X-Men", "value": "371" }, { "label": "Лютер Строуд Сага / The Luther Strode Saga", "value": "1700" }, { "label": "Люцифер(телесериал) / Lucifer", "value": "681" }, { "label": "Маг на полную ставку / Quanzhi Fashi", "value": "291" }, { "label": "Маг смерти не желающий четвертой реинкарнации / The Death Mage Who Doesn’t Want a Fourth Time", "value": "1775" }, { "label": "Маг-целитель: Новый старт / Kaifuku Jutsushi no Yarinaoshi", "value": "1311" }, { "label": "Маги: Волшебный лабиринт / Magi: The Labyrinth of Magic", "value": "1581" }, { "label": "Магистр дьявольского культа / The Grandmaster of Demonic Cultivation", "value": "608" }, { "label": "Магическая академия Атараксия: Гибрид х Сердце / Hybrid x Heart Magias Academy Ataraxia", "value": "1898" }, { "label": "Магическая битва / Magic Battle / Jujutsu Kaisen", "value": "671" }, { "label": "Маленькие кошмары 2 / Little Nightmares 2", "value": "601" }, { "label": "Малефисента / Maleficent", "value": "775" }, { "label": "Мальчик с оленьими рогами / Сладкоежка / Sweet tooth", "value": "1772" }, { "label": "Маска / The mask", "value": "847" }, { "label": "Мастер Урадана / The Master of Uradan", "value": "1395" }, { "label": "Мастера меча онлайн / Sword Art Online / SAO", "value": "324" }, { "label": "Межвидовые Рецензенты / Interspecies Reviewers", "value": "1555" }, { "label": "Менеджер среднего звена Тонэгава / Chuukan Kanriroku Tonegawa", "value": "1084" }, { "label": "Мерлин / Merlin", "value": "486" }, { "label": "Мертвы к Рассвету / Dead by Daylight", "value": "899" }, { "label": "Мертвый или живой / Dead or Alive", "value": "1563" }, { "label": "Мертвый остров / Dead Island", "value": "124" }, { "label": "Месть Масамуне-куна! / Masamune-kun no Revenge", "value": "571" }, { "label": "Метавселенная Рудазова / Rudazov's Metauniverse", "value": "1211" }, { "label": "Метро 2033(Games) / Metro 2033", "value": "1584" }, { "label": "Милый во Франксе / Любимый во Франксе / Darling in the Franxx", "value": "942" }, { "label": "Мир боевых искусств / 武极天下 / Wuji Tianxia / Martial World", "value": "620" }, { "label": "Мир зомби / Zombie World", "value": "1880" }, { "label": "Мир Льда и Пламени / The World of Ice & Fire", "value": "415" }, { "label": "Мир приключений Джеки Чана(мультсериал, 2000) / ackie Chan Adventures", "value": "1544" }, { "label": "Мир танков / WoT Blitz / World of Tanks Blitz", "value": "525" }, { "label": "Мир Тьмы / World of Darkness", "value": "145" }, { "label": "Мир Эрастай / The World of Erasthay", "value": "1836" }, { "label": "Мир Warcraft / World of Warcraft", "value": "89" }, { "label": "Мировая война Z / Война миров Z / World War Z", "value": "1217" }, { "label": "Моана / Moana", "value": "686" }, { "label": "Моб психо 100 / Mob Psycho 100", "value": "866" }, { "label": "Мобильные легенды: Бах-Бах(Games) / Mobile Legends: Bang Bang", "value": "1497" }, { "label": "Могучие рейнджеры / Power Rangers", "value": "1486" }, { "label": "Может, я встречу тебя в подземелье? / DanMachi", "value": "9" }, { "label": "Мой жених сбежал / My Groom Ran Away", "value": "1047" }, { "label": "Мой маленький пони / My Little Pony", "value": "655" }, { "label": "Мой маленький пони: Дружба — это чудо / My Little Pony: Friendship is Magic", "value": "658" }, { "label": "Мой шумный дом(мультсериал, 2016) / The Loud House", "value": "1467" }, { "label": "Монстер Хай / Monster High", "value": "1012" }, { "label": "Моя возлюбленная чпокается со всеми / Kanojo wa Dare to demo Sex Sur", "value": "1274" }, { "label": "Моя геройская академия / Boku no Hero Academia", "value": "69" }, { "label": "Моя девушка - зомби / My Girlfriend is a Zombie", "value": "754" }, { "label": "Моя жена - красивый генеральный директор / My Wife is a Beautiful CEO", "value": "1025" }, { "label": "Моя жена — президент студенческого совета! / My Wife is the Student Council President / Okusama ga Seitokaichou", "value": "241" }, { "label": "Моя Марвел Академия / My marvel academia", "value": "696" }, { "label": "Моя первая модница / Hajimete no Gal", "value": "1835" }, { "label": "Моя Супер-Бывшая / My Super Ex-Girlfriend", "value": "1828" }, { "label": "Мрачный рассвет / Grim Dawn", "value": "1113" }, { "label": "Мстители / The Avengers", "value": "1747" }, { "label": "Мстители. Эра Альтрона / The Avengers. Age of Ultron", "value": "784" }, { "label": "Мулан / Mulan", "value": "706" }, { "label": "Мы не можем учится / Bokutachi wa Benkyou ga Dekinai", "value": "912" }, { "label": "Мэй Гунцин / Mei Gongqing", "value": "753" }, { "label": "Наблюдать / Overwatch", "value": "607" }, { "label": "Надпись / Inscription", "value": "1718" }, { "label": "Нам Ён / Nam Yeon", "value": "1188" }, { "label": "Наруто / Naruto", "value": "3" }, { "label": "Начало после конца / The Beginning After The End", "value": "888" }, { "label": "Не голодай / Don't Starve", "value": "274" }, { "label": "Не издевайся надо мной, Нагаторо / Ijiranaide / Nagatoro-san Don't Toy with Me, Miss Nagatoro", "value": "1041" }, { "label": "Не люблю боль, так что вкачаю все в защиту / Itai no wa Iya nano de Bougyoryoku ni Kyokufuri Shitai to Omoimasu", "value": "517" }, { "label": "Не моя вина, что я непопулярна! / Watashi ga Motenai no wa Dou Kangaetemo Omaera ga Warui", "value": "1381" }, { "label": "Небесный замок Лапута / Tenkuu no Shiro Laputa", "value": "1109" }, { "label": "Невероятные приключения ДжоДжо / JoJo's Bizarre Adventure", "value": "20" }, { "label": "Негодник, которому не снилась девочка-зайка / Rascal Does Not Dream of Bunny Girl Senpai", "value": "1897" }, { "label": "Негодяй спасает мужскую роль / The Villain Saves the Male Lead", "value": "1224" }, { "label": "Неизвестен / Persona", "value": "205" }, { "label": "Некий магический индекс / To Aru Majutsu no Index", "value": "562" }, { "label": "Некий научный акселератор / Toaru Kagaku no Accelerator", "value": "1487" }, { "label": "Ненасытный Берсерк / Boushoku no Berserk: Ore dake Level to Iu Gainen wo Toppa suru the Comic", "value": "1195" }, { "label": "Необъятные небеса / Infinite Stratos / IS", "value": "280" }, { "label": "Необъятный океан / Grand Blue", "value": "531" }, { "label": "Непревзойденная / Master Piece The Animation", "value": "712" }, { "label": "Непризнанный школой владыка демонов / Maou Gakuin no Futekigousha", "value": "1476" }, { "label": "Непутевый ученик в школе магии / Mahouka Koukou No Rettousei", "value": "982" }, { "label": "Непутевый ученик в школе магии / The Irregular at Magic High School", "value": "630" }, { "label": "Несокрушимая механическая кукла / Machine-Doll wa Kizutsukanai", "value": "1030" }, { "label": "Несправедливость / Injustice", "value": "1026" }, { "label": "Нет игры - нет жизни / Без игры жизни нет / No Game No Life", "value": "718" }, { "label": "Неуязвимый / Invincible", "value": "702" }, { "label": "НиоХ(Games) / NioH", "value": "1465" }, { "label": "Новый завет Владыки тьмы / Shinmai Maou no Testament", "value": "1432" }, { "label": "Ну и ну! Земляничные яйца / I My Me! Strawberry Eggs", "value": "1485" }, { "label": "Нулевой Уровень Целомудрия / Teisou Kannen Zero", "value": "1209" }, { "label": "О моём перерождении в меч / Tensei Shitara Ken deshita", "value": "53" }, { "label": "О моём перерождении в слизь / Tensei shitara Slime Datta Ken", "value": "64" }, { "label": "О моя Богиня / Aa! Megami-sama! / Ah! My Goddess", "value": "915" }, { "label": "Обесчещенный(Games) / Dishonored", "value": "1073" }, { "label": "Обитель зла / Resident Evil", "value": "86" }, { "label": "Огненная эмблема / Fire Emblem", "value": "1615" }, { "label": "Огненная эмблема: Пробуждение / Fire Emblem: Awakening", "value": "1616" }, { "label": "Огненная эмблема: Три Дома / Fire Emblem:Three Houses", "value": "1716" }, { "label": "Одинокий рокер! / Bocchi the Rock!", "value": "1904" }, { "label": "Одному лишь Богу ведомый мир / World God Only Knows", "value": "1248" }, { "label": "Она становится гламурной после расторжения помолвки / She gets glamorous after the engagement is annulled", "value": "1404" }, { "label": "Орк-рубака / Orc Grunt", "value": "779" }, { "label": "Освободите эту ведьму / Release that witch", "value": "994" }, { "label": "Острые козырьки(телесериал) / Peaky Blinders", "value": "1177" }, { "label": "От заката до рассвета! / From Dusk till Dawn!", "value": "1416" }, { "label": "Отброс из семьи графа / Trash of counts family", "value": "853" }, { "label": "Отряд самоубийц / The Suicide Squad", "value": "1844" }, { "label": "Отчаянные домохозяйки / Desperate Housewives", "value": "1011" }, { "label": "Отчет о буйстве духов / YuYu Hakusho", "value": "1008" }, { "label": "Охота демонического короля на свою жену / Xie Wang Zhui Qi", "value": "1737" }, { "label": "Охотник х Охотник / Hunter x Hunter", "value": "101" }, { "label": "Охотницы на демонов / Taimanin Asagi", "value": "1463" }, { "label": "Очень приятно Бог! / Kamisama Hajimemashita", "value": "1585" }, { "label": "Очень Странные Дела(телесериал) / Stranger Things", "value": "1834" }, { "label": "ПАЗЛ / PUZZLE", "value": "1762" }, { "label": "Палач Рока / DOOM", "value": "132" }, { "label": "Параграф 78(Фильм) / Paragraph 78", "value": "923" }, { "label": "Паразит: Учение о жизни / Parasyte: The Maxim", "value": "1176" }, { "label": "Пастырь(Фильм, 2011) / Priest", "value": "1173" }, { "label": "Пацаны / The Boys", "value": "133" }, { "label": "Первый детский сад во вселенной / The First Kindergarten in the Universe", "value": "1049" }, { "label": "Перевозчик / Le Transporteur", "value": "365" }, { "label": "Передающийся через кровь / Bloodborne", "value": "229" }, { "label": "Пережить / Outlast", "value": "645" }, { "label": "Перерождение / Rebirth", "value": "550" }, { "label": "Перерождение бессмертного горожанина-культиватора / Rebirth – City Cultivation / Rebirth of the Urban Immortal Cultivator", "value": "843" }, { "label": "Перерождение в монстра / Re:Monster", "value": "85" }, { "label": "Перестрой мир / Sekai O Sai Kochiku / Rebuild World", "value": "961" }, { "label": "Период полураспада(Valve) / Half-Life", "value": "895" }, { "label": "Перси Джексон / Percy Jackson", "value": "308" }, { "label": "Персона 5 / Persona 5", "value": "1614" }, { "label": "Печать ветра / Kaze no Stigma", "value": "845" }, { "label": "Пик боевых искусств / Martial Peak", "value": "414" }, { "label": "Пираты Карибского моря / Pirates of the Caribbean", "value": "932" }, { "label": "Пираты черной лагуны / Black Lagoon", "value": "621" }, { "label": "Пламенная бригада пожарных / Fire Force / Enen no Shouboutai", "value": "841" }, { "label": "Пламя бесчисленых невзгод / I' m really not demon god's lackey", "value": "1452" }, { "label": "Планетарная аннигиляция / Planetary Annihilation", "value": "487" }, { "label": "Плоскостной пейзаж: Мучение / Planescape: Torment", "value": "1768" }, { "label": "По велению адской сестры / The Testament of Sister New Devil", "value": "18" }, { "label": "Поборники тьмы / Darksiders", "value": "1028" }, { "label": "Повар небесной гостиницы / Чем кормят в ином мире / Kakuriyo no Yadomeshi", "value": "998" }, { "label": "Повар-боец Сома / В поисках божественного рецепта / Shokugeki no Souma", "value": "191" }, { "label": "Повелитель тьмы на подработке! / Hataraku Maou-sama!", "value": "674" }, { "label": "Повелитель тьмы: Другая история мира / How Not to Summon a Demon Lord / Isekai Maou to Shoukan Shoujo no Dorei Majutsu", "value": "699" }, { "label": "Повелитель(Куганэ Маруяма) / Overlord", "value": "27" }, { "label": "Повелитель(Games) / Overlord", "value": "1623" }, { "label": "Повесть о Конце Света / Record of Ragnarok", "value": "332" }, { "label": "Повесть о лунной принцессе / Tsukihime: Lunar Legend", "value": "750" }, { "label": "Повесть о Небесных островах / Фэнтези Гранблю / Granblue Fantasy", "value": "808" }, { "label": "Повседневная жизнь бессмертного короля / The Daily Life of the Immortal King / Xian Wang de Richang Shenghuo", "value": "1466" }, { "label": "Повседневная жизнь с девушкой-монстром / Monster Musume", "value": "760" }, { "label": "Пограничье(Games) / Borderlands", "value": "992" }, { "label": "Под лунами Драконьих глаз / Beneath the Dragoneye Moons", "value": "1735" }, { "label": "Подземелья и драконы / Dungeons & Dragons", "value": "81" }, { "label": "Подземная история / Андертейл / Undertale", "value": "390" }, { "label": "Поднявшийся(Games) / Risen", "value": "1273" }, { "label": "Поднятие уровня в одиночку / Solo Leveling", "value": "127" }, { "label": "Подручный Луизы-Нулизы / Zero no Tsukaima", "value": "580" }, { "label": "Пожиратель богов / God Eater", "value": "1321" }, { "label": "Поймай себя ! Моя дорогая жена / Catch You ! My Dear Wife", "value": "1317" }, { "label": "Покемон / Pokemon", "value": "43" }, { "label": "Политическая Хроника Молодой Девушки / A Young Woman's Political Record", "value": "1306" }, { "label": "Полностью пленённые / Totally Captivated", "value": "1086" }, { "label": "Полый Рыцарь(Games) / Hollow Knight", "value": "1198" }, { "label": "Пользователи Силы / Forceusers", "value": "1162" }, { "label": "Поля битвы Неизвестного игрока / ПАБГ / Player Unknown's Battlegrounds / PUBG", "value": "622" }, { "label": "Попытка приручить злого повелителя / Trying to Tame an Evil Overlord", "value": "983" }, { "label": "Поработитель Ада / Helltaker", "value": "776" }, { "label": "Порновселенная / Porn Universe", "value": "1776" }, { "label": "Портал(Valve) / Portal", "value": "800" }, { "label": "Последние из нас / Last Of Us", "value": "1717" }, { "label": "Последний Серафим / Owari no Seraph", "value": "551" }, { "label": "Последняя из рода Блау(Тайга Ри) / The last of the Blau family", "value": "1507" }, { "label": "Последняя фантазия / ファイナルファンタジ / Final Fantasy", "value": "769" }, { "label": "Преподобное безумие / Reverend Insanity", "value": "1280" }, { "label": "Преподобный Гу / Gu Zhen Ren / Daoist Gu", "value": "1464" }, { "label": "Призрачный бегун / Ghostrunner", "value": "613" }, { "label": "Призрачный гонщик / Ghost Rider", "value": "823" }, { "label": "Принц Драконов Хаоса / The Chaos Dragon Prince", "value": "1397" }, { "label": "Принц Персии / Prince of Persia", "value": "1535" }, { "label": "Принцесса монстров / Princess Resurrection", "value": "1304" }, { "label": "Принцесса Цу / Не проиграю! / Maken Ki", "value": "675" }, { "label": "Проект „Восток“ / Touhou Project", "value": "809" }, { "label": "Проект Кей / K Project", "value": "73" }, { "label": "Проклятие: Автоматизация / NieR:Automata", "value": "1496" }, { "label": "Противостояние святого / Renegade Immortal", "value": "926" }, { "label": "Прототип / Prototype", "value": "54" }, { "label": "Пуленепробиваемый / Bang-Tan / BTS", "value": "520" }, { "label": "Путешествие на Запад / Journey to the West", "value": "1833" }, { "label": "Пять невест / Go-Toubun no Hanayome", "value": "713" }, { "label": "Пять ночей у Фредди / Five nights at freddy's", "value": "930" }, { "label": "Рагнарёк Онлайн / Ragnarok Online", "value": "953" }, { "label": "Радуга 6: Осада / Rainbow Six: Siege", "value": "421" }, { "label": "Развращение Дочери / Daraku Reijou Hakoiri Ojou-sama Netorare Choukyou Kiroku", "value": "1284" }, { "label": "Рай Грисайи / Эдем в серых тонах / Grisaia no Rakuen", "value": "584" }, { "label": "Рандеву с жизнью / Date A live", "value": "851" }, { "label": "Ранма ½ / Ranma ½", "value": "1192" }, { "label": "Рапунцель: Запутанная история / Tangled", "value": "773" }, { "label": "Расколотая битвой синева небес / Battle Through the Heavens", "value": "927" }, { "label": "Рассказ служанки / The Handmaid's Tale", "value": "1135" }, { "label": "Расхитительница гробниц / Tomb Raider", "value": "988" }, { "label": "Резатель / Лангриссер / Langrisser", "value": "792" }, { "label": "Реинкарнация безработного / Mushoku Tensei", "value": "569" }, { "label": "Реинкарнация Богини / Megami Tensei", "value": "1161" }, { "label": "Репликант НиеР / NieR Replicant / NieR Gestalt", "value": "1299" }, { "label": "Рецеттия: Повесть о магазине предметов / Recettear: An Item Shop's Tale", "value": "858" }, { "label": "Ривердэйл / Riverdale", "value": "637" }, { "label": "Рик и Морти / Rick and Morty", "value": "315" }, { "label": "Розарий и Вампир / Rosario+Vampire", "value": "83" }, { "label": "Розовая пора моей школьной жизни сплошной обман / Yahari Ore no Seishun Love Come wa Machigatteiru", "value": "856" }, { "label": "Рок шоу! / Show By Rock!!", "value": "344" }, { "label": "Русалочка / The Little Mermaid", "value": "892" }, { "label": "Рыцарь и маг / Knight's & Magic", "value": "1491" }, { "label": "Сага о Винланде / Vinland Saga", "value": "1200" }, { "label": "Садистская смесь / Blend S", "value": "1120" }, { "label": "Сайт волшебниц / Mahou Shoujo Site", "value": "909" }, { "label": "Сверхъестественное(телесериал) / Supernatural", "value": "916" }, { "label": "Связь принцесс: повторное погружение / Princess Connect! Re:Dive", "value": "1481" }, { "label": "Святые / Saints Row", "value": "1390" }, { "label": "Сейлор Мун / Sailor Moon", "value": "114" }, { "label": "Секире: Тени Умирают Дважды / Sekiro: Shadows Die Twice", "value": "1076" }, { "label": "Семь смертных грехов / Nanatsu no Taizai", "value": "61" }, { "label": "Семья шпиона / Spy x Family", "value": "1646" }, { "label": "Сердца Пандоры / Pandora Hearts", "value": "497" }, { "label": "Серия Метроидов / Metroid Series", "value": "1612" }, { "label": "Серый человек / Ди: Гурэйман / D.Gray-man", "value": "367" }, { "label": "Си Тянь Гуань / Si Tian Guan", "value": "1189" }, { "label": "Сильнейший в истории ученик Кэнити / Shijou Saikyou no Deshi Kenichi", "value": "242" }, { "label": "Сильнейший в истории ученик Кэнъити / KenIchi: The Mightiest Disciple", "value": "745" }, { "label": "Сильнейший магнат / The Strongest Tycoon", "value": "1340" }, { "label": "Сильнейший мудрец низшей эмблемы / Shikkakumon no Saikyou Kenja", "value": "1472" }, { "label": "Симпсоны / The Simpsons", "value": "1461" }, { "label": "Симс / The Sims", "value": "654" }, { "label": "Симфония морской стали / Aoki Hagane no Arpeggio", "value": "958" }, { "label": "Сингулярность(Games) / Singularity", "value": "1793" }, { "label": "Синий Архив / Blue Archive", "value": "1411" }, { "label": "Синий экзорцист / Blue Exorcist", "value": "312" }, { "label": "Синяя Тюрьма: Блю Лок / Blue Lock", "value": "1792" }, { "label": "Система Богов и Демонов / God and Devil World", "value": "1648" }, { "label": "Система Спаси-Себя-Сам / The Scum Villain's Self-Saving System: Ren Zha Fanpai Zijiu Xitong", "value": "1505" }, { "label": "Система: Восьмой уровень(Д. Серебряков) / System: Eighth level", "value": "1175" }, { "label": "Сисястая Принцесса под гипнозом / Kyonyuu Princess Saimin", "value": "1618" }, { "label": "Сказание о Демонах и Богах / Tales of Demons and Gods", "value": "59" }, { "label": "Сказание о Тёмном Рыцаре ~ Призван, чтобы одолеть Героя ~ / Tale of Dark Knight~Summoned to Defeat The Hero~", "value": "1647" }, { "label": "Сказки хранителей(Games) / Guardian tales", "value": "1068" }, { "label": "Скрытая Похотливая Натура Моих Русских Сестренок и Мачехи / Muttsuri do Sukebe ro Gibo Shimai", "value": "1282" }, { "label": "Скуби-Ду / Scooby-Doo", "value": "638" }, { "label": "Скучный мир, где не существует самой идеи похабных шуток / Shimoneta to Iu Gainen ga Sonzai Shinai Taikutsu na Sekai", "value": "830" }, { "label": "Сладкая жизнь / Happy Sugar Life", "value": "1099" }, { "label": "Сладкий флирт / Amour Sucré / Sweet Crush", "value": "495" }, { "label": "Сладости и Сигареты / Candy & Cigarettes", "value": "778" }, { "label": "Следопыт Гнев Праведников / Pathfinder Wrath Of The Righteous", "value": "1077" }, { "label": "Следопыт: Творец королей / Pathfinder: Kingmaker", "value": "1770" }, { "label": "Смертельная битва / Мортал Комбат / Mortal Kombat", "value": "806" }, { "label": "Смертельный укус", "value": "1902" }, { "label": "Созданный в бездне / Made in Abyss", "value": "952" }, { "label": "Сок джунглей", "value": "1901" }, { "label": "Сокрушитель: Новые волны / The Breaker: New Waves", "value": "1500" }, { "label": "Соник еж / Sonic the hedgehog", "value": "1052" }, { "label": "Сорвиголова / Daredevil", "value": "1690" }, { "label": "Сотня / Hundred", "value": "885" }, { "label": "Спаун / Spawn", "value": "1254" }, { "label": "Спецагент Арчер / Archer", "value": "624" }, { "label": "Специалист по апгрейду из другого мира / Endless Sea of Clouds ESC", "value": "1499" }, { "label": "Спираль / Удзумаки / Uzumaki", "value": "1164" }, { "label": "СТАЛКЕР / STALKER / S.T.A.L.K.E.R", "value": "677" }, { "label": "Стальная тревога / Full Metal Panic! The Second Raid", "value": "1489" }, { "label": "Стальной алхимик / Fullmetal Alchemist", "value": "1123" }, { "label": "Стальной Гигант / The Iron Giant", "value": "1241" }, { "label": "Становление богом / Bai Lian Cheng Shen", "value": "1315" }, { "label": "Старгерл / Stargirl", "value": "1137" }, { "label": "Стелларис / Stellaris", "value": "1098" }, { "label": "Сторожевые Псы / Watch Dogs", "value": "1886" }, { "label": "Стражи Галактики / Guardians of the Galaxy", "value": "1426" }, { "label": "Страна Самоцветов / Houseki no Kuni", "value": "1305" }, { "label": "Страна чудес смертников / Зона-парк смертников / Deadman Wonderland", "value": "857" }, { "label": "Страношары / Кантриболз / Countryballs", "value": "1895" }, { "label": "Студии 20-й век / 20th Century Studios", "value": "1715" }, { "label": "Судьба / Fate", "value": "1740" }, { "label": "Судьба: Апокриф / Fate: Apocrypha", "value": "231" }, { "label": "Судьба: Великий Орден / Fate: Grand Order", "value": "60" }, { "label": "Судьба: Девочка волшебница Илия / Fate: Kaleid Liner Prisma", "value": "789" }, { "label": "Судьба: Истоки / Fate: Zero", "value": "230" }, { "label": "Судьба: Ночь схватки / Fate: Stay Night", "value": "536" }, { "label": "Сумерки / Twilight", "value": "471" }, { "label": "Супер ген бога / Super God Gene", "value": "316" }, { "label": "Супер Марио / Super Mario", "value": "1661" }, { "label": "Супергёрл(телесериал, 2015) / Supergirl", "value": "1088" }, { "label": "Супермедицинский ниндзя / Super medical ninja", "value": "1391" }, { "label": "Суперсемейка / The Incredibles", "value": "306" }, { "label": "Сэкирэй / Sekirei", "value": "111" }, { "label": "Тада не может влюбиться! / Tada-kun wa koi wo shinai!", "value": "1905" }, { "label": "Тайны Смолвиля / Smallville", "value": "449" }, { "label": "Танец клинка Элементалиста / Seireitsukai no Blade Dance", "value": "1498" }, { "label": "Твоя апрельская ложь / Your lie in april", "value": "532" }, { "label": "Те, кто охотятся на эльфов / エルフを狩るモノたち / Those Who Hunt Elves", "value": "1168" }, { "label": "Темнейшее подземелье / Darkest dungeon", "value": "1405" }, { "label": "Темные Души / Dark Souls", "value": "200" }, { "label": "Темный Ангел / Dark Angel", "value": "1010" }, { "label": "Тёмный Дворецкий / Kuroshitsuj / Dark Butler", "value": "411" }, { "label": "Темный дворецкий / Kuroshitsuji", "value": "1043" }, { "label": "Темный призыватель Апокалипсиса / The Dark Summoner of the Apocalypse", "value": "1407" }, { "label": "Тень ежа / Ёж Шэдоу / Shadow the hedgehog", "value": "796" }, { "label": "Терминатор / The Terminator", "value": "759" }, { "label": "Террарий / Terraria", "value": "805" }, { "label": "Тетрадь смерти / Death Note", "value": "78" }, { "label": "Тибериумные войны / Tiberium Wars", "value": "1893" }, { "label": "Титаник / Titanic", "value": "1842" }, { "label": "Тихий Холм / Сайлент Хилл / Silent Hill", "value": "848" }, { "label": "Тихоокеанский рубеж / Pacific Rim", "value": "832" }, { "label": "Тогайну но Чи ~Потерял кровь~(Games) / Togainu no Chi ~Lost Blood~", "value": "1540" }, { "label": "Токийские вороны / Tokyo Ravens", "value": "836" }, { "label": "Токийские мстители / Tokyo Revengers", "value": "1064" }, { "label": "Токийский Гуль / Tokyo Ghoul", "value": "271" }, { "label": "Тор / Thor", "value": "764" }, { "label": "Торико / Toriko", "value": "342" }, { "label": "Точка зрения Всеведущего читателя / Omniscient Reader’s Viewpoint", "value": "1872" }, { "label": "Трансформеры / Transformers", "value": "117" }, { "label": "Трес Наварра / Tres Navarre", "value": "1197" }, { "label": "Три Икса / xXx", "value": "364" }, { "label": "Трон: Восстание / Tron: Uprising", "value": "1887" }, { "label": "Тропико / Tropico", "value": "694" }, { "label": "Ты единственная, кто любит Великого Меня / Ore wo Suki nano wa Omae dake ka yo", "value": "1818" }, { "label": "Ты же любишь мамочку, удары которой бьют по площади двойным уроном? / Tsuujou Kougeki ga Zentai Kougeki de Ni-kai Kougeki no Okaasan wa Suki Desu ka?", "value": "333" }, { "label": "Тэнти - лишний! / Tenchi Muyo", "value": "1316" }, { "label": "У Коми-сан проблемы с общением / 古見さんは、コミュ症です / Komi Can't Communicate", "value": "591" }, { "label": "У меня мало друзей / Boku wa Tomodachi ga Sukunai", "value": "1506" }, { "label": "Убийца Акаме / Akame ga Kill", "value": "30" }, { "label": "Убийца Брайан / Carl Robert Brown", "value": "1092" }, { "label": "Убийца гоблинов / Goblin slayer", "value": "803" }, { "label": "Удар крови / Very AU strike the blood", "value": "1255" }, { "label": "Уж не зомби ли это? / Kore wa Zombie Desu ka?", "value": "725" }, { "label": "Уличный боец(Games) / Суторито Фаита / Street Fighter", "value": "1203" }, { "label": "Ультрафиолет / Ultraviolet", "value": "1831" }, { "label": "Усио и Тора / Ushio and Tora", "value": "1501" }, { "label": "Утраченное небесами / Sora no Otoshimoto / Lost Property of the Sky", "value": "627" }, { "label": "Ученик Мудреца / Kenja no Deshi wo Nanoru Kenja", "value": "1474" }, { "label": "Ученик чародея / The Sorcerer's Apprentice", "value": "862" }, { "label": "Ученики(Games) / Disciples", "value": "1478" }, { "label": "Учитель Хокаге / Hokage Master", "value": "1319" }, { "label": "Учитель-мафиози Реборн! / Katekyo Hitman Reborn!", "value": "134" }, { "label": "Ушастые Друзья / Kemono Friends", "value": "578" }, { "label": "Фальшивая любовь / Nisekoi", "value": "1103" }, { "label": "Фантастическая четвёрка / Fantastic Four", "value": "625" }, { "label": "Фантастические твари и где они обитают / Fantastic Beasts and Where to Find Them", "value": "246" }, { "label": "Финес и Ферб / Phineas and Ferb", "value": "898" }, { "label": "Флотская коллекция / Kantai Collection", "value": "1194" }, { "label": "Флэш / The Flash", "value": "1136" }, { "label": "Фонд SCP / SCP / SCP Foundation", "value": "822" }, { "label": "Форма голоса / A Silent Voice", "value": "1100" }, { "label": "Форсаж / The Fast and the Furious", "value": "363" }, { "label": "Фронт кровавой блокады / Кровавый круг - линия фронта / Kekkai Sensen / Blood Blockade Battlefront", "value": "794" }, { "label": "Футадом мир / Futadom world", "value": "984" }, { "label": "Халк / Hulk", "value": "973" }, { "label": "Хвост Феи / Fairy Tail", "value": "13" }, { "label": "Хеллбой / Hellboy", "value": "1171" }, { "label": "Хеллсинг: Война с нечистью / Hellsing", "value": "116" }, { "label": "Хикару и го / Hikaru no Go", "value": "1121" }, { "label": "Хищник / Predator", "value": "747" }, { "label": "Хоббит(Дж. Р. Р. Толкина) / The Hobbit(John R.R. Tolkien)", "value": "1127" }, { "label": "Ходячие мертвецы / The Walking Dead", "value": "704" }, { "label": "Холодное сердце / Frozen", "value": "633" }, { "label": "Хонкай удар / Honkai impact", "value": "1332" }, { "label": "Хранители Пандоры / The guardians of Pandora", "value": "1187" }, { "label": "Хранитель вечности / UQ Holder", "value": "1469" }, { "label": "Хроники Акаши / Rokudenashi Majutsu Koushi to Akashic Records", "value": "1166" }, { "label": "Хроники Ксенобладания / Дзэнобурэйдо / Xenoblade Chronicles", "value": "1110" }, { "label": "Хроники Миров(Е. Лукин) / Chronicles of the Worlds(E. Lukin)", "value": "346" }, { "label": "Хроники расхитителей гробниц / Даому Биджи / Grave Robbery Note / Dao Mu Bi Ji / Daomu Biji", "value": "724" }, { "label": "Хроники Ренегата / The Renegade Chronicles", "value": "1225" }, { "label": "Царь Горы / The Gog of the Highschool", "value": "1285" }, { "label": "Чародейки / W.I.T.C.H.", "value": "118" }, { "label": "Человек — бензопила / Chainsaw Man", "value": "797" }, { "label": "Человек — летучая мышь / Бэтмен / Bat-man / Batman", "value": "440" }, { "label": "Человек одного удара / Ванпанчмен / One Punch-Man", "value": "70" }, { "label": "Человек-паук / Spider-Man", "value": "326" }, { "label": "Чемпион! / Campione!", "value": "534" }, { "label": "Червь(Джон Маккрей) / Worm(John C. McCrae(Wildbow))", "value": "700" }, { "label": "Черная Пантера(Фильм, 2018) / Black Panther", "value": "1605" }, { "label": "Черновик(С.Лукьяненко) / Draft", "value": "1023" }, { "label": "Чернокнижник в Мире Магов / Варлок / Warlock", "value": "635" }, { "label": "Чёрные души / Black Souls", "value": "1439" }, { "label": "Чёрный зверь / Чёрный Пёс / Kuroinu", "value": "755" }, { "label": "Чёрный зверь: Развращение Благородных Воительниц / Black Beast: Corruption of the Noble Warriors", "value": "1733" }, { "label": "Чёрный клевер / Black Clover", "value": "11" }, { "label": "Что такое настоящий мир? / What is real peace?", "value": "1336" }, { "label": "Чудачества любви не помеха! / Chuunibyou Demo Koi ga Shitai!", "value": "1719" }, { "label": "Чужой / Чужие / Aliens", "value": "1791" }, { "label": "Чужой / Alien", "value": "748" }, { "label": "Чума инкорпорейтед / Plague Inc", "value": "125" }, { "label": "Шазам! / Shazam!", "value": "1560" }, { "label": "Шальной последний босс появился! / A Wild Last Boss Appeared!", "value": "968" }, { "label": "Шальные девчонки / Girl the Wild's", "value": "965" }, { "label": "Шан Чи и легенда десяти колец / Shang-Chi and the Legend of the Ten Rings", "value": "1424" }, { "label": "Шарлотта / Charlotte", "value": "71" }, { "label": "Шерлок (ВВС) / Sherlock", "value": "492" }, { "label": "Шестерни войны / Gears of War", "value": "1346" }, { "label": "Школа мертвецов / Highschool of the Dead", "value": "98" }, { "label": "Школа строгого режима / Prison School", "value": "676" }, { "label": "Школьные воины / Сила тысячи / Ikki Tosen", "value": "818" }, { "label": "Шрек(мультфильм) / Шрэк / Shrek", "value": "1586" }, { "label": "Шухер, у нас новый студент / Transfer Student The Storm Bringer", "value": "628" }, { "label": "Эволюционировать(Games) / Evolve", "value": "1789" }, { "label": "Эволюция. Естественный Отбор / Game Evolution", "value": "287" }, { "label": "Эльсворд: Эль-ий Йоин / Elsword", "value": "199" }, { "label": "Эльфийская песнь / Elfen Lied", "value": "1899" }, { "label": "Эпоха Драконов / Dragon Age", "value": "253" }, { "label": "Эр Ген Я запечатаю небеса / ISSTH / Er Gen I shall seal the heavens", "value": "1170" }, { "label": "Эрагон(Кристофер Паолини) / Eragon", "value": "417" }, { "label": "Эроманга-сэнсэй / Ero-manga Sensei", "value": "1094" }, { "label": "Эстетика заблудшего героя / Hagure Yuusha no Aesthetica", "value": "1310" }, { "label": "Эта гяру будет встречаться с отаку через 100 дней. / 100-nichigo ni Otaku-kun to Tsukiau Gal", "value": "1246" }, { "label": "Эта фарфоровая кукла влюбилась / Sono Bisque Doll wa Koi wo Suru My Dress-Up Darling", "value": "1335" }, { "label": "Это не Гарри Поттер / This is not Harry Potter", "value": "1219" }, { "label": "Этот герой неуязвим, но очень осторожен / This Hero Is Invincible but Too Cautious", "value": "1276" }, { "label": "Эффект массы / Mass Effect", "value": "213" }, { "label": "Эхо пули / Bullet Echo", "value": "1523" }, { "label": "Югио: Дуэльные монстры / Yu-Gi-Oh", "value": "1814" }, { "label": "Югио! Вреинс / Yu-Gi-Oh! VRAINS", "value": "1888" }, { "label": "Юна из гостиницы Юраги / Yuuna of Yuragi Manor", "value": "493" }, { "label": "Юная Лига Справедливости / Young Justice", "value": "1020" }, { "label": "Юные Титаны / Teen Titans", "value": "420" }, { "label": "Я - Четвертый / I Am Number Four", "value": "590" }, { "label": "Я Король-Волшебник / I Am The Sorcerer King", "value": "1292" }, { "label": "Я мачеха, но моя дочь слишком милая / I'm stepmother but daughter is too cute", "value": "777" }, { "label": "Я не родился счастливчиком / I Wasn’t Born Lucky", "value": "996" }, { "label": "Я получил читерские способности в другом мире и стал экстраординарным в реальном мире / I Got a Cheat Skill in Another World and Became Unrivaled in The Real World, Too", "value": "1900" }, { "label": "Я стала потерянной дочерью злодея / I Became the Villain’s Lost Daughter", "value": "1387" }, { "label": "Ядерный трон / Nuclear Throne", "value": "1456" }, { "label": "Ярость [Пересмотрено] / Rage [Revised]", "value": "1337" }, { "label": "Ящик предложений Мэдаки / Medaka box", "value": "874" }, { "label": "Cказка для Дьявола / Tale For Satan", "value": "1271" }, { "label": "D&D стиль / D&D style", "value": "1289" }, { "label": "Dying Light 2: Stay Human", "value": "1906" }, { "label": "Fallout: Нью-Вегас / Fallout: New Vegas", "value": "1249" }, { "label": "Re: Жизнь в альтернативном мире с нуля / Re: Zero, Starting Life in Another World", "value": "57" }, { "label": "Re:Zero Начало жизни в другом мире / Re:Zero Starting Life in Another World", "value": "1531" }, { "label": "Rimworld", "value": "1894" }, { "label": "The Second Coming of Gluttony / The Second Coming of Avarice", "value": "1236" }, { "label": "Vfhdbk", "value": "1884" }, { "label": "XCOM: Враг внутри / XCOM: Enemy Unknown", "value": "476" }, { "label": "Xenus: Точка кипения / Boiling point: Road To Hell / Xenus: Boiling Point", "value": "695" }], "inputType": filterInputs_1.FilterInputs.Checkbox }, { "key": "genres_ex", "label": "Исключить жанры:", "values": [{ "label": "18+", "value": "52" }, { "label": "Арт", "value": "1" }, { "label": "Боевик", "value": "2" }, { "label": "Боевые искусства", "value": "3" }, { "label": "Гаремник", "value": "5" }, { "label": "Героическое фэнтези", "value": "7" }, { "label": "Детектив", "value": "8" }, { "label": "Дзёсэй", "value": "9" }, { "label": "Додзинси", "value": "10" }, { "label": "Драма", "value": "11" }, { "label": "История", "value": "13" }, { "label": "Киберпанк", "value": "46" }, { "label": "Кодомо", "value": "14" }, { "label": "Комедия", "value": "15" }, { "label": "Литрпг", "value": "48" }, { "label": "Махо-сёдзё", "value": "16" }, { "label": "Мелодрама", "value": "49" }, { "label": "Меха", "value": "17" }, { "label": "Мистика", "value": "18" }, { "label": "Научная фантастика", "value": "19" }, { "label": "Повседневность", "value": "20" }, { "label": "Постапокалиптика", "value": "21" }, { "label": "Приключения", "value": "22" }, { "label": "Психология", "value": "23" }, { "label": "Романтика", "value": "24" }, { "label": "Самурайский боевик", "value": "25" }, { "label": "Сверхъестественное", "value": "26" }, { "label": "Сёдзё", "value": "27" }, { "label": "Сёнэн", "value": "29" }, { "label": "Смат", "value": "45" }, { "label": "Спорт", "value": "31" }, { "label": "Сэйнэн", "value": "32" }, { "label": "Сюаньхуа", "value": "44" }, { "label": "Сюаньхуань", "value": "47" }, { "label": "Сянься (XianXia)", "value": "42" }, { "label": "Трагедия", "value": "33" }, { "label": "Триллер", "value": "34" }, { "label": "Ужасы", "value": "35" }, { "label": "Уся (wuxia)", "value": "41" }, { "label": "Фантастика", "value": "36" }, { "label": "Фанфик", "value": "50" }, { "label": "Фэнтези", "value": "37" }, { "label": "Школа", "value": "38" }, { "label": "Этти", "value": "39" }, { "label": "Bl", "value": "43" }, { "label": "Gl", "value": "40" }], "inputType": filterInputs_1.FilterInputs.Checkbox }, { "key": "tags_ex", "label": "Исключить тэги:", "values": [{ "label": "12+", "value": "3316" }, { "label": "16+", "value": "83" }, { "label": "Абсурд", "value": "7973" }, { "label": "Авантюристы", "value": "222" }, { "label": "Автомат", "value": "5272" }, { "label": "Авторский мир", "value": "1062" }, { "label": "Агрессивные персонажи", "value": "3249" }, { "label": "Ад", "value": "2623" }, { "label": "Ад и рай", "value": "817" }, { "label": "Адам дженсен", "value": "1649" }, { "label": "Адаптация произведения", "value": "192" }, { "label": "Адвокат", "value": "6340" }, { "label": "Адекватные главные герои", "value": "1953" }, { "label": "Азартные игры", "value": "5301" }, { "label": "Азгард", "value": "3494" }, { "label": "Азула", "value": "5550" }, { "label": "Аид", "value": "7641" }, { "label": "Айдолы", "value": "4081" }, { "label": "Академия", "value": "316" }, { "label": "Акамэ", "value": "5059" }, { "label": "Аквакинез", "value": "5952" }, { "label": "Акира", "value": "2639" }, { "label": "Акнология", "value": "4634" }, { "label": "Актерское мастерство", "value": "4798" }, { "label": "Актёры", "value": "7506" }, { "label": "Активные герои", "value": "6376" }, { "label": "Акутагава рюноске", "value": "4113" }, { "label": "Аладдин", "value": "6489" }, { "label": "Алая ведьма", "value": "4767" }, { "label": "Алиса", "value": "4761" }, { "label": "Алкоголь", "value": "5508" }, { "label": "Аллегория", "value": "271" }, { "label": "Алукард", "value": "4914" }, { "label": "Алхимики", "value": "1164" }, { "label": "Алхимия", "value": "1473" }, { "label": "Алчность", "value": "6897" }, { "label": "Альбус дамблдор", "value": "5784" }, { "label": "Альтернативное развитие событий", "value": "5330" }, { "label": "Альянсы", "value": "328" }, { "label": "Амбициозный главный герой", "value": "3751" }, { "label": "Америка", "value": "4082" }, { "label": "Амнезия", "value": "2207" }, { "label": "Аморальный герой", "value": "18" }, { "label": "Анбу", "value": "8129" }, { "label": "Ангелы", "value": "857" }, { "label": "Ангелы и демоны", "value": "1327" }, { "label": "Ангст", "value": "4638" }, { "label": "Андроиды", "value": "1993" }, { "label": "Анимализм", "value": "5249" }, { "label": "Аниме", "value": "1294" }, { "label": "Анко митараши", "value": "5768" }, { "label": "Антагонист", "value": "2144" }, { "label": "Антигерой", "value": "7725" }, { "label": "Антиквариат", "value": "3552" }, { "label": "Антимаг", "value": "1348" }, { "label": "Антиутопия", "value": "662" }, { "label": "Апокалипсис", "value": "1498" }, { "label": "Аристократия", "value": "371" }, { "label": "Аристократы", "value": "7338" }, { "label": "Армия", "value": "1723" }, { "label": "Артас", "value": "6700" }, { "label": "Артефакты", "value": "2296" }, { "label": "Археология", "value": "6523" }, { "label": "Асгард", "value": "3635" }, { "label": "Ассасин", "value": "1415" }, { "label": "Асуна", "value": "5044" }, { "label": "Аугментации", "value": "7751" }, { "label": "Ацуши накаджима", "value": "4109" }, { "label": "Аянокоджи киетака", "value": "6862" }, { "label": "Бандиты", "value": "2188" }, { "label": "Басейн", "value": "6847" }, { "label": "Баскетбол", "value": "7933" }, { "label": "Бастарды", "value": "76" }, { "label": "Бедность", "value": "1207" }, { "label": "Без культивации", "value": "668" }, { "label": "Без любовной линий", "value": "2225" }, { "label": "Без перерождений", "value": "262" }, { "label": "Без попаданца", "value": "8065" }, { "label": "Без системы", "value": "747" }, { "label": "Без юмора", "value": "763" }, { "label": "Бездна", "value": "1026" }, { "label": "Безжалостное домашнее животное", "value": "1245" }, { "label": "Безжалостные персонажи", "value": "2986" }, { "label": "Беззаботные персонажи", "value": "3123" }, { "label": "Безответная любовь", "value": "7815" }, { "label": "Безработный", "value": "2202" }, { "label": "Безумие", "value": "37" }, { "label": "Безумные персонажи", "value": "2049" }, { "label": "Бейсбол", "value": "7623" }, { "label": "Беременность", "value": "2122" }, { "label": "Бесконечный поток", "value": "7556" }, { "label": "Беспечные персонажи", "value": "742" }, { "label": "Бесплатно", "value": "8403" }, { "label": "Бессмертные персонажи", "value": "566" }, { "label": "Бесстрашные персонажи", "value": "6921" }, { "label": "Бесстыдные персонажи", "value": "1257" }, { "label": "Бесстыдный главный герой", "value": "8190" }, { "label": "Библиотека", "value": "4210" }, { "label": "Библия", "value": "488" }, { "label": "Бизнес", "value": "704" }, { "label": "Биология", "value": "2220" }, { "label": "Биомехи", "value": "1968" }, { "label": "Биседзе", "value": "777" }, { "label": "Битва за веру", "value": "721" }, { "label": "Битва за трон", "value": "7211" }, { "label": "Битва королевств", "value": "1151" }, { "label": "Битва рас", "value": "6989" }, { "label": "Битвы", "value": "1740" }, { "label": "Благородные персонажи", "value": "2201" }, { "label": "Близнецы", "value": "2931" }, { "label": "Богатство", "value": "6522" }, { "label": "Богатые персонажи", "value": "520" }, { "label": "Боги", "value": "173" }, { "label": "Богини", "value": "30" }, { "label": "Богиня", "value": "8324" }, { "label": "Богоубийца", "value": "1253" }, { "label": "Богохульство", "value": "95" }, { "label": "Боевая академия", "value": "2108" }, { "label": "Большая грудь", "value": "4717" }, { "label": "Борос", "value": "6533" }, { "label": "Борьба", "value": "1925" }, { "label": "Борьба за власть", "value": "8072" }, { "label": "Босс и подчиненный", "value": "7157" }, { "label": "Бояръ", "value": "2307" }, { "label": "Брак", "value": "1558" }, { "label": "Брак по расчету", "value": "1389" }, { "label": "Брат и сестра", "value": "615" }, { "label": "Братский комплекс", "value": "2321" }, { "label": "Броманс", "value": "1103" }, { "label": "Брошенные дети", "value": "2846" }, { "label": "Буддизм", "value": "1871" }, { "label": "Будущее", "value": "1820" }, { "label": "Бывший муж", "value": "8080" }, { "label": "Быстрое развитие", "value": "1443" }, { "label": "Бэтгерл", "value": "2584" }, { "label": "Бэтмен", "value": "4668" }, { "label": "В первый раз", "value": "6212" }, { "label": "В этот же мир", "value": "49" }, { "label": "Ваканда", "value": "8331" }, { "label": "Валькирии", "value": "4047" }, { "label": "Вампиры", "value": "2206" }, { "label": "Веб камера", "value": "5664" }, { "label": "Веб новелла", "value": "2349" }, { "label": "Ведьмак", "value": "843" }, { "label": "Ведьмы", "value": "643" }, { "label": "Везучие персонажи", "value": "1879" }, { "label": "Веном", "value": "3994" }, { "label": "Вестерн", "value": "2131" }, { "label": "Вестерос", "value": "8171" }, { "label": "Взросление", "value": "624" }, { "label": "Взрослый главный герой", "value": "2416" }, { "label": "Видео игры", "value": "2630" }, { "label": "Викинги", "value": "267" }, { "label": "Вино", "value": "6972" }, { "label": "Вирт", "value": "6213" }, { "label": "Виртуальная реальность", "value": "325" }, { "label": "Вирусы", "value": "3327" }, { "label": "Владыка демонов", "value": "555" }, { "label": "Власть", "value": "756" }, { "label": "Влюбленность", "value": "6132" }, { "label": "Внешний вид отличается от личности", "value": "1938" }, { "label": "Внучка", "value": "8399" }, { "label": "Военные", "value": "1096" }, { "label": "Возрождение", "value": "1160" }, { "label": "Воины", "value": "287" }, { "label": "Война", "value": "443" }, { "label": "Войны", "value": "2431" }, { "label": "Воландеморт", "value": "4278" }, { "label": "Волейбол", "value": "6415" }, { "label": "Волки", "value": "1166" }, { "label": "Волшебники", "value": "122" }, { "label": "Волшебные существа", "value": "1689" }, { "label": "Волшебство", "value": "719" }, { "label": "Вор", "value": "1399" }, { "label": "Воровка", "value": "6948" }, { "label": "Ворон", "value": "848" }, { "label": "Воскрешение", "value": "6915" }, { "label": "Воспоминания из другого мира", "value": "1366" }, { "label": "Воспоминания из прошлого", "value": "1372" }, { "label": "Воссоединие семьи", "value": "8130" }, { "label": "Восхождение", "value": "380" }, { "label": "Враги становятся любовниками", "value": "978" }, { "label": "Врата", "value": "40" }, { "label": "Врата в другой мир", "value": "1957" }, { "label": "Врач", "value": "1243" }, { "label": "Временная петля", "value": "2852" }, { "label": "Врмморпг", "value": "2043" }, { "label": "Все дозволено", "value": "96" }, { "label": "Всемогущий главный герой", "value": "1414" }, { "label": "Второй шанс", "value": "2372" }, { "label": "Вуайеризм", "value": "2498" }, { "label": "Выживание", "value": "501" }, { "label": "Вымышленные существа", "value": "3466" }, { "label": "Вынужденный брак", "value": "7705" }, { "label": "Высокие технологии", "value": "653" }, { "label": "Высокомерные персонажи", "value": "3250" }, { "label": "Галустян", "value": "5199" }, { "label": "Гангстеры", "value": "7704" }, { "label": "Гарем", "value": "440" }, { "label": "Гарри поттер", "value": "226" }, { "label": "Геймеры", "value": "2130" }, { "label": "Генетические модификации", "value": "1750" }, { "label": "Гениальный главный герой", "value": "1500" }, { "label": "Гений", "value": "1650" }, { "label": "Гермиона грейнджер", "value": "4280" }, { "label": "Герои", "value": "185" }, { "label": "Гигаполис", "value": "8393" }, { "label": "Гильгамеш", "value": "6031" }, { "label": "Гильдии", "value": "900" }, { "label": "Гильдия авантюристов", "value": "1858" }, { "label": "Гинтама", "value": "4544" }, { "label": "Гипноз", "value": "358" }, { "label": "Главная героиня влюбляется первой", "value": "973" }, { "label": "Главный герой бог", "value": "164" }, { "label": "Главный герой влюбляется первым", "value": "3629" }, { "label": "Главный герой выживальщик", "value": "120" }, { "label": "Главный герой гонг", "value": "7877" }, { "label": "Главный герой девушка", "value": "257" }, { "label": "Главный герой демон", "value": "136" }, { "label": "Главный герой женщина", "value": "7329" }, { "label": "Главный герой жестокий", "value": "1553" }, { "label": "Главный герой извращенец", "value": "94" }, { "label": "Главный герой имба", "value": "2421" }, { "label": "Главный герой киборг", "value": "7780" }, { "label": "Главный герой монстр", "value": "869" }, { "label": "Главный герой мужчина", "value": "1997" }, { "label": "Главный герой на стороне сил зла", "value": "1514" }, { "label": "Главный герой не адекватный", "value": "5" }, { "label": "Главный герой не психопат", "value": "7804" }, { "label": "Главный герой не человек", "value": "2172" }, { "label": "Главный герой не эмоционален", "value": "1150" }, { "label": "Главный герой подросток", "value": "2215" }, { "label": "Главный герой позитивный", "value": "7787" }, { "label": "Главный герой психопат", "value": "7803" }, { "label": "Главный герой ребенок", "value": "2347" }, { "label": "Главный герой русский", "value": "2417" }, { "label": "Главный герой сильный с самого начала", "value": "88" }, { "label": "Главный герой скрывает свою силу", "value": "1059" }, { "label": "Главный герой эгоист", "value": "8326" }, { "label": "Гномы", "value": "1870" }, { "label": "Гоблины", "value": "2029" }, { "label": "Годзилла", "value": "6990" }, { "label": "Големы", "value": "1690" }, { "label": "Голливуд", "value": "7754" }, { "label": "Головоломка", "value": "1697" }, { "label": "Горничные", "value": "8091" }, { "label": "Гробница", "value": "388" }, { "label": "Дазай осаму", "value": "4112" }, { "label": "Даньмэй", "value": "3411" }, { "label": "Даосизм", "value": "258" }, { "label": "Дарк соулс", "value": "6057" }, { "label": "Дарт вейдер", "value": "6826" }, { "label": "Дафна гринграсс", "value": "5192" }, { "label": "Дворяне", "value": "7204" }, { "label": "Девушки", "value": "7668" }, { "label": "Девушки монстры", "value": "2231" }, { "label": "Дедушка и внучка", "value": "8400" }, { "label": "Дейви джонс", "value": "8061" }, { "label": "Действие", "value": "1425" }, { "label": "Демон лорд", "value": "153" }, { "label": "Демонология", "value": "2024" }, { "label": "Демоны", "value": "1406" }, { "label": "Дети", "value": "580" }, { "label": "Джарвис", "value": "933" }, { "label": "Джедай", "value": "4442" }, { "label": "Джин", "value": "4024" }, { "label": "Джокер", "value": "3351" }, { "label": "Джон сноу", "value": "7412" }, { "label": "Джоффри баратеон", "value": "3936" }, { "label": "Дзесэй", "value": "678" }, { "label": "Дин винчестер", "value": "6953" }, { "label": "Династии", "value": "2982" }, { "label": "Динозавры", "value": "3666" }, { "label": "Директор", "value": "1417" }, { "label": "Для девушек", "value": "1441" }, { "label": "Дневник", "value": "298" }, { "label": "Добби", "value": "6762" }, { "label": "Добрый мир", "value": "1685" }, { "label": "Договоры с богами", "value": "2152" }, { "label": "Договоры с демонами", "value": "1922" }, { "label": "Доктор", "value": "1991" }, { "label": "Доктор стрэндж", "value": "7634" }, { "label": "Доминирование", "value": "2054" }, { "label": "Дота", "value": "6965" }, { "label": "Доудзюцу", "value": "7133" }, { "label": "Дочь", "value": "3291" }, { "label": "Драко малфой", "value": "46" }, { "label": "Драконы", "value": "282" }, { "label": "Драконы оборотни", "value": "8082" }, { "label": "Древние времена", "value": "7781" }, { "label": "Древний египет", "value": "7614" }, { "label": "Древний китай", "value": "473" }, { "label": "Древний мир", "value": "4" }, { "label": "Другая вселенная", "value": "39" }, { "label": "Другие планеты", "value": "2371" }, { "label": "Другой мир", "value": "2248" }, { "label": "Дружба", "value": "1903" }, { "label": "Друзья детства", "value": "1153" }, { "label": "Духи", "value": "114" }, { "label": "Духовные силы", "value": "1955" }, { "label": "Души", "value": "1212" }, { "label": "Дьявол", "value": "1094" }, { "label": "Дьявольские фрукты", "value": "1564" }, { "label": "Дэдпул", "value": "4399" }, { "label": "Евнух", "value": "6293" }, { "label": "Европейская атмосфера", "value": "5837" }, { "label": "Египет", "value": "528" }, { "label": "Еда", "value": "2056" }, { "label": "Единороги", "value": "437" }, { "label": "Екаи", "value": "655" }, { "label": "Жалкий главный герой", "value": "97" }, { "label": "Жена", "value": "5729" }, { "label": "Женское доминирование", "value": "4622" }, { "label": "Женщина в теле мужчины", "value": "2748" }, { "label": "Женщина кошка", "value": "7513" }, { "label": "Жестокие персонажи", "value": "3153" }, { "label": "Жестокий мир", "value": "1532" }, { "label": "Жестокость", "value": "7880" }, { "label": "Животные", "value": "7488" }, { "label": "Животные компаньоны", "value": "2061" }, { "label": "Жизнь и смерть", "value": "2014" }, { "label": "Жнец", "value": "6288" }, { "label": "Жойен рид", "value": "3926" }, { "label": "Заботливый главный герой", "value": "338" }, { "label": "Закалка тела", "value": "148" }, { "label": "Заклинания", "value": "558" }, { "label": "Заключенные", "value": "3052" }, { "label": "Занпакто", "value": "1102" }, { "label": "Запретная любовь", "value": "8033" }, { "label": "Запутанный сюжет", "value": "1041" }, { "label": "Захват мира", "value": "315" }, { "label": "Зачарованные", "value": "4169" }, { "label": "Звери", "value": "1638" }, { "label": "Зверодевочки", "value": "2006" }, { "label": "Зверолюди", "value": "1018" }, { "label": "Земля", "value": "82" }, { "label": "Злая организация", "value": "7768" }, { "label": "Зло", "value": "1512" }, { "label": "Злодей", "value": "1060" }, { "label": "Злодейка", "value": "2376" }, { "label": "Злой главный герой", "value": "616" }, { "label": "Злые боги", "value": "7109" }, { "label": "Злые персонажи", "value": "3243" }, { "label": "Змей", "value": "5721" }, { "label": "Знаменитости", "value": "1341" }, { "label": "Знание медицины", "value": "1411" }, { "label": "Золушка", "value": "2980" }, { "label": "Зомби", "value": "1743" }, { "label": "Зомби апокалипсис", "value": "912" }, { "label": "Зона 51", "value": "3051" }, { "label": "Зооморфы", "value": "375" }, { "label": "Зорро", "value": "6736" }, { "label": "Зрелые женщины", "value": "1458" }, { "label": "Игра", "value": "663" }, { "label": "Игра на выживание", "value": "2182" }, { "label": "Игровая система", "value": "384" }, { "label": "Игровые элементы", "value": "720" }, { "label": "Извращения", "value": "651" }, { "label": "Измена", "value": "1874" }, { "label": "Изменение характера", "value": "1113" }, { "label": "Изменения внешности", "value": "259" }, { "label": "Изменения личности", "value": "1080" }, { "label": "Изобретения", "value": "126" }, { "label": "Изуку мидория", "value": "6967" }, { "label": "Император", "value": "867" }, { "label": "Империи", "value": "712" }, { "label": "Империя", "value": "1716" }, { "label": "Инвалидность", "value": "2073" }, { "label": "Инквизитор", "value": "143" }, { "label": "Инкуб", "value": "3264" }, { "label": "Инопланетное вторжение", "value": "209" }, { "label": "Инопланетяне", "value": "866" }, { "label": "Интерактив с читателями", "value": "472" }, { "label": "Интересный сюжет", "value": "7374" }, { "label": "Интернет", "value": "739" }, { "label": "Интимные сцены", "value": "3450" }, { "label": "Интрига", "value": "317" }, { "label": "Интриги и заговоры", "value": "1009" }, { "label": "Иные миры", "value": "35" }, { "label": "Исекай", "value": "2979" }, { "label": "Искусственный интеллект", "value": "1900" }, { "label": "Исследование", "value": "1626" }, { "label": "Исторический роман", "value": "573" }, { "label": "Итачи учиха", "value": "4556" }, { "label": "Ичиго", "value": "7254" }, { "label": "Йода", "value": "6829" }, { "label": "Йоруичи", "value": "6755" }, { "label": "Калипсо", "value": "8062" }, { "label": "Каннибализм", "value": "2249" }, { "label": "Капитан америка", "value": "6301" }, { "label": "Каракура", "value": "7473" }, { "label": "Карточная игра", "value": "1557" }, { "label": "Кастиэль", "value": "6954" }, { "label": "Кафе", "value": "3934" }, { "label": "Кацуки бакуго", "value": "7696" }, { "label": "Квесты", "value": "1707" }, { "label": "Киберспорт", "value": "1984" }, { "label": "Кино", "value": "7126" }, { "label": "Китай", "value": "3762" }, { "label": "Кицунэ", "value": "241" }, { "label": "Кланы", "value": "834" }, { "label": "Клоны", "value": "1624" }, { "label": "Книги", "value": "1068" }, { "label": "Книжный червь", "value": "521" }, { "label": "Колдовство", "value": "2681" }, { "label": "колледж", "value": "5058" }, { "label": "Коллекционер", "value": "2588" }, { "label": "Кольцо", "value": "1628" }, { "label": "Коммунисты", "value": "1042" }, { "label": "Коноха", "value": "2827" }, { "label": "Контракт", "value": "4304" }, { "label": "Контроль разума", "value": "485" }, { "label": "Конфеты", "value": "341" }, { "label": "Корейцы", "value": "6535" }, { "label": "Корея", "value": "2443" }, { "label": "Королевская власть", "value": "55" }, { "label": "Королевская семья", "value": "276" }, { "label": "Королевство", "value": "1695" }, { "label": "Короткий рассказ", "value": "239" }, { "label": "Коррупция", "value": "831" }, { "label": "Космическая опера", "value": "2245" }, { "label": "Космические рейнджеры", "value": "5860" }, { "label": "Космос", "value": "329" }, { "label": "Кот", "value": "5171" }, { "label": "Кража навыков", "value": "1159" }, { "label": "Красивая главная героиня", "value": "186" }, { "label": "Красивые женщины", "value": "66" }, { "label": "Красивые персонажи", "value": "5787" }, { "label": "Красивый главный герой", "value": "895" }, { "label": "Крафт", "value": "1599" }, { "label": "Кроссовер", "value": "75" }, { "label": "Ктулху", "value": "920" }, { "label": "Кузнец", "value": "853" }, { "label": "Кукла", "value": "3085" }, { "label": "Кулинария", "value": "2230" }, { "label": "Культивация", "value": "1901" }, { "label": "Культивирование", "value": "1860" }, { "label": "Курама", "value": "5709" }, { "label": "Курилин", "value": "6134" }, { "label": "Кушина узумаки", "value": "5222" }, { "label": "Лавкрафт", "value": "6063" }, { "label": "Лара крофт", "value": "6435" }, { "label": "Легенда о зельде", "value": "5707" }, { "label": "Ленивый главный герой", "value": "1516" }, { "label": "Леон золдик", "value": "7469" }, { "label": "Лес", "value": "6645" }, { "label": "Лечебная магия", "value": "562" }, { "label": "Локи", "value": "1725" }, { "label": "Лоли", "value": "1576" }, { "label": "Лопата", "value": "4989" }, { "label": "Лорд", "value": "8404" }, { "label": "Лориен", "value": "7397" }, { "label": "Лошади", "value": "6110" }, { "label": "Лунатизм", "value": "3520" }, { "label": "Луффи", "value": "274" }, { "label": "Лучник", "value": "1038" }, { "label": "Любовный интерес влюбляется первым", "value": "7753" }, { "label": "Любовный треугольник", "value": "2109" }, { "label": "Любовь", "value": "2297" }, { "label": "Любовь с первого взгляда", "value": "7748" }, { "label": "Любящие родители", "value": "2699" }, { "label": "Люди", "value": "3572" }, { "label": "Люцифер", "value": "5883" }, { "label": "Маг", "value": "780" }, { "label": "Магазин", "value": "4762" }, { "label": "Маги", "value": "58" }, { "label": "Магическая академия", "value": "6788" }, { "label": "Магические звери", "value": "684" }, { "label": "Магические предметы", "value": "1648" }, { "label": "Магический мир", "value": "578" }, { "label": "Магия", "value": "150" }, { "label": "Магия воды", "value": "6450" }, { "label": "Магия воздуха", "value": "7627" }, { "label": "Магия земли", "value": "7626" }, { "label": "Магия и технология", "value": "107" }, { "label": "Магия крови", "value": "7976" }, { "label": "Магия льда", "value": "1379" }, { "label": "Магия огня", "value": "7625" }, { "label": "Магия призыва", "value": "885" }, { "label": "Магия природы", "value": "6226" }, { "label": "Магия стихий", "value": "7673" }, { "label": "Магия тьмы", "value": "3596" }, { "label": "Мадара", "value": "2929" }, { "label": "Мазохизм", "value": "1961" }, { "label": "Мама", "value": "12" }, { "label": "Мама и дочь", "value": "7894" }, { "label": "Мама и сын", "value": "7895" }, { "label": "Манга", "value": "2464" }, { "label": "Манипуляция временем", "value": "932" }, { "label": "Маньяк", "value": "2026" }, { "label": "Маргери тирелл", "value": "3935" }, { "label": "Марионетки", "value": "3175" }, { "label": "Марс", "value": "4013" }, { "label": "Марти стью", "value": "594" }, { "label": "Мастер на все руки", "value": "3189" }, { "label": "Матриархат", "value": "7197" }, { "label": "Мать и сестры", "value": "7946" }, { "label": "Мафия", "value": "353" }, { "label": "Мачеха", "value": "4664" }, { "label": "Мегаполис", "value": "3322" }, { "label": "Медицина", "value": "441" }, { "label": "Медленная романтика", "value": "8383" }, { "label": "Медленное развитие истории", "value": "7462" }, { "label": "Мелиодас", "value": "7224" }, { "label": "Мелодрама", "value": "1507" }, { "label": "Менеджмент", "value": "368" }, { "label": "Мерлин", "value": "3977" }, { "label": "Месть", "value": "1218" }, { "label": "Меч", "value": "48" }, { "label": "Мечники", "value": "969" }, { "label": "Мечта", "value": "527" }, { "label": "Мизуки", "value": "4269" }, { "label": "Микото", "value": "3862" }, { "label": "Милая главная героиня", "value": "134" }, { "label": "Милф", "value": "1987" }, { "label": "Милый главный герой", "value": "2678" }, { "label": "Мимик", "value": "5706" }, { "label": "Мина ашидо", "value": "7695" }, { "label": "Минато намикадзе", "value": "5223" }, { "label": "Мир будущего", "value": "1770" }, { "label": "Мир земли", "value": "8394" }, { "label": "Мир меча и магии", "value": "1271" }, { "label": "Мистер пропер", "value": "565" }, { "label": "Мифические существа", "value": "1878" }, { "label": "Мифы и легенды", "value": "4463" }, { "label": "Младшая сестра", "value": "1523" }, { "label": "Мморпг", "value": "620" }, { "label": "Много главных героев", "value": "1191" }, { "label": "Много крови", "value": "5318" }, { "label": "Много персонажей", "value": "1539" }, { "label": "Множество королевств", "value": "32" }, { "label": "Модерн", "value": "5457" }, { "label": "Мокутон", "value": "4438" }, { "label": "Молоко", "value": "5469" }, { "label": "Монархия", "value": "3590" }, { "label": "Монстры", "value": "307" }, { "label": "Море", "value": "922" }, { "label": "Моритика ринносукэ", "value": "1142" }, { "label": "Мортал комбат", "value": "5861" }, { "label": "Мошенник", "value": "959" }, { "label": "Мрачный мир", "value": "1" }, { "label": "Мужчина в женском теле", "value": "8405" }, { "label": "Музыка", "value": "1183" }, { "label": "Мультивселенная", "value": "7410" }, { "label": "Мурим", "value": "7342" }, { "label": "Мутанты", "value": "2392" }, { "label": "Мутация", "value": "29" }, { "label": "Мясо", "value": "1503" }, { "label": "На реальных событиях", "value": "26" }, { "label": "Навыки", "value": "415" }, { "label": "Нагато узумаки", "value": "5221" }, { "label": "Наемники", "value": "1668" }, { "label": "Назарик", "value": "5369" }, { "label": "Наивный главный герой", "value": "159" }, { "label": "Наложница", "value": "4867" }, { "label": "Наноботы", "value": "2332" }, { "label": "Наруто", "value": "7177" }, { "label": "Наруто и хината", "value": "5766" }, { "label": "Насилие и жестокость", "value": "1440" }, { "label": "Наука", "value": "2150" }, { "label": "Национализм", "value": "5556" }, { "label": "Нацу", "value": "5826" }, { "label": "Нацуки субару", "value": "6656" }, { "label": "Начальная школа", "value": "3920" }, { "label": "Наши дни", "value": "1814" }, { "label": "Не всесильный главный герой", "value": "42" }, { "label": "Не по канону", "value": "1611" }, { "label": "Неверность", "value": "5735" }, { "label": "Невеста", "value": "6011" }, { "label": "Неджи хьюга", "value": "3099" }, { "label": "Недооценённый главный герой", "value": "43" }, { "label": "Нежить", "value": "1949" }, { "label": "Некромаг", "value": "7441" }, { "label": "Некромант", "value": "1914" }, { "label": "Некромантия", "value": "754" }, { "label": "Ненормативная лексика", "value": "160" }, { "label": "Необычные герои", "value": "67" }, { "label": "Нет людей", "value": "7486" }, { "label": "Нетораре", "value": "403" }, { "label": "Нетори", "value": "5393" }, { "label": "Нефилимы", "value": "7764" }, { "label": "Нецензурная лексика", "value": "4912" }, { "label": "Нечисть", "value": "4559" }, { "label": "Ник фьюри", "value": "6304" }, { "label": "Ниндзюцу", "value": "2354" }, { "label": "Ниндзя", "value": "1330" }, { "label": "Новелла", "value": "2105" }, { "label": "Нэко", "value": "147" }, { "label": "Оби ван кеноби", "value": "6830" }, { "label": "Обито учиха", "value": "2814" }, { "label": "Оборотни", "value": "53" }, { "label": "Обратный гарем", "value": "3303" }, { "label": "Овощ", "value": "6098" }, { "label": "Огнестрельное оружие", "value": "3155" }, { "label": "Одержимость", "value": "708" }, { "label": "Один в поле воин", "value": "6498" }, { "label": "Онлайн игра", "value": "1565" }, { "label": "Ооками теппей", "value": "849" }, { "label": "Оригинальные персонажи", "value": "7741" }, { "label": "Орки", "value": "1597" }, { "label": "Оружие", "value": "125" }, { "label": "Основано на видео игре", "value": "602" }, { "label": "Особые способности", "value": "2904" }, { "label": "От бедности к богатству", "value": "901" }, { "label": "От слабого до сильного", "value": "118" }, { "label": "Отель", "value": "2879" }, { "label": "Отец", "value": "3290" }, { "label": "Отношения", "value": "398" }, { "label": "Отношения человек/нечеловек", "value": "7406" }, { "label": "Офис", "value": "3460" }, { "label": "Охотники", "value": "2263" }, { "label": "Оцуцуки", "value": "5101" }, { "label": "Ошейник", "value": "2362" }, { "label": "Ояш", "value": "8048" }, { "label": "Падчерица", "value": "7023" }, { "label": "Падший ангел", "value": "184" }, { "label": "Палач", "value": "852" }, { "label": "Палочка", "value": "2682" }, { "label": "Пандорум", "value": "4360" }, { "label": "Папа и дочь", "value": "7647" }, { "label": "Паразит", "value": "1213" }, { "label": "Параллельный мир", "value": "2092" }, { "label": "Парень", "value": "619" }, { "label": "Паркур", "value": "3391" }, { "label": "Пародия", "value": "898" }, { "label": "Пасхалки", "value": "455" }, { "label": "Паук", "value": "2209" }, { "label": "Пекарь", "value": "5073" }, { "label": "Первая книга", "value": "269" }, { "label": "Первая любовь", "value": "640" }, { "label": "Первый раз", "value": "1465" }, { "label": "Переводы", "value": "24" }, { "label": "Перевоплощение", "value": "1596" }, { "label": "Перевоплощение в игровом мире", "value": "92" }, { "label": "Перемещение в другой мир", "value": "1288" }, { "label": "Перемещение во времени", "value": "146" }, { "label": "Перерождение", "value": "894" }, { "label": "Перерождение в демона", "value": "1111" }, { "label": "Перерождение в дракона", "value": "6867" }, { "label": "Перерождение в злодейку", "value": "5619" }, { "label": "Перерождение в злодея", "value": "749" }, { "label": "Перерождение в ином мире", "value": "109" }, { "label": "Перерождение в монстра", "value": "917" }, { "label": "Перерождений", "value": "335" }, { "label": "Переселение", "value": "813" }, { "label": "Переселение души", "value": "1864" }, { "label": "Перси джексон", "value": "6329" }, { "label": "Пилот", "value": "5521" }, { "label": "Пилюли", "value": "1531" }, { "label": "Пират", "value": "1579" }, { "label": "Пирог", "value": "80" }, { "label": "Писатель", "value": "734" }, { "label": "Пистолеты", "value": "4916" }, { "label": "Письмо", "value": "840" }, { "label": "Питомцы", "value": "3122" }, { "label": "Планомерное развитие событий", "value": "62" }, { "label": "Племянник", "value": "8303" }, { "label": "Пленница", "value": "4897" }, { "label": "Плети", "value": "4839" }, { "label": "Пляж", "value": "4243" }, { "label": "Повар", "value": "658" }, { "label": "Повествование от первого лица", "value": "1054" }, { "label": "Повествование от разных лиц", "value": "600" }, { "label": "Повествование от третьего лица", "value": "2116" }, { "label": "Подавитель", "value": "497" }, { "label": "Подземелье", "value": "798" }, { "label": "Подростки", "value": "636" }, { "label": "Подруга", "value": "5804" }, { "label": "Подчинение", "value": "8343" }, { "label": "Подчинение и унижение", "value": "4500" }, { "label": "Покемоны", "value": "2840" }, { "label": "Полиамория", "value": "1300" }, { "label": "Полигамия", "value": "1336" }, { "label": "Политика", "value": "1313" }, { "label": "Полицейский", "value": "1907" }, { "label": "Полубог", "value": "7170" }, { "label": "Полукровка", "value": "999" }, { "label": "Полулюди", "value": "2273" }, { "label": "Поношенные трусики", "value": "1204" }, { "label": "Попаданец", "value": "2396" }, { "label": "Попаданец в другой мир", "value": "685" }, { "label": "Попаданец в игру", "value": "6466" }, { "label": "Попадание в книгу", "value": "6957" }, { "label": "Постапокалипсис", "value": "1079" }, { "label": "Похищение", "value": "7452" }, { "label": "Поэзия", "value": "1120" }, { "label": "Правитель", "value": "2261" }, { "label": "Превращения в животных", "value": "3410" }, { "label": "Преданный любовный интерес", "value": "2055" }, { "label": "Предательство", "value": "70" }, { "label": "Президент", "value": "4334" }, { "label": "Преступник", "value": "4049" }, { "label": "Преступный мир", "value": "965" }, { "label": "Призрак", "value": "511" }, { "label": "Призыв", "value": "332" }, { "label": "Призыв в другой мир", "value": "781" }, { "label": "Призыв существ", "value": "412" }, { "label": "Приложение на телефоне", "value": "5345" }, { "label": "Принудительный брак", "value": "2954" }, { "label": "Принуждение", "value": "1442" }, { "label": "Принц", "value": "362" }, { "label": "Принцесса", "value": "2403" }, { "label": "Приручение мостров", "value": "2338" }, { "label": "Прислуга", "value": "5185" }, { "label": "Пришельцы", "value": "273" }, { "label": "Проза", "value": "2012" }, { "label": "Прокачка", "value": "1070" }, { "label": "Проклятия", "value": "1347" }, { "label": "Проработанный мир", "value": "1711" }, { "label": "Пророчество", "value": "7762" }, { "label": "Против наркотиков", "value": "8406" }, { "label": "Псайкеры", "value": "3659" }, { "label": "Псионика", "value": "5216" }, { "label": "Психбольница", "value": "6969" }, { "label": "Психические расстройства", "value": "2445" }, { "label": "Психологические травмы", "value": "3418" }, { "label": "Публичный дом", "value": "7860" }, { "label": "Путешествие в другой мир", "value": "10" }, { "label": "Пух", "value": "4286" }, { "label": "Пушечное мясо", "value": "7234" }, { "label": "Пытки", "value": "1756" }, { "label": "Пьяный мастер", "value": "1655" }, { "label": "Пэнси паркинсон", "value": "7411" }, { "label": "Раб", "value": "977" }, { "label": "Рабы", "value": "1240" }, { "label": "Разведение животных", "value": "3990" }, { "label": "Развитие", "value": "208" }, { "label": "Развитие персонажа", "value": "1780" }, { "label": "Развитие поселения", "value": "7203" }, { "label": "Развитие технологий", "value": "1875" }, { "label": "Раздвоение личности", "value": "2062" }, { "label": "Разные расы", "value": "1188" }, { "label": "Разорванная помолвка", "value": "2057" }, { "label": "Разработчик", "value": "2333" }, { "label": "Ранги", "value": "1568" }, { "label": "Ранобэ", "value": "1764" }, { "label": "Расизм", "value": "3554" }, { "label": "Растение", "value": "407" }, { "label": "Реализм", "value": "1180" }, { "label": "Ребенок", "value": "2881" }, { "label": "Ревность", "value": "293" }, { "label": "Революция", "value": "3996" }, { "label": "Реинкарнация", "value": "1302" }, { "label": "Реинкарнация в другом мире", "value": "2180" }, { "label": "Реинкарнация в игровой мир", "value": "304" }, { "label": "Рейджер", "value": "5147" }, { "label": "Религия", "value": "2184" }, { "label": "Рем", "value": "6655" }, { "label": "Ремесленник", "value": "1483" }, { "label": "Ремонт", "value": "5703" }, { "label": "Репликаторы", "value": "3495" }, { "label": "Ресторан", "value": "7519" }, { "label": "Риас гремори", "value": "6950" }, { "label": "Рим", "value": "612" }, { "label": "Риннеган", "value": "4230" }, { "label": "Ритуал", "value": "1233" }, { "label": "Робот", "value": "4011" }, { "label": "Роботы", "value": "467" }, { "label": "Рок ли", "value": "7002" }, { "label": "Рокси", "value": "7380" }, { "label": "Рон уизли", "value": "4279" }, { "label": "Ророноа зоро", "value": "1590" }, { "label": "Росомаха", "value": "1035" }, { "label": "Российская империя", "value": "2146" }, { "label": "Россия", "value": "4246" }, { "label": "Рудеус", "value": "7379" }, { "label": "Руны", "value": "2393" }, { "label": "Русалки", "value": "3127" }, { "label": "Русь", "value": "2016" }, { "label": "Рыцари", "value": "1902" }, { "label": "Рэо хатаке", "value": "2823" }, { "label": "Сабли", "value": "6136" }, { "label": "Сайян", "value": "6802" }, { "label": "Сакура", "value": "2515" }, { "label": "Самец", "value": "1592" }, { "label": "Самураи", "value": "576" }, { "label": "Санса старк", "value": "3925" }, { "label": "Сарказм", "value": "4658" }, { "label": "Саске", "value": "7237" }, { "label": "Сатира", "value": "215" }, { "label": "Сборник", "value": "7367" }, { "label": "Свадьба", "value": "1524" }, { "label": "Сверхсила", "value": "1055" }, { "label": "Свинцовые книги", "value": "5322" }, { "label": "Связывание", "value": "4506" }, { "label": "Священик", "value": "61" }, { "label": "Северус снейп", "value": "5783" }, { "label": "Сёдзе", "value": "2219" }, { "label": "Секты", "value": "1234" }, { "label": "Сельское хозяйство", "value": "787" }, { "label": "Семейный конфликт", "value": "935" }, { "label": "Семья", "value": "728" }, { "label": "Сенджу", "value": "6069" }, { "label": "Серийный убийца", "value": "261" }, { "label": "Сестра", "value": "2342" }, { "label": "Сила глаза", "value": "1019" }, { "label": "Сильная героиня", "value": "7292" }, { "label": "Сильная главная героиня", "value": "1994" }, { "label": "Сильный главный герой", "value": "570" }, { "label": "Сильфиетта", "value": "7381" }, { "label": "Симбиот", "value": "2648" }, { "label": "Сириус блэк", "value": "7655" }, { "label": "Сирота", "value": "297" }, { "label": "Система", "value": "251" }, { "label": "Система уровней", "value": "2174" }, { "label": "Ситх", "value": "1618" }, { "label": "Сказка", "value": "3570" }, { "label": "Скайрим", "value": "4032" }, { "label": "Скайуокер", "value": "6828" }, { "label": "Сквиб", "value": "4101" }, { "label": "Скелет", "value": "1315" }, { "label": "Скрытые способности", "value": "3417" }, { "label": "Скульптор", "value": "1178" }, { "label": "Слабая главная героиня", "value": "5805" }, { "label": "Слабый главный герой", "value": "731" }, { "label": "Славяне", "value": "2168" }, { "label": "Слизерин", "value": "6979" }, { "label": "Слизь", "value": "1095" }, { "label": "Сломанная игрушка", "value": "8396" }, { "label": "Служанка", "value": "3486" }, { "label": "Смартфон", "value": "457" }, { "label": "Смена сущности", "value": "8391" }, { "label": "Смерть", "value": "1779" }, { "label": "Смерть основного персонажа", "value": "1530" }, { "label": "Собаки", "value": "6109" }, { "label": "Соблазн", "value": "7994" }, { "label": "Соблазнение", "value": "2290" }, { "label": "Современность", "value": "568" }, { "label": "Современные знания", "value": "988" }, { "label": "Сожительство", "value": "3026" }, { "label": "Создание армии", "value": "1992" }, { "label": "Создание королевства", "value": "1497" }, { "label": "Создание пилюль", "value": "816" }, { "label": "Создатель", "value": "1045" }, { "label": "Сокровища", "value": "6521" }, { "label": "Сокрытие истинной личности", "value": "2894" }, { "label": "Сома и эрина", "value": "5737" }, { "label": "Соперничество", "value": "7699" }, { "label": "Соседи", "value": "4075" }, { "label": "Сотрудник", "value": "6339" }, { "label": "Социология", "value": "7618" }, { "label": "Спокойная главная героиня", "value": "236" }, { "label": "Спокойный главный герой", "value": "1656" }, { "label": "Спор", "value": "3484" }, { "label": "Спортивное тело", "value": "8317" }, { "label": "Способность кражи", "value": "7784" }, { "label": "Сражения", "value": "23" }, { "label": "Средневековье", "value": "1022" }, { "label": "Сталкер", "value": "1932" }, { "label": "Становление государства", "value": "111" }, { "label": "Старшая школа", "value": "1658" }, { "label": "Стёб", "value": "454" }, { "label": "Стекло", "value": "7453" }, { "label": "Стеснительный персонаж", "value": "152" }, { "label": "Стимпанк", "value": "1894" }, { "label": "Стихи", "value": "1309" }, { "label": "Стратегия", "value": "569" }, { "label": "Строительство", "value": "921" }, { "label": "Студент", "value": "1464" }, { "label": "Студентка", "value": "7518" }, { "label": "Суккубы", "value": "2662" }, { "label": "Супер зрение", "value": "6574" }, { "label": "Супер удача", "value": "489" }, { "label": "Супергерои", "value": "1481" }, { "label": "Суперзлодеи", "value": "2125" }, { "label": "Супермен", "value": "6997" }, { "label": "Суперсилы", "value": "2276" }, { "label": "Существа", "value": "6033" }, { "label": "Сферы", "value": "1077" }, { "label": "Схемы и заговоры", "value": "7116" }, { "label": "Сценарий", "value": "7489" }, { "label": "Счастливый конец", "value": "3293" }, { "label": "Сын", "value": "3297" }, { "label": "Сэм винчестер", "value": "7461" }, { "label": "Сюаньхуа", "value": "2560" }, { "label": "Сюжетные повороты", "value": "7202" }, { "label": "Таблетки для развития", "value": "589" }, { "label": "Таинственное прошлое", "value": "769" }, { "label": "Тайная личность", "value": "8096" }, { "label": "Тайная любовь", "value": "113" }, { "label": "Тайны", "value": "7481" }, { "label": "Тайные отношения", "value": "7450" }, { "label": "Тайцы", "value": "6413" }, { "label": "Танки", "value": "1787" }, { "label": "Творчество", "value": "20" }, { "label": "Тейлор эберт", "value": "3526" }, { "label": "Телекинез", "value": "2203" }, { "label": "Телепортация", "value": "914" }, { "label": "Телохранитель", "value": "723" }, { "label": "Темари", "value": "4810" }, { "label": "Темная магия", "value": "4788" }, { "label": "Темное фэнтези", "value": "1675" }, { "label": "Темные эльфы", "value": "7198" }, { "label": "Тенсейган", "value": "4367" }, { "label": "Тетя", "value": "4194" }, { "label": "Техномагия", "value": "508" }, { "label": "Тиран", "value": "1174" }, { "label": "Титаны", "value": "3308" }, { "label": "Тодороки шото", "value": "5105" }, { "label": "Токио", "value": "5791" }, { "label": "Том реддл", "value": "6652" }, { "label": "Тони старк", "value": "1338" }, { "label": "Тор", "value": "1800" }, { "label": "Тор и локи", "value": "2645" }, { "label": "Торговля", "value": "1637" }, { "label": "Травничество", "value": "221" }, { "label": "Трагическое прошлое", "value": "644" }, { "label": "Трактир", "value": "1918" }, { "label": "Трансмиграция", "value": "1071" }, { "label": "Трансформация", "value": "156" }, { "label": "Трансформеры", "value": "4616" }, { "label": "Тревор филипс", "value": "5427" }, { "label": "Тройняшки", "value": "7169" }, { "label": "Троли", "value": "4250" }, { "label": "Трудолюбивый главный герой", "value": "248" }, { "label": "Тупой главный герой", "value": "3710" }, { "label": "Тьма", "value": "1919" }, { "label": "Тюрьма", "value": "5597" }, { "label": "Тяжёлое детство", "value": "2253" }, { "label": "Убийства", "value": "378" }, { "label": "Убийцы", "value": "1766" }, { "label": "Убийцы драконов", "value": "1484" }, { "label": "Увечья", "value": "3266" }, { "label": "Удача", "value": "6575" }, { "label": "Узумаки", "value": "7579" }, { "label": "Укротитель", "value": "367" }, { "label": "Умения", "value": "531" }, { "label": "Умная главная героиня", "value": "1381" }, { "label": "Умные персонажи", "value": "2756" }, { "label": "Умный главный герой", "value": "2093" }, { "label": "Университет", "value": "2102" }, { "label": "Унижение", "value": "8342" }, { "label": "Уничтожение мира", "value": "81" }, { "label": "Управление временем", "value": "5648" }, { "label": "Уровни", "value": "8" }, { "label": "Усиление", "value": "3549" }, { "label": "Усопп", "value": "6737" }, { "label": "Устроенный брак", "value": "2223" }, { "label": "Усыновление", "value": "395" }, { "label": "Утопия", "value": "4677" }, { "label": "Уход за детьми", "value": "7609" }, { "label": "Учеба в университете", "value": "2797" }, { "label": "Учебное заведение", "value": "1817" }, { "label": "Ученые", "value": "1843" }, { "label": "Учитель", "value": "845" }, { "label": "Учиха", "value": "5348" }, { "label": "Фамильяры", "value": "1471" }, { "label": "Фанатичная любовь", "value": "6721" }, { "label": "Фанаты", "value": "7739" }, { "label": "Фантастический мир", "value": "2414" }, { "label": "Фармацевт", "value": "1706" }, { "label": "Фашисты", "value": "3118" }, { "label": "Феи", "value": "7185" }, { "label": "Фелляция", "value": "5880" }, { "label": "Феминизм", "value": "6527" }, { "label": "Феникс", "value": "2413" }, { "label": "Фенрир", "value": "2740" }, { "label": "Феодализм", "value": "280" }, { "label": "Ферма", "value": "285" }, { "label": "Фехтовальщик", "value": "4685" }, { "label": "Филиппины", "value": "128" }, { "label": "Философия", "value": "1859" }, { "label": "Флафф", "value": "5048" }, { "label": "Флер делакур", "value": "5191" }, { "label": "Флэш", "value": "4667" }, { "label": "Фокусник", "value": "7602" }, { "label": "Фольклор", "value": "4086" }, { "label": "Фугаку", "value": "6161" }, { "label": "Фурри", "value": "6631" }, { "label": "Футбол", "value": "1121" }, { "label": "Фэнтезийный мир", "value": "1556" }, { "label": "Хакер", "value": "475" }, { "label": "Халк", "value": "1196" }, { "label": "Хан нуньен синг", "value": "4817" }, { "label": "Ханма юджиро", "value": "4369" }, { "label": "Хаос", "value": "3117" }, { "label": "Харизматичный главный герой", "value": "2350" }, { "label": "Хатаке какаши", "value": "2820" }, { "label": "Хиддлстон", "value": "5903" }, { "label": "Химавари", "value": "2583" }, { "label": "Хината", "value": "2513" }, { "label": "Хитрый главный герой", "value": "2036" }, { "label": "Хоббит", "value": "6698" }, { "label": "Хогвартс", "value": "5954" }, { "label": "Холодная главная героиня", "value": "6507" }, { "label": "Холодное оружие", "value": "4889" }, { "label": "Холодный главный герой", "value": "2686" }, { "label": "Храм", "value": "2135" }, { "label": "Христианство", "value": "877" }, { "label": "Художественная литература", "value": "2380" }, { "label": "Художница", "value": "518" }, { "label": "Хулиганы", "value": "854" }, { "label": "Цветок", "value": "902" }, { "label": "Цезарь", "value": "1705" }, { "label": "Целители", "value": "4523" }, { "label": "Церковь", "value": "1980" }, { "label": "Цундере", "value": "1078" }, { "label": "Чакра", "value": "1393" }, { "label": "Чат-система", "value": "8407" }, { "label": "Черный юмор", "value": "2868" }, { "label": "Честная главная героиня", "value": "5855" }, { "label": "Честный главный герой", "value": "129" }, { "label": "Читы", "value": "451" }, { "label": "Шантаж", "value": "7175" }, { "label": "Шаринган", "value": "5165" }, { "label": "Шинигами", "value": "4661" }, { "label": "Шиноби", "value": "1227" }, { "label": "Школьная жизнь", "value": "284" }, { "label": "Школьники", "value": "218" }, { "label": "Школьницы", "value": "5946" }, { "label": "Шлюха", "value": "5822" }, { "label": "Шоу-бизнес", "value": "7119" }, { "label": "Шпионы", "value": "4262" }, { "label": "Эволюция", "value": "2040" }, { "label": "Экзорцизм", "value": "676" }, { "label": "Экономика", "value": "121" }, { "label": "Экспансия", "value": "110" }, { "label": "Эксперименты над людьми", "value": "7408" }, { "label": "Элементальная магия", "value": "1264" }, { "label": "Эльфы", "value": "1362" }, { "label": "Эротика", "value": "2053" }, { "label": "Юмор", "value": "7360" }, { "label": "Яды", "value": "201" }, { "label": "Якудза", "value": "4599" }, { "label": "Яндере", "value": "7111" }, { "label": "Rpg", "value": "90" }, { "label": "Star wars", "value": "1985" }, { "label": "Time skip", "value": "824" }, { "label": "Warrior of light", "value": "5289" }], "inputType": filterInputs_1.FilterInputs.Checkbox }, { "key": "fandoms_ex", "label": "Исключить фэндомы:", "values": [{ "label": "19 Дней - Один день / 19 Days - One Day", "value": "838" }, { "label": "47-й / Хитмэн: Агент 47 / Наёмный убийца / Hitman", "value": "589" }, { "label": "Абсолютный дуэт / Absolute Duo", "value": "1029" }, { "label": "Аватар (Короля; об Аанге; об Корре) / Avatar", "value": "1889" }, { "label": "Аватар: Легенда о Корре / Avatar legend of Korra", "value": "351" }, { "label": "Аватар: Легенда об Аанге / Avatar: The Legend of Aang / Avatar: The Last Airbender", "value": "303" }, { "label": "Аватар(Фильм, 2009) / Avatar", "value": "19" }, { "label": "Ад Данте(Данте Алигьери) / Dante's Inferno(Dante Alighieri)", "value": "1502" }, { "label": "Азур Лейн / Azur Lane", "value": "1009" }, { "label": "Айон / Aion", "value": "1005" }, { "label": "Аладдин / Aladdin", "value": "502" }, { "label": "Алиса в Стране чудес / Alice in Wonderland", "value": "616" }, { "label": "Альдноа.Зеро / Aldnoah.Zero", "value": "1799" }, { "label": "Амагами СС / Amagami SS", "value": "900" }, { "label": "Амано Мегуми полна любви! / Amano Megumi wa Sukidarake!", "value": "991" }, { "label": "Американские боги / American Gods", "value": "1843" }, { "label": "Американский папаша! / American Dad", "value": "348" }, { "label": "Ангельские ритмы! / Angel Beats!", "value": "880" }, { "label": "Анлимитед: Хёбу Кёске / Zettai Karen Children: The Unlimited - Hyoubu Kyousuke", "value": "74" }, { "label": "Апостол карточек / The Apostle of Cards", "value": "1504" }, { "label": "Арифурэта: сильнейший ремесленник в мире / Arifureta: From Commonplace to World's Strongest", "value": "62" }, { "label": "Аркан: О Паровых Заводах и Магии Обскуры / Arcanum: Of Steamworks and Magick Obscura", "value": "1495" }, { "label": "Аркейн / Arcane: League of Legends", "value": "1154" }, { "label": "Аркнайтс(Games) / Arknights", "value": "1210" }, { "label": "Армелло(Games) / Armello", "value": "1846" }, { "label": "Астра, затерянная в космосе / Kanata no Astra", "value": "1851" }, { "label": "Атака титанов / Атака на титанов / Attack on Titan", "value": "106" }, { "label": "Атлантида: Затерянный мир / Atlantis: The Lost Empire", "value": "985" }, { "label": "Бакуган Отчаянные бойцы / Bakugan Battle Brawlers", "value": "1069" }, { "label": "Банановая рыба / Banana Fish", "value": "1685" }, { "label": "Баскетбол Куроко / Kuroko no basuke", "value": "582" }, { "label": "Баффи - Истребительница вампиров / Buffy the Vampire Slayer", "value": "115" }, { "label": "Башня Бога / Tower of God", "value": "58" }, { "label": "Бездарная Нана / Munou na Nana", "value": "954" }, { "label": "Бездомный бог / Норагами / Noragami", "value": "1014" }, { "label": "Безумные Мотивы / Looney Tunes", "value": "1140" }, { "label": "Безумный азарт / Kakegurui", "value": "334" }, { "label": "Бейблэйд / Beyblade", "value": "921" }, { "label": "Бен - 10 / Ben 10", "value": "475" }, { "label": "Берсерк / Berserk", "value": "479" }, { "label": "Бесконечное лето / Everlasting Summer", "value": "966" }, { "label": "Бесконечный ужас / Terror Infinity", "value": "381" }, { "label": "Бесподобный Воинственный Бог / Peerless Martial God", "value": "419" }, { "label": "Бессмертный Деревенщина(Games) / Immortal Redneck", "value": "1524" }, { "label": "Бесстыжие / Shameless", "value": "1759" }, { "label": "Био шок(Games) / BioShock", "value": "1095" }, { "label": "Блейд / Blade", "value": "1479" }, { "label": "Блич / Bleach", "value": "7" }, { "label": "Бог войны / God Of War", "value": "352" }, { "label": "Бог из машины / Deus Ex", "value": "612" }, { "label": "Боги поступают плохо / Игры богов / Gods Behaving Badly", "value": "301" }, { "label": "Боевая академия города Астериск / Gakusen Toshi Asterisk", "value": "884" }, { "label": "Боевой континент / Combat Continent / Douluo Dalu", "value": "739" }, { "label": "Боевой молот 40-го тысячелетия / WH40K / Warhammer 40,000", "value": "341" }, { "label": "Боевой молот Фэнтезийная битва / Warhammer Fantasy Battles", "value": "1742" }, { "label": "Боевые машины(Games) / BattleTech", "value": "1667" }, { "label": "Боец Баки / Baki the Grappler", "value": "821" }, { "label": "Божественность II: Эго Дракона(Games) / Divinity II: Ego Draconis", "value": "1538" }, { "label": "Божественные Врата / Divine Gate", "value": "1490" }, { "label": "Большая автомобильная кража 5 / GTA V / Grand Theft Auto V", "value": "1139" }, { "label": "Большая автомобильная кража: Сан-Андреас / GTA: SA / Grand Theft Auto: San Andreas", "value": "820" }, { "label": "Большая разница / Far Cry", "value": "939" }, { "label": "Большой куш / Ван Пис / One Piece", "value": "25" }, { "label": "Боруто: Следующие поколения Наруто / Boruto: Naruto Next Generations", "value": "602" }, { "label": "Брак по договоренности с принцессой красных скорпионов / Arranged marriage to the princess of the Red Scorpions", "value": "1386" }, { "label": "Бэтмен за гранью: Наследие / Batman Beyond: Legacy", "value": "1380" }, { "label": "В другом мире со смартфоном / Isekai wa Smartphone to Tomo ni", "value": "947" }, { "label": "В объятиях шлюхи / JK Bitch ni Shiboraretai", "value": "1283" }, { "label": "В ожидании бедности, я собираюсь стать кузнецом / Expecting to Fall into Ruin, I Aim to Become a Blacksmith", "value": "1475" }, { "label": "В Повелителе как Довакин / In Overlord as a Dovahkiin", "value": "1816" }, { "label": "Вакфу / Wakfu", "value": "814" }, { "label": "ВАЛЛ-И / Wally", "value": "801" }, { "label": "Вампир: Маскарад - Родословные / Vampire: The Masquerade Bloodline", "value": "1212" }, { "label": "Вампирелла / Vampirella", "value": "1214" }, { "label": "Варфрейм / Warframe", "value": "967" }, { "label": "Ведьмак / The Witcher", "value": "278" }, { "label": "Великий из бродячих псов / Bungou Stray Dogs", "value": "75" }, { "label": "Великолепный парк Амаги / Amagi Brilliant Park", "value": "813" }, { "label": "Вельзепуз / Вельзевул / Beelzebub", "value": "765" }, { "label": "Веном / Venom", "value": "978" }, { "label": "Веселая ферма / Fun Farm", "value": "1124" }, { "label": "Вечная история / The Neverending Story", "value": "547" }, { "label": "Вечные(Фильм, 2021) / Eternal", "value": "1234" }, { "label": "Виви: Песнь флюоритового глаза / Vivy: Fluorite Eye's Song", "value": "1819" }, { "label": "Викинги / Vikings", "value": "369" }, { "label": "Владелец ранчо со слизью(Games) / Ранчо слизи / Slime Rancher", "value": "1529" }, { "label": "Властелин колец / Lord of the Ring", "value": "254" }, { "label": "Власть книжного червя / Honzuki no Gekokujou", "value": "1399" }, { "label": "Внук Мудрец / Kenjo no Mago", "value": "1260" }, { "label": "Внук Нурарихёна / Nurarihyon no Mago", "value": "66" }, { "label": "Во всеоружии / Overgeared", "value": "1021" }, { "label": "Во тьме(Games) / The Darkness", "value": "938" }, { "label": "Военная хроника маленькой девочки / Сага о злой Тане / The Saga of Tanya the Evil / \tGekijouban Youjo Senki", "value": "1726" }, { "label": "Возвращение в детские годы / Gaki ni Modotte Yarinaoshi!!!", "value": "1031" }, { "label": "Возрождение Серийного Убийцы / Rebirth Of A Serial Killer", "value": "1358" }, { "label": "Воинственный Бог Асура / Martial God Asura", "value": "771" }, { "label": "Война будущего / The Tomorrow War", "value": "1174" }, { "label": "Война Любовь Снег / War Love Snow", "value": "1417" }, { "label": "Волейбол! / Haikyuu!!", "value": "697" }, { "label": "Волчонок / Teen Wolf", "value": "795" }, { "label": "Волшебная Девушка Спецоперация Аска / Magical Girl Spec-Ops Asuka", "value": "1470" }, { "label": "Волшебник-воин Орфен / Majutsushi Orphen Hagure Tabi: Kimluck-hen", "value": "1128" }, { "label": "Волшебники / The Magicians", "value": "1314" }, { "label": "Волшебный учитель Нэгима! / Negima!: Magister Negi Mag", "value": "1777" }, { "label": "Воля второго цикла мироздания. / Will of the second cycle of the Worldifice.", "value": "1036" }, { "label": "Воспитание хозяина / Yours to Claim", "value": "839" }, { "label": "Восставший против неба / Against the Gods", "value": "957" }, { "label": "Восстание стражей / Хранители снов / Rise of the Guardians", "value": "1488" }, { "label": "Восхождение в Голливуде / I'm in Hollywood", "value": "1237" }, { "label": "Восхождение героя щита / The Rising of the Shield Hero", "value": "103" }, { "label": "Врата Штейна / Steins: Gate", "value": "1044" }, { "label": "Врата: там бьются наши воины / Gate: Jieitai Kanochi nite, Kaku Tatakaeri", "value": "727" }, { "label": "Время / In Time", "value": "542" }, { "label": "Всегда вялый Танака-кун / Tanaka-kun wa Itsumo Kedaruge", "value": "1082" }, { "label": "Всего лишь восьмой сын? Я с этим не смирюсь! / Hachinan tte, Sore wa Nai Deshou! / Eighth son, I don’t think so!", "value": "1473" }, { "label": "Вселенная Марвел / Marvel Universe / Marvel Comics", "value": "6" }, { "label": "Вселенная монстров / Monsterverse / Monster Verse", "value": "905" }, { "label": "Вселенная Стивена / Steven universe", "value": "573" }, { "label": "Вселенная Стрелы / Arrowverse", "value": "488" }, { "label": "Вселенная Тип Луны(Игровая компания) / Universe Type Moon", "value": "1221" }, { "label": "Вселенная DC / DC Universe / DC Comics", "value": "36" }, { "label": "Выпадение радиоактивных осадков / Fallout", "value": "55" }, { "label": "Выращивание онлайн / Cultivation Online", "value": "1252" }, { "label": "Галактическая секс-звезда / Galaxy Sex Star", "value": "1539" }, { "label": "Гало(Games) / Halo", "value": "1338" }, { "label": "Ганц / Gantz", "value": "256" }, { "label": "Гарем рабов в лабиринте другого мира / Slave Harem in the Labyrinth of the Other World", "value": "1853" }, { "label": "Гарри Поттер / Harry Potter", "value": "1" }, { "label": "Гвен-паук / Spider-Gwen", "value": "920" }, { "label": "Генерал маньяк с его сумасшедшей системой / The Maniacal General with his Crazy System", "value": "1356" }, { "label": "Генерал, вы вправе уйти. / General, You May Leave Now", "value": "1385" }, { "label": "Геншин Импакт / Genshin Impact", "value": "689" }, { "label": "Геркулес / Hercules", "value": "721" }, { "label": "Герои и замки / Heroes & Castles", "value": "940" }, { "label": "Герои меча и магии / Heroes of Might and Magic", "value": "1002" }, { "label": "Герои(телесериал) / Heroes", "value": "864" }, { "label": "Гильгамеш / Gilgamesh", "value": "1143" }, { "label": "Гинтама / Gintama", "value": "129" }, { "label": "Глубина(Фильм, 2002) / Below", "value": "1186" }, { "label": "Гнев Асуры / Asura's wrath", "value": "100" }, { "label": "Годзилла / Godzilla", "value": "922" }, { "label": "Голодные игры / The Hunger Games", "value": "859" }, { "label": "Горец / Highlander", "value": "1761" }, { "label": "Горожане(Games) / Townsmen", "value": "1599" }, { "label": "Госпожа Кагуя: в любви как на войне / Kaguya sama: Love is war", "value": "533" }, { "label": "Готика / Gothic", "value": "418" }, { "label": "Готов ли ты влюбиться в извращенку до тех пор, пока она милая? / Hentai demo Suki ni Natte Kuremasu ka", "value": "1383" }, { "label": "Гоэтия / Гоетия / Yοητεία / Ars Goetia", "value": "772" }, { "label": "Гравити Фолз / Gravity Falls", "value": "491" }, { "label": "Граница пустоты / Kara no Kyoukai", "value": "1101" }, { "label": "Гриффины / Family Guy", "value": "349" }, { "label": "Гром над небом / Thunder over the sky", "value": "793" }, { "label": "Гуррен-Лаганн / Tengen Toppa Gurren Lagann", "value": "719" }, { "label": "Да будет благословенен этот прекрасный мир! / Konosuba / Kono Subarashii Sekai ni Shukufuku wo!", "value": "82" }, { "label": "Да Здравствует Призыв! / Long Live Summons!", "value": "948" }, { "label": "Да, я паук, и что с того? / So I'm a Spider, So What? / Kumo Desu ga, Nani ka?", "value": "910" }, { "label": "Данганронпа / Danganronpa", "value": "972" }, { "label": "Две звезды Онмёджи / Sousei no Onmyouji", "value": "1108" }, { "label": "Дворянство / Благородство / Noblesse", "value": "636" }, { "label": "Девочка-волшебница Мадока Магика / Mahou Shoujo Madoka Magica", "value": "1412" }, { "label": "Девочка, которая видит это / Mieruko-chan", "value": "1645" }, { "label": "Декстер(телесериал) / Dexter", "value": "1543" }, { "label": "Демон Бездны всех царств / Abyss Demon of All Realms", "value": "1419" }, { "label": "Демоны старшей школы / High School DxD", "value": "8" }, { "label": "День независимости(Фильм, 1996) / Independence Day", "value": "850" }, { "label": "Детектив Конан / Detective Conan", "value": "1554" }, { "label": "Дети индиго из другого мира / Mondaiji-tachi ga isekai kara kuru sô desu yo", "value": "1484" }, { "label": "Джаггед Альянс 2: Агония Власти(Games) / Jagged Alliance 2", "value": "1668" }, { "label": "Джессика Джонс / Marvel's Jessica Jones", "value": "1817" }, { "label": "Джон Уик / John Wick", "value": "388" }, { "label": "Дисней / The Walt Disney Company", "value": "503" }, { "label": "Для тебя, Бессмертный / Fumetsu no Anata e / To Your Eternity", "value": "1802" }, { "label": "Дневник Будущего / Mirai Nikki", "value": "368" }, { "label": "Дневники вампира / The Vampire Diaries", "value": "160" }, { "label": "Доблесть рыцаря-неудачника / Chivalry of a Failed Knight", "value": "1462" }, { "label": "Добро пожаловать в ад, Ирума / Welcome to Demon School! Iruma-kun", "value": "261" }, { "label": "Добро пожаловать в класс превосходства / Classroom of the Elite", "value": "122" }, { "label": "Добро пожаловать! В лес похотливых эльфов! / Youkoso! Sukebe Elf no Mori e", "value": "1034" }, { "label": "Добывать ремесло / Майнкрафт / Minecraft", "value": "102" }, { "label": "Доктор Кто / Doctor Who", "value": "277" }, { "label": "Доктор Стоун / Dr. Stone", "value": "720" }, { "label": "Доля секунды: скорость / Split - second: velocity", "value": "890" }, { "label": "Дом кролика / Кофейня "Кроличий домик" / Gochuumon wa Usagi Desu ka?", "value": "642" }, { "label": "Домашний очаг / Hearthstone: Heroes of Warcraft / Hearthstone", "value": "934" }, { "label": "Домекано / Domestic Na Kanojo", "value": "632" }, { "label": "Дорогой звёзд / Звёздное преобразование / Stellar Transformation / Xing Chen Bian", "value": "1155" }, { "label": "Доспехи Бога 2: Операция Кондор / Armour of God II: Operation Condor", "value": "1829" }, { "label": "Дота 2 / Dota 2", "value": "1105" }, { "label": "Дофус / Dofus", "value": "817" }, { "label": "Дракенгард / Drakengard / Drag-On Dragoon", "value": "919" }, { "label": "Дракон-горничная госпожи Кобаяси / Kobayashi-san Chi no Maid Dragon", "value": "673" }, { "label": "Дракон-сама из семьи Касумигаока / Dragon-sama of the Kasumigaoka Family", "value": "1458" }, { "label": "Драконий жемчуг Зет / Dragon Ball Z", "value": "307" }, { "label": "Дракониум Онлайн / Draconic Online", "value": "1360" }, { "label": "Дракула / Dracula", "value": "709" }, { "label": "Древнегреческая мифология / Ancient Greek mythology", "value": "1159" }, { "label": "Дре́вние / Первородные / The Originals", "value": "863" }, { "label": "Древние свитки / The Elder Scrolls", "value": "428" }, { "label": "Древние свитки: Скайрим / TES: Skyrim", "value": "337" }, { "label": "Другой мир / Underworld", "value": "480" }, { "label": "Друид с Сеульской станции / Seoul Station Druid", "value": "1178" }, { "label": "Дьявол / Диабло / Diablo", "value": "1787" }, { "label": "Дьявол может плакать / Devil May Cry / DMC", "value": "339" }, { "label": "Дьявол Юраги-су / The Devil of Yuragi-sou", "value": "431" }, { "label": "Дьявол II(Games) / Диабло II / Diablo II", "value": "1055" }, { "label": "Дэдпул / Deadpool", "value": "810" }, { "label": "Дэнни-призрак / Danny Phantom", "value": "109" }, { "label": "Евангелион / Neon Genesis Evangelion", "value": "583" }, { "label": "Единство семи магов / Тринити: Семь Магов / Trinity Seven", "value": "442" }, { "label": "Еженедельный прыжок сёнэн / Weekly Shōnen Jump", "value": "1629" }, { "label": "Ёрмунганд / Jormungand", "value": "77" }, { "label": "Жажда скорости / Need For Speed", "value": "1493" }, { "label": "Железный человек / Iron Man", "value": "710" }, { "label": "Жемчуг дракона / Dragon Ball", "value": "309" }, { "label": "Женщина-Халк(телесериал) / She-Hulk: Attorney at Law", "value": "1593" }, { "label": "Жизнь девушки в игровом мире / A Girl’s Life In A Gaming World", "value": "1406" }, { "label": "Жизнь после / Days Gone", "value": "1279" }, { "label": "За гранью / Beyond the Boundary", "value": "357" }, { "label": "Загипнотизировать Семью / Kyonyuu Kazoku Saimin", "value": "1032" }, { "label": "Закон Уэки / The Law of Ueki", "value": "790" }, { "label": "Закулисье / Backrooms", "value": "1827" }, { "label": "Зачарованные / Charmed", "value": "113" }, { "label": "Защитники / Defenders", "value": "1832" }, { "label": "Защитница Химари / Omamori Himari", "value": "279" }, { "label": "Звёздная принцесса и силы зла\t / Стар против сил зла / Star vs. The Forces of Evil", "value": "782" }, { "label": "Звёздное дитя / Oshi no Ko", "value": "1903" }, { "label": "Звёздное ремесло / StarCraft", "value": "386" }, { "label": "Звездные Войны / Star Wars", "value": "40" }, { "label": "Звёздные войны: Войны клонов - Все типы носителей(мультсериал, 2008) / Star Wars: The Clone Wars", "value": "1182" }, { "label": "Звёздные врата / Stargate", "value": "770" }, { "label": "Звёздные врата: Атлантида / Stargate: Atlantis", "value": "1097" }, { "label": "Звездный путь / Стартрек / Star Trek", "value": "849" }, { "label": "Зверополис / Zootopia", "value": "1449" }, { "label": "Зеленая Жизнь / Green Life", "value": "1196" }, { "label": "Зеленый фонарь / The Green Lantern", "value": "1222" }, { "label": "Зетмен / Zetman", "value": "1191" }, { "label": "Игра в кальмара(телесериал) / Squid game", "value": "1065" }, { "label": "Игра престолов / Game of Thrones", "value": "22" }, { "label": "Игрок / The Gamer", "value": "126" }, { "label": "Идеальная судьба / The Perfect Destiny", "value": "781" }, { "label": "Идолмастер / The Idolmaster", "value": "807" }, { "label": "Иерихон Клайва Баркера / Иерихон / Clive Barker’s Jericho /Jericho", "value": "320" }, { "label": "Извивающийся дракон / Coiling Dragon", "value": "692" }, { "label": "Изгнаные королевства РПГ / Exiled Kingdoms RPG", "value": "1375" }, { "label": "Импульс Валькирии: Сирена / Варукири Дораиву: Сирена / Valkyrie Drive: Mermaid", "value": "1736" }, { "label": "Индекс волшебства / A Certain Magical Index", "value": "68" }, { "label": "Инуяша - Пес-демон / InuYasha", "value": "481" }, { "label": "Искусственный отбор / Triage X", "value": "1037" }, { "label": "Истинный мир боевых искусств / Zhenwu Shijie / True Martial World", "value": "867" }, { "label": "История монстров / Monogatari", "value": "911" }, { "label": "История о второстепенном персонаже который стал игроком в другой игре. / The story is about a minor character who became a player in another game.", "value": "868" }, { "label": "Кабанери железной крепости / Koutetsujou no Kabaneri", "value": "1494" }, { "label": "Каждый раз, когда я сплю, моя душа покидает мое тело / Every Day I Sleep, My Soul Goes Out of My Body", "value": "1048" }, { "label": "Как воспитать героиню из обычной девушки / Saenai Heroine no Sodatekata", "value": "1637" }, { "label": "Как игрок глупой FPS попал в иной мир / Как дурачок из стрелялки в другой мир попал / Manuke na FPS Player ga Isekai e Ochita Baai", "value": "746" }, { "label": "Как приручить дракона / How to Train Your Dragon", "value": "687" }, { "label": "Капитан Америка / Captain America", "value": "1425" }, { "label": "Капитан Марвел(Фильм, 2019) / Captain Marvel", "value": "1594" }, { "label": "Каратель / The Punisher", "value": "387" }, { "label": "Касл / Castle", "value": "389" }, { "label": "Касльвания / Castlevania", "value": "1215" }, { "label": "Катаклизм: Тёмные дни впереди / DDA / Cataclysm: Dark Days Ahead", "value": "680" }, { "label": "Квайзер со Стигматом / Адепт Святого Знака / The Qwaser of Stigmata", "value": "72" }, { "label": "Квартет из альтернативного мира / Isekai Quartet", "value": "1801" }, { "label": "Квест Девушки-монстра / Monster Girl Questt", "value": "928" }, { "label": "Квест титана(Games) / Титанический квест / Titan Quest", "value": "1483" }, { "label": "Кенши(Games) / Kenshi", "value": "1230" }, { "label": "Киберпанк 2077 / Cyberpunk 2077", "value": "416" }, { "label": "Ким Пять-с-плюсом / Kim Possible", "value": "436" }, { "label": "Киру ра Киру / Круши Кромсай / Убей или умри / Kill la Kill", "value": "763" }, { "label": "Класс убийц / Assassination classroom", "value": "610" }, { "label": "Клеймор / Claymore", "value": "110" }, { "label": "Клинок зла / Evil Blade / Übel Blatt", "value": "722" }, { "label": "Клинок королевы / Queen’s Blade", "value": "757" }, { "label": "Клинок Маню: Тайна сисечного свитка / Manyuu Hiken-chou", "value": "501" }, { "label": "Клинок рассекающий демонов / Demon Slayer: Kimetsu no Yaiba", "value": "21" }, { "label": "Клуб Винкс / Winx Club", "value": "397" }, { "label": "Книга джунглей / The Jungle Book", "value": "1688" }, { "label": "Князь тьмы с задней парты / Demon King Daimao / Ichiban Ushiro no Daimaou", "value": "1207" }, { "label": "Код Гиас / Code Geass", "value": "340" }, { "label": "Код Квалидеи / Qualidea Code", "value": "76" }, { "label": "Кольцо Элдена / Elden Ring", "value": "1408" }, { "label": "Комната / The Room", "value": "889" }, { "label": "Конь и клинок: Боевой отряд(Games) / Mount and Blade:Warband", "value": "1477" }, { "label": "Королевства Сердец / Kingdom Hearts", "value": "407" }, { "label": "Короли крестоносцев / Crusader kings", "value": "572" }, { "label": "Король бойцов / The King of Fighters", "value": "1378" }, { "label": "Король лев / The Lion king", "value": "1705" }, { "label": "Король Шаманов / Shaman King", "value": "744" }, { "label": "Корона греха / Guilty Crown", "value": "1007" }, { "label": "Корпорация лоботомии / Lobotomy corporation", "value": "852" }, { "label": "Космические рейнджеры(Games) / Space Rangers", "value": "1508" }, { "label": "Кошечка из Сакурасо / Sakurasou no Pet na Kanojo", "value": "605" }, { "label": "Красавица и чудовище / Beauty and the Beast", "value": "1765" }, { "label": "Красная угроза 3 / Command & Conquer: Red Alert 3", "value": "742" }, { "label": "Красный, Белый, Черный, Желтый / RWBY", "value": "131" }, { "label": "Кредо убийцы / Assassin's Creed", "value": "690" }, { "label": "Кризис / Crysis", "value": "1734" }, { "label": "Крушитель / The Breaker", "value": "1080" }, { "label": "Кунг-фу панда / Kung Fu Panda", "value": "831" }, { "label": "Кэйон! / K-On!", "value": "1785" }, { "label": "Кэнган Асура / Kengan Asura", "value": "726" }, { "label": "Лаборатория Декстера / Dexter Lab", "value": "639" }, { "label": "Лавкрафт / Говард Филлипс Лавкрафт / Howard Phillips Lovecraft", "value": "1259" }, { "label": "Легенда о восьми псах востока / Hakkenden: Touhou Hakken Ibun", "value": "1699" }, { "label": "Легенда о Зельде / The Legend of Zelda", "value": "870" }, { "label": "Легенда о Короле Драконов / Legend of the Dragon King", "value": "623" }, { "label": "Легенда о Легендарных Героях / Densetsu no Yuusha no Densetsu", "value": "193" }, { "label": "Легион Супергероев / The Legion of Super-Heroes", "value": "450" }, { "label": "Леди Баг и Супер-Кот / Miraculous Ladybug", "value": "327" }, { "label": "Летняя сага / Summertime Saga", "value": "1441" }, { "label": "Лига Легенд / League of Legends", "value": "65" }, { "label": "Линия фронта для девочек / Girls' Frontline", "value": "1686" }, { "label": "Литературный клуб Доки Доки / Литературный клуб / Doki Doki literature club!", "value": "819" }, { "label": "Лорд героев(Games) / Lord of Heroes", "value": "1771" }, { "label": "Лорд человечества / Lord of the People", "value": "1896" }, { "label": "Лориенская Сага / Lorien Legacies", "value": "521" }, { "label": "Любимая жена господина генерального директора / Mr.CEO's Beloved Wife", "value": "1389" }, { "label": "Любовные неприятности / To love ru", "value": "353" }, { "label": "Любовь, Деньги, Рок-н-Ролл / Love, Money, Rock'n'Roll", "value": "1890" }, { "label": "Люди в чёрном(Фильм) / Men in Black", "value": "1193" }, { "label": "Люди Икс / X-Men", "value": "371" }, { "label": "Лютер Строуд Сага / The Luther Strode Saga", "value": "1700" }, { "label": "Люцифер(телесериал) / Lucifer", "value": "681" }, { "label": "Маг на полную ставку / Quanzhi Fashi", "value": "291" }, { "label": "Маг смерти не желающий четвертой реинкарнации / The Death Mage Who Doesn’t Want a Fourth Time", "value": "1775" }, { "label": "Маг-целитель: Новый старт / Kaifuku Jutsushi no Yarinaoshi", "value": "1311" }, { "label": "Маги: Волшебный лабиринт / Magi: The Labyrinth of Magic", "value": "1581" }, { "label": "Магистр дьявольского культа / The Grandmaster of Demonic Cultivation", "value": "608" }, { "label": "Магическая академия Атараксия: Гибрид х Сердце / Hybrid x Heart Magias Academy Ataraxia", "value": "1898" }, { "label": "Магическая битва / Magic Battle / Jujutsu Kaisen", "value": "671" }, { "label": "Маленькие кошмары 2 / Little Nightmares 2", "value": "601" }, { "label": "Малефисента / Maleficent", "value": "775" }, { "label": "Мальчик с оленьими рогами / Сладкоежка / Sweet tooth", "value": "1772" }, { "label": "Маска / The mask", "value": "847" }, { "label": "Мастер Урадана / The Master of Uradan", "value": "1395" }, { "label": "Мастера меча онлайн / Sword Art Online / SAO", "value": "324" }, { "label": "Межвидовые Рецензенты / Interspecies Reviewers", "value": "1555" }, { "label": "Менеджер среднего звена Тонэгава / Chuukan Kanriroku Tonegawa", "value": "1084" }, { "label": "Мерлин / Merlin", "value": "486" }, { "label": "Мертвы к Рассвету / Dead by Daylight", "value": "899" }, { "label": "Мертвый или живой / Dead or Alive", "value": "1563" }, { "label": "Мертвый остров / Dead Island", "value": "124" }, { "label": "Месть Масамуне-куна! / Masamune-kun no Revenge", "value": "571" }, { "label": "Метавселенная Рудазова / Rudazov's Metauniverse", "value": "1211" }, { "label": "Метро 2033(Games) / Metro 2033", "value": "1584" }, { "label": "Милый во Франксе / Любимый во Франксе / Darling in the Franxx", "value": "942" }, { "label": "Мир боевых искусств / 武极天下 / Wuji Tianxia / Martial World", "value": "620" }, { "label": "Мир зомби / Zombie World", "value": "1880" }, { "label": "Мир Льда и Пламени / The World of Ice & Fire", "value": "415" }, { "label": "Мир приключений Джеки Чана(мультсериал, 2000) / ackie Chan Adventures", "value": "1544" }, { "label": "Мир танков / WoT Blitz / World of Tanks Blitz", "value": "525" }, { "label": "Мир Тьмы / World of Darkness", "value": "145" }, { "label": "Мир Эрастай / The World of Erasthay", "value": "1836" }, { "label": "Мир Warcraft / World of Warcraft", "value": "89" }, { "label": "Мировая война Z / Война миров Z / World War Z", "value": "1217" }, { "label": "Моана / Moana", "value": "686" }, { "label": "Моб психо 100 / Mob Psycho 100", "value": "866" }, { "label": "Мобильные легенды: Бах-Бах(Games) / Mobile Legends: Bang Bang", "value": "1497" }, { "label": "Могучие рейнджеры / Power Rangers", "value": "1486" }, { "label": "Может, я встречу тебя в подземелье? / DanMachi", "value": "9" }, { "label": "Мой жених сбежал / My Groom Ran Away", "value": "1047" }, { "label": "Мой маленький пони / My Little Pony", "value": "655" }, { "label": "Мой маленький пони: Дружба — это чудо / My Little Pony: Friendship is Magic", "value": "658" }, { "label": "Мой шумный дом(мультсериал, 2016) / The Loud House", "value": "1467" }, { "label": "Монстер Хай / Monster High", "value": "1012" }, { "label": "Моя возлюбленная чпокается со всеми / Kanojo wa Dare to demo Sex Sur", "value": "1274" }, { "label": "Моя геройская академия / Boku no Hero Academia", "value": "69" }, { "label": "Моя девушка - зомби / My Girlfriend is a Zombie", "value": "754" }, { "label": "Моя жена - красивый генеральный директор / My Wife is a Beautiful CEO", "value": "1025" }, { "label": "Моя жена — президент студенческого совета! / My Wife is the Student Council President / Okusama ga Seitokaichou", "value": "241" }, { "label": "Моя Марвел Академия / My marvel academia", "value": "696" }, { "label": "Моя первая модница / Hajimete no Gal", "value": "1835" }, { "label": "Моя Супер-Бывшая / My Super Ex-Girlfriend", "value": "1828" }, { "label": "Мрачный рассвет / Grim Dawn", "value": "1113" }, { "label": "Мстители / The Avengers", "value": "1747" }, { "label": "Мстители. Эра Альтрона / The Avengers. Age of Ultron", "value": "784" }, { "label": "Мулан / Mulan", "value": "706" }, { "label": "Мы не можем учится / Bokutachi wa Benkyou ga Dekinai", "value": "912" }, { "label": "Мэй Гунцин / Mei Gongqing", "value": "753" }, { "label": "Наблюдать / Overwatch", "value": "607" }, { "label": "Надпись / Inscription", "value": "1718" }, { "label": "Нам Ён / Nam Yeon", "value": "1188" }, { "label": "Наруто / Naruto", "value": "3" }, { "label": "Начало после конца / The Beginning After The End", "value": "888" }, { "label": "Не голодай / Don't Starve", "value": "274" }, { "label": "Не издевайся надо мной, Нагаторо / Ijiranaide / Nagatoro-san Don't Toy with Me, Miss Nagatoro", "value": "1041" }, { "label": "Не люблю боль, так что вкачаю все в защиту / Itai no wa Iya nano de Bougyoryoku ni Kyokufuri Shitai to Omoimasu", "value": "517" }, { "label": "Не моя вина, что я непопулярна! / Watashi ga Motenai no wa Dou Kangaetemo Omaera ga Warui", "value": "1381" }, { "label": "Небесный замок Лапута / Tenkuu no Shiro Laputa", "value": "1109" }, { "label": "Невероятные приключения ДжоДжо / JoJo's Bizarre Adventure", "value": "20" }, { "label": "Негодник, которому не снилась девочка-зайка / Rascal Does Not Dream of Bunny Girl Senpai", "value": "1897" }, { "label": "Негодяй спасает мужскую роль / The Villain Saves the Male Lead", "value": "1224" }, { "label": "Неизвестен / Persona", "value": "205" }, { "label": "Некий магический индекс / To Aru Majutsu no Index", "value": "562" }, { "label": "Некий научный акселератор / Toaru Kagaku no Accelerator", "value": "1487" }, { "label": "Ненасытный Берсерк / Boushoku no Berserk: Ore dake Level to Iu Gainen wo Toppa suru the Comic", "value": "1195" }, { "label": "Необъятные небеса / Infinite Stratos / IS", "value": "280" }, { "label": "Необъятный океан / Grand Blue", "value": "531" }, { "label": "Непревзойденная / Master Piece The Animation", "value": "712" }, { "label": "Непризнанный школой владыка демонов / Maou Gakuin no Futekigousha", "value": "1476" }, { "label": "Непутевый ученик в школе магии / Mahouka Koukou No Rettousei", "value": "982" }, { "label": "Непутевый ученик в школе магии / The Irregular at Magic High School", "value": "630" }, { "label": "Несокрушимая механическая кукла / Machine-Doll wa Kizutsukanai", "value": "1030" }, { "label": "Несправедливость / Injustice", "value": "1026" }, { "label": "Нет игры - нет жизни / Без игры жизни нет / No Game No Life", "value": "718" }, { "label": "Неуязвимый / Invincible", "value": "702" }, { "label": "НиоХ(Games) / NioH", "value": "1465" }, { "label": "Новый завет Владыки тьмы / Shinmai Maou no Testament", "value": "1432" }, { "label": "Ну и ну! Земляничные яйца / I My Me! Strawberry Eggs", "value": "1485" }, { "label": "Нулевой Уровень Целомудрия / Teisou Kannen Zero", "value": "1209" }, { "label": "О моём перерождении в меч / Tensei Shitara Ken deshita", "value": "53" }, { "label": "О моём перерождении в слизь / Tensei shitara Slime Datta Ken", "value": "64" }, { "label": "О моя Богиня / Aa! Megami-sama! / Ah! My Goddess", "value": "915" }, { "label": "Обесчещенный(Games) / Dishonored", "value": "1073" }, { "label": "Обитель зла / Resident Evil", "value": "86" }, { "label": "Огненная эмблема / Fire Emblem", "value": "1615" }, { "label": "Огненная эмблема: Пробуждение / Fire Emblem: Awakening", "value": "1616" }, { "label": "Огненная эмблема: Три Дома / Fire Emblem:Three Houses", "value": "1716" }, { "label": "Одинокий рокер! / Bocchi the Rock!", "value": "1904" }, { "label": "Одному лишь Богу ведомый мир / World God Only Knows", "value": "1248" }, { "label": "Она становится гламурной после расторжения помолвки / She gets glamorous after the engagement is annulled", "value": "1404" }, { "label": "Орк-рубака / Orc Grunt", "value": "779" }, { "label": "Освободите эту ведьму / Release that witch", "value": "994" }, { "label": "Острые козырьки(телесериал) / Peaky Blinders", "value": "1177" }, { "label": "От заката до рассвета! / From Dusk till Dawn!", "value": "1416" }, { "label": "Отброс из семьи графа / Trash of counts family", "value": "853" }, { "label": "Отряд самоубийц / The Suicide Squad", "value": "1844" }, { "label": "Отчаянные домохозяйки / Desperate Housewives", "value": "1011" }, { "label": "Отчет о буйстве духов / YuYu Hakusho", "value": "1008" }, { "label": "Охота демонического короля на свою жену / Xie Wang Zhui Qi", "value": "1737" }, { "label": "Охотник х Охотник / Hunter x Hunter", "value": "101" }, { "label": "Охотницы на демонов / Taimanin Asagi", "value": "1463" }, { "label": "Очень приятно Бог! / Kamisama Hajimemashita", "value": "1585" }, { "label": "Очень Странные Дела(телесериал) / Stranger Things", "value": "1834" }, { "label": "ПАЗЛ / PUZZLE", "value": "1762" }, { "label": "Палач Рока / DOOM", "value": "132" }, { "label": "Параграф 78(Фильм) / Paragraph 78", "value": "923" }, { "label": "Паразит: Учение о жизни / Parasyte: The Maxim", "value": "1176" }, { "label": "Пастырь(Фильм, 2011) / Priest", "value": "1173" }, { "label": "Пацаны / The Boys", "value": "133" }, { "label": "Первый детский сад во вселенной / The First Kindergarten in the Universe", "value": "1049" }, { "label": "Перевозчик / Le Transporteur", "value": "365" }, { "label": "Передающийся через кровь / Bloodborne", "value": "229" }, { "label": "Пережить / Outlast", "value": "645" }, { "label": "Перерождение / Rebirth", "value": "550" }, { "label": "Перерождение бессмертного горожанина-культиватора / Rebirth – City Cultivation / Rebirth of the Urban Immortal Cultivator", "value": "843" }, { "label": "Перерождение в монстра / Re:Monster", "value": "85" }, { "label": "Перестрой мир / Sekai O Sai Kochiku / Rebuild World", "value": "961" }, { "label": "Период полураспада(Valve) / Half-Life", "value": "895" }, { "label": "Перси Джексон / Percy Jackson", "value": "308" }, { "label": "Персона 5 / Persona 5", "value": "1614" }, { "label": "Печать ветра / Kaze no Stigma", "value": "845" }, { "label": "Пик боевых искусств / Martial Peak", "value": "414" }, { "label": "Пираты Карибского моря / Pirates of the Caribbean", "value": "932" }, { "label": "Пираты черной лагуны / Black Lagoon", "value": "621" }, { "label": "Пламенная бригада пожарных / Fire Force / Enen no Shouboutai", "value": "841" }, { "label": "Пламя бесчисленых невзгод / I' m really not demon god's lackey", "value": "1452" }, { "label": "Планетарная аннигиляция / Planetary Annihilation", "value": "487" }, { "label": "Плоскостной пейзаж: Мучение / Planescape: Torment", "value": "1768" }, { "label": "По велению адской сестры / The Testament of Sister New Devil", "value": "18" }, { "label": "Поборники тьмы / Darksiders", "value": "1028" }, { "label": "Повар небесной гостиницы / Чем кормят в ином мире / Kakuriyo no Yadomeshi", "value": "998" }, { "label": "Повар-боец Сома / В поисках божественного рецепта / Shokugeki no Souma", "value": "191" }, { "label": "Повелитель тьмы на подработке! / Hataraku Maou-sama!", "value": "674" }, { "label": "Повелитель тьмы: Другая история мира / How Not to Summon a Demon Lord / Isekai Maou to Shoukan Shoujo no Dorei Majutsu", "value": "699" }, { "label": "Повелитель(Куганэ Маруяма) / Overlord", "value": "27" }, { "label": "Повелитель(Games) / Overlord", "value": "1623" }, { "label": "Повесть о Конце Света / Record of Ragnarok", "value": "332" }, { "label": "Повесть о лунной принцессе / Tsukihime: Lunar Legend", "value": "750" }, { "label": "Повесть о Небесных островах / Фэнтези Гранблю / Granblue Fantasy", "value": "808" }, { "label": "Повседневная жизнь бессмертного короля / The Daily Life of the Immortal King / Xian Wang de Richang Shenghuo", "value": "1466" }, { "label": "Повседневная жизнь с девушкой-монстром / Monster Musume", "value": "760" }, { "label": "Пограничье(Games) / Borderlands", "value": "992" }, { "label": "Под лунами Драконьих глаз / Beneath the Dragoneye Moons", "value": "1735" }, { "label": "Подземелья и драконы / Dungeons & Dragons", "value": "81" }, { "label": "Подземная история / Андертейл / Undertale", "value": "390" }, { "label": "Поднявшийся(Games) / Risen", "value": "1273" }, { "label": "Поднятие уровня в одиночку / Solo Leveling", "value": "127" }, { "label": "Подручный Луизы-Нулизы / Zero no Tsukaima", "value": "580" }, { "label": "Пожиратель богов / God Eater", "value": "1321" }, { "label": "Поймай себя ! Моя дорогая жена / Catch You ! My Dear Wife", "value": "1317" }, { "label": "Покемон / Pokemon", "value": "43" }, { "label": "Политическая Хроника Молодой Девушки / A Young Woman's Political Record", "value": "1306" }, { "label": "Полностью пленённые / Totally Captivated", "value": "1086" }, { "label": "Полый Рыцарь(Games) / Hollow Knight", "value": "1198" }, { "label": "Пользователи Силы / Forceusers", "value": "1162" }, { "label": "Поля битвы Неизвестного игрока / ПАБГ / Player Unknown's Battlegrounds / PUBG", "value": "622" }, { "label": "Попытка приручить злого повелителя / Trying to Tame an Evil Overlord", "value": "983" }, { "label": "Поработитель Ада / Helltaker", "value": "776" }, { "label": "Порновселенная / Porn Universe", "value": "1776" }, { "label": "Портал(Valve) / Portal", "value": "800" }, { "label": "Последние из нас / Last Of Us", "value": "1717" }, { "label": "Последний Серафим / Owari no Seraph", "value": "551" }, { "label": "Последняя из рода Блау(Тайга Ри) / The last of the Blau family", "value": "1507" }, { "label": "Последняя фантазия / ファイナルファンタジ / Final Fantasy", "value": "769" }, { "label": "Преподобное безумие / Reverend Insanity", "value": "1280" }, { "label": "Преподобный Гу / Gu Zhen Ren / Daoist Gu", "value": "1464" }, { "label": "Призрачный бегун / Ghostrunner", "value": "613" }, { "label": "Призрачный гонщик / Ghost Rider", "value": "823" }, { "label": "Принц Драконов Хаоса / The Chaos Dragon Prince", "value": "1397" }, { "label": "Принц Персии / Prince of Persia", "value": "1535" }, { "label": "Принцесса монстров / Princess Resurrection", "value": "1304" }, { "label": "Принцесса Цу / Не проиграю! / Maken Ki", "value": "675" }, { "label": "Проект „Восток“ / Touhou Project", "value": "809" }, { "label": "Проект Кей / K Project", "value": "73" }, { "label": "Проклятие: Автоматизация / NieR:Automata", "value": "1496" }, { "label": "Противостояние святого / Renegade Immortal", "value": "926" }, { "label": "Прототип / Prototype", "value": "54" }, { "label": "Пуленепробиваемый / Bang-Tan / BTS", "value": "520" }, { "label": "Путешествие на Запад / Journey to the West", "value": "1833" }, { "label": "Пять невест / Go-Toubun no Hanayome", "value": "713" }, { "label": "Пять ночей у Фредди / Five nights at freddy's", "value": "930" }, { "label": "Рагнарёк Онлайн / Ragnarok Online", "value": "953" }, { "label": "Радуга 6: Осада / Rainbow Six: Siege", "value": "421" }, { "label": "Развращение Дочери / Daraku Reijou Hakoiri Ojou-sama Netorare Choukyou Kiroku", "value": "1284" }, { "label": "Рай Грисайи / Эдем в серых тонах / Grisaia no Rakuen", "value": "584" }, { "label": "Рандеву с жизнью / Date A live", "value": "851" }, { "label": "Ранма ½ / Ranma ½", "value": "1192" }, { "label": "Рапунцель: Запутанная история / Tangled", "value": "773" }, { "label": "Расколотая битвой синева небес / Battle Through the Heavens", "value": "927" }, { "label": "Рассказ служанки / The Handmaid's Tale", "value": "1135" }, { "label": "Расхитительница гробниц / Tomb Raider", "value": "988" }, { "label": "Резатель / Лангриссер / Langrisser", "value": "792" }, { "label": "Реинкарнация безработного / Mushoku Tensei", "value": "569" }, { "label": "Реинкарнация Богини / Megami Tensei", "value": "1161" }, { "label": "Репликант НиеР / NieR Replicant / NieR Gestalt", "value": "1299" }, { "label": "Рецеттия: Повесть о магазине предметов / Recettear: An Item Shop's Tale", "value": "858" }, { "label": "Ривердэйл / Riverdale", "value": "637" }, { "label": "Рик и Морти / Rick and Morty", "value": "315" }, { "label": "Розарий и Вампир / Rosario+Vampire", "value": "83" }, { "label": "Розовая пора моей школьной жизни сплошной обман / Yahari Ore no Seishun Love Come wa Machigatteiru", "value": "856" }, { "label": "Рок шоу! / Show By Rock!!", "value": "344" }, { "label": "Русалочка / The Little Mermaid", "value": "892" }, { "label": "Рыцарь и маг / Knight's & Magic", "value": "1491" }, { "label": "Сага о Винланде / Vinland Saga", "value": "1200" }, { "label": "Садистская смесь / Blend S", "value": "1120" }, { "label": "Сайт волшебниц / Mahou Shoujo Site", "value": "909" }, { "label": "Сверхъестественное(телесериал) / Supernatural", "value": "916" }, { "label": "Связь принцесс: повторное погружение / Princess Connect! Re:Dive", "value": "1481" }, { "label": "Святые / Saints Row", "value": "1390" }, { "label": "Сейлор Мун / Sailor Moon", "value": "114" }, { "label": "Секире: Тени Умирают Дважды / Sekiro: Shadows Die Twice", "value": "1076" }, { "label": "Семь смертных грехов / Nanatsu no Taizai", "value": "61" }, { "label": "Семья шпиона / Spy x Family", "value": "1646" }, { "label": "Сердца Пандоры / Pandora Hearts", "value": "497" }, { "label": "Серия Метроидов / Metroid Series", "value": "1612" }, { "label": "Серый человек / Ди: Гурэйман / D.Gray-man", "value": "367" }, { "label": "Си Тянь Гуань / Si Tian Guan", "value": "1189" }, { "label": "Сильнейший в истории ученик Кэнити / Shijou Saikyou no Deshi Kenichi", "value": "242" }, { "label": "Сильнейший в истории ученик Кэнъити / KenIchi: The Mightiest Disciple", "value": "745" }, { "label": "Сильнейший магнат / The Strongest Tycoon", "value": "1340" }, { "label": "Сильнейший мудрец низшей эмблемы / Shikkakumon no Saikyou Kenja", "value": "1472" }, { "label": "Симпсоны / The Simpsons", "value": "1461" }, { "label": "Симс / The Sims", "value": "654" }, { "label": "Симфония морской стали / Aoki Hagane no Arpeggio", "value": "958" }, { "label": "Сингулярность(Games) / Singularity", "value": "1793" }, { "label": "Синий Архив / Blue Archive", "value": "1411" }, { "label": "Синий экзорцист / Blue Exorcist", "value": "312" }, { "label": "Синяя Тюрьма: Блю Лок / Blue Lock", "value": "1792" }, { "label": "Система Богов и Демонов / God and Devil World", "value": "1648" }, { "label": "Система Спаси-Себя-Сам / The Scum Villain's Self-Saving System: Ren Zha Fanpai Zijiu Xitong", "value": "1505" }, { "label": "Система: Восьмой уровень(Д. Серебряков) / System: Eighth level", "value": "1175" }, { "label": "Сисястая Принцесса под гипнозом / Kyonyuu Princess Saimin", "value": "1618" }, { "label": "Сказание о Демонах и Богах / Tales of Demons and Gods", "value": "59" }, { "label": "Сказание о Тёмном Рыцаре ~ Призван, чтобы одолеть Героя ~ / Tale of Dark Knight~Summoned to Defeat The Hero~", "value": "1647" }, { "label": "Сказки хранителей(Games) / Guardian tales", "value": "1068" }, { "label": "Скрытая Похотливая Натура Моих Русских Сестренок и Мачехи / Muttsuri do Sukebe ro Gibo Shimai", "value": "1282" }, { "label": "Скуби-Ду / Scooby-Doo", "value": "638" }, { "label": "Скучный мир, где не существует самой идеи похабных шуток / Shimoneta to Iu Gainen ga Sonzai Shinai Taikutsu na Sekai", "value": "830" }, { "label": "Сладкая жизнь / Happy Sugar Life", "value": "1099" }, { "label": "Сладкий флирт / Amour Sucré / Sweet Crush", "value": "495" }, { "label": "Сладости и Сигареты / Candy & Cigarettes", "value": "778" }, { "label": "Следопыт Гнев Праведников / Pathfinder Wrath Of The Righteous", "value": "1077" }, { "label": "Следопыт: Творец королей / Pathfinder: Kingmaker", "value": "1770" }, { "label": "Смертельная битва / Мортал Комбат / Mortal Kombat", "value": "806" }, { "label": "Смертельный укус", "value": "1902" }, { "label": "Созданный в бездне / Made in Abyss", "value": "952" }, { "label": "Сок джунглей", "value": "1901" }, { "label": "Сокрушитель: Новые волны / The Breaker: New Waves", "value": "1500" }, { "label": "Соник еж / Sonic the hedgehog", "value": "1052" }, { "label": "Сорвиголова / Daredevil", "value": "1690" }, { "label": "Сотня / Hundred", "value": "885" }, { "label": "Спаун / Spawn", "value": "1254" }, { "label": "Спецагент Арчер / Archer", "value": "624" }, { "label": "Специалист по апгрейду из другого мира / Endless Sea of Clouds ESC", "value": "1499" }, { "label": "Спираль / Удзумаки / Uzumaki", "value": "1164" }, { "label": "СТАЛКЕР / STALKER / S.T.A.L.K.E.R", "value": "677" }, { "label": "Стальная тревога / Full Metal Panic! The Second Raid", "value": "1489" }, { "label": "Стальной алхимик / Fullmetal Alchemist", "value": "1123" }, { "label": "Стальной Гигант / The Iron Giant", "value": "1241" }, { "label": "Становление богом / Bai Lian Cheng Shen", "value": "1315" }, { "label": "Старгерл / Stargirl", "value": "1137" }, { "label": "Стелларис / Stellaris", "value": "1098" }, { "label": "Сторожевые Псы / Watch Dogs", "value": "1886" }, { "label": "Стражи Галактики / Guardians of the Galaxy", "value": "1426" }, { "label": "Страна Самоцветов / Houseki no Kuni", "value": "1305" }, { "label": "Страна чудес смертников / Зона-парк смертников / Deadman Wonderland", "value": "857" }, { "label": "Страношары / Кантриболз / Countryballs", "value": "1895" }, { "label": "Студии 20-й век / 20th Century Studios", "value": "1715" }, { "label": "Судьба / Fate", "value": "1740" }, { "label": "Судьба: Апокриф / Fate: Apocrypha", "value": "231" }, { "label": "Судьба: Великий Орден / Fate: Grand Order", "value": "60" }, { "label": "Судьба: Девочка волшебница Илия / Fate: Kaleid Liner Prisma", "value": "789" }, { "label": "Судьба: Истоки / Fate: Zero", "value": "230" }, { "label": "Судьба: Ночь схватки / Fate: Stay Night", "value": "536" }, { "label": "Сумерки / Twilight", "value": "471" }, { "label": "Супер ген бога / Super God Gene", "value": "316" }, { "label": "Супер Марио / Super Mario", "value": "1661" }, { "label": "Супергёрл(телесериал, 2015) / Supergirl", "value": "1088" }, { "label": "Супермедицинский ниндзя / Super medical ninja", "value": "1391" }, { "label": "Суперсемейка / The Incredibles", "value": "306" }, { "label": "Сэкирэй / Sekirei", "value": "111" }, { "label": "Тада не может влюбиться! / Tada-kun wa koi wo shinai!", "value": "1905" }, { "label": "Тайны Смолвиля / Smallville", "value": "449" }, { "label": "Танец клинка Элементалиста / Seireitsukai no Blade Dance", "value": "1498" }, { "label": "Твоя апрельская ложь / Your lie in april", "value": "532" }, { "label": "Те, кто охотятся на эльфов / エルフを狩るモノたち / Those Who Hunt Elves", "value": "1168" }, { "label": "Темнейшее подземелье / Darkest dungeon", "value": "1405" }, { "label": "Темные Души / Dark Souls", "value": "200" }, { "label": "Темный Ангел / Dark Angel", "value": "1010" }, { "label": "Тёмный Дворецкий / Kuroshitsuj / Dark Butler", "value": "411" }, { "label": "Темный дворецкий / Kuroshitsuji", "value": "1043" }, { "label": "Темный призыватель Апокалипсиса / The Dark Summoner of the Apocalypse", "value": "1407" }, { "label": "Тень ежа / Ёж Шэдоу / Shadow the hedgehog", "value": "796" }, { "label": "Терминатор / The Terminator", "value": "759" }, { "label": "Террарий / Terraria", "value": "805" }, { "label": "Тетрадь смерти / Death Note", "value": "78" }, { "label": "Тибериумные войны / Tiberium Wars", "value": "1893" }, { "label": "Титаник / Titanic", "value": "1842" }, { "label": "Тихий Холм / Сайлент Хилл / Silent Hill", "value": "848" }, { "label": "Тихоокеанский рубеж / Pacific Rim", "value": "832" }, { "label": "Тогайну но Чи ~Потерял кровь~(Games) / Togainu no Chi ~Lost Blood~", "value": "1540" }, { "label": "Токийские вороны / Tokyo Ravens", "value": "836" }, { "label": "Токийские мстители / Tokyo Revengers", "value": "1064" }, { "label": "Токийский Гуль / Tokyo Ghoul", "value": "271" }, { "label": "Тор / Thor", "value": "764" }, { "label": "Торико / Toriko", "value": "342" }, { "label": "Точка зрения Всеведущего читателя / Omniscient Reader’s Viewpoint", "value": "1872" }, { "label": "Трансформеры / Transformers", "value": "117" }, { "label": "Трес Наварра / Tres Navarre", "value": "1197" }, { "label": "Три Икса / xXx", "value": "364" }, { "label": "Трон: Восстание / Tron: Uprising", "value": "1887" }, { "label": "Тропико / Tropico", "value": "694" }, { "label": "Ты единственная, кто любит Великого Меня / Ore wo Suki nano wa Omae dake ka yo", "value": "1818" }, { "label": "Ты же любишь мамочку, удары которой бьют по площади двойным уроном? / Tsuujou Kougeki ga Zentai Kougeki de Ni-kai Kougeki no Okaasan wa Suki Desu ka?", "value": "333" }, { "label": "Тэнти - лишний! / Tenchi Muyo", "value": "1316" }, { "label": "У Коми-сан проблемы с общением / 古見さんは、コミュ症です / Komi Can't Communicate", "value": "591" }, { "label": "У меня мало друзей / Boku wa Tomodachi ga Sukunai", "value": "1506" }, { "label": "Убийца Акаме / Akame ga Kill", "value": "30" }, { "label": "Убийца Брайан / Carl Robert Brown", "value": "1092" }, { "label": "Убийца гоблинов / Goblin slayer", "value": "803" }, { "label": "Удар крови / Very AU strike the blood", "value": "1255" }, { "label": "Уж не зомби ли это? / Kore wa Zombie Desu ka?", "value": "725" }, { "label": "Уличный боец(Games) / Суторито Фаита / Street Fighter", "value": "1203" }, { "label": "Ультрафиолет / Ultraviolet", "value": "1831" }, { "label": "Усио и Тора / Ushio and Tora", "value": "1501" }, { "label": "Утраченное небесами / Sora no Otoshimoto / Lost Property of the Sky", "value": "627" }, { "label": "Ученик Мудреца / Kenja no Deshi wo Nanoru Kenja", "value": "1474" }, { "label": "Ученик чародея / The Sorcerer's Apprentice", "value": "862" }, { "label": "Ученики(Games) / Disciples", "value": "1478" }, { "label": "Учитель Хокаге / Hokage Master", "value": "1319" }, { "label": "Учитель-мафиози Реборн! / Katekyo Hitman Reborn!", "value": "134" }, { "label": "Ушастые Друзья / Kemono Friends", "value": "578" }, { "label": "Фальшивая любовь / Nisekoi", "value": "1103" }, { "label": "Фантастическая четвёрка / Fantastic Four", "value": "625" }, { "label": "Фантастические твари и где они обитают / Fantastic Beasts and Where to Find Them", "value": "246" }, { "label": "Финес и Ферб / Phineas and Ferb", "value": "898" }, { "label": "Флотская коллекция / Kantai Collection", "value": "1194" }, { "label": "Флэш / The Flash", "value": "1136" }, { "label": "Фонд SCP / SCP / SCP Foundation", "value": "822" }, { "label": "Форма голоса / A Silent Voice", "value": "1100" }, { "label": "Форсаж / The Fast and the Furious", "value": "363" }, { "label": "Фронт кровавой блокады / Кровавый круг - линия фронта / Kekkai Sensen / Blood Blockade Battlefront", "value": "794" }, { "label": "Футадом мир / Futadom world", "value": "984" }, { "label": "Халк / Hulk", "value": "973" }, { "label": "Хвост Феи / Fairy Tail", "value": "13" }, { "label": "Хеллбой / Hellboy", "value": "1171" }, { "label": "Хеллсинг: Война с нечистью / Hellsing", "value": "116" }, { "label": "Хикару и го / Hikaru no Go", "value": "1121" }, { "label": "Хищник / Predator", "value": "747" }, { "label": "Хоббит(Дж. Р. Р. Толкина) / The Hobbit(John R.R. Tolkien)", "value": "1127" }, { "label": "Ходячие мертвецы / The Walking Dead", "value": "704" }, { "label": "Холодное сердце / Frozen", "value": "633" }, { "label": "Хонкай удар / Honkai impact", "value": "1332" }, { "label": "Хранители Пандоры / The guardians of Pandora", "value": "1187" }, { "label": "Хранитель вечности / UQ Holder", "value": "1469" }, { "label": "Хроники Акаши / Rokudenashi Majutsu Koushi to Akashic Records", "value": "1166" }, { "label": "Хроники Ксенобладания / Дзэнобурэйдо / Xenoblade Chronicles", "value": "1110" }, { "label": "Хроники Миров(Е. Лукин) / Chronicles of the Worlds(E. Lukin)", "value": "346" }, { "label": "Хроники расхитителей гробниц / Даому Биджи / Grave Robbery Note / Dao Mu Bi Ji / Daomu Biji", "value": "724" }, { "label": "Хроники Ренегата / The Renegade Chronicles", "value": "1225" }, { "label": "Царь Горы / The Gog of the Highschool", "value": "1285" }, { "label": "Чародейки / W.I.T.C.H.", "value": "118" }, { "label": "Человек — бензопила / Chainsaw Man", "value": "797" }, { "label": "Человек — летучая мышь / Бэтмен / Bat-man / Batman", "value": "440" }, { "label": "Человек одного удара / Ванпанчмен / One Punch-Man", "value": "70" }, { "label": "Человек-паук / Spider-Man", "value": "326" }, { "label": "Чемпион! / Campione!", "value": "534" }, { "label": "Червь(Джон Маккрей) / Worm(John C. McCrae(Wildbow))", "value": "700" }, { "label": "Черная Пантера(Фильм, 2018) / Black Panther", "value": "1605" }, { "label": "Черновик(С.Лукьяненко) / Draft", "value": "1023" }, { "label": "Чернокнижник в Мире Магов / Варлок / Warlock", "value": "635" }, { "label": "Чёрные души / Black Souls", "value": "1439" }, { "label": "Чёрный зверь / Чёрный Пёс / Kuroinu", "value": "755" }, { "label": "Чёрный зверь: Развращение Благородных Воительниц / Black Beast: Corruption of the Noble Warriors", "value": "1733" }, { "label": "Чёрный клевер / Black Clover", "value": "11" }, { "label": "Что такое настоящий мир? / What is real peace?", "value": "1336" }, { "label": "Чудачества любви не помеха! / Chuunibyou Demo Koi ga Shitai!", "value": "1719" }, { "label": "Чужой / Чужие / Aliens", "value": "1791" }, { "label": "Чужой / Alien", "value": "748" }, { "label": "Чума инкорпорейтед / Plague Inc", "value": "125" }, { "label": "Шазам! / Shazam!", "value": "1560" }, { "label": "Шальной последний босс появился! / A Wild Last Boss Appeared!", "value": "968" }, { "label": "Шальные девчонки / Girl the Wild's", "value": "965" }, { "label": "Шан Чи и легенда десяти колец / Shang-Chi and the Legend of the Ten Rings", "value": "1424" }, { "label": "Шарлотта / Charlotte", "value": "71" }, { "label": "Шерлок (ВВС) / Sherlock", "value": "492" }, { "label": "Шестерни войны / Gears of War", "value": "1346" }, { "label": "Школа мертвецов / Highschool of the Dead", "value": "98" }, { "label": "Школа строгого режима / Prison School", "value": "676" }, { "label": "Школьные воины / Сила тысячи / Ikki Tosen", "value": "818" }, { "label": "Шрек(мультфильм) / Шрэк / Shrek", "value": "1586" }, { "label": "Шухер, у нас новый студент / Transfer Student The Storm Bringer", "value": "628" }, { "label": "Эволюционировать(Games) / Evolve", "value": "1789" }, { "label": "Эволюция. Естественный Отбор / Game Evolution", "value": "287" }, { "label": "Эльсворд: Эль-ий Йоин / Elsword", "value": "199" }, { "label": "Эльфийская песнь / Elfen Lied", "value": "1899" }, { "label": "Эпоха Драконов / Dragon Age", "value": "253" }, { "label": "Эр Ген Я запечатаю небеса / ISSTH / Er Gen I shall seal the heavens", "value": "1170" }, { "label": "Эрагон(Кристофер Паолини) / Eragon", "value": "417" }, { "label": "Эроманга-сэнсэй / Ero-manga Sensei", "value": "1094" }, { "label": "Эстетика заблудшего героя / Hagure Yuusha no Aesthetica", "value": "1310" }, { "label": "Эта гяру будет встречаться с отаку через 100 дней. / 100-nichigo ni Otaku-kun to Tsukiau Gal", "value": "1246" }, { "label": "Эта фарфоровая кукла влюбилась / Sono Bisque Doll wa Koi wo Suru My Dress-Up Darling", "value": "1335" }, { "label": "Это не Гарри Поттер / This is not Harry Potter", "value": "1219" }, { "label": "Этот герой неуязвим, но очень осторожен / This Hero Is Invincible but Too Cautious", "value": "1276" }, { "label": "Эффект массы / Mass Effect", "value": "213" }, { "label": "Эхо пули / Bullet Echo", "value": "1523" }, { "label": "Югио: Дуэльные монстры / Yu-Gi-Oh", "value": "1814" }, { "label": "Югио! Вреинс / Yu-Gi-Oh! VRAINS", "value": "1888" }, { "label": "Юна из гостиницы Юраги / Yuuna of Yuragi Manor", "value": "493" }, { "label": "Юная Лига Справедливости / Young Justice", "value": "1020" }, { "label": "Юные Титаны / Teen Titans", "value": "420" }, { "label": "Я - Четвертый / I Am Number Four", "value": "590" }, { "label": "Я Король-Волшебник / I Am The Sorcerer King", "value": "1292" }, { "label": "Я мачеха, но моя дочь слишком милая / I'm stepmother but daughter is too cute", "value": "777" }, { "label": "Я не родился счастливчиком / I Wasn’t Born Lucky", "value": "996" }, { "label": "Я получил читерские способности в другом мире и стал экстраординарным в реальном мире / I Got a Cheat Skill in Another World and Became Unrivaled in The Real World, Too", "value": "1900" }, { "label": "Я стала потерянной дочерью злодея / I Became the Villain’s Lost Daughter", "value": "1387" }, { "label": "Ядерный трон / Nuclear Throne", "value": "1456" }, { "label": "Ярость [Пересмотрено] / Rage [Revised]", "value": "1337" }, { "label": "Ящик предложений Мэдаки / Medaka box", "value": "874" }, { "label": "Cказка для Дьявола / Tale For Satan", "value": "1271" }, { "label": "D&D стиль / D&D style", "value": "1289" }, { "label": "Dying Light 2: Stay Human", "value": "1906" }, { "label": "Fallout: Нью-Вегас / Fallout: New Vegas", "value": "1249" }, { "label": "Re: Жизнь в альтернативном мире с нуля / Re: Zero, Starting Life in Another World", "value": "57" }, { "label": "Re:Zero Начало жизни в другом мире / Re:Zero Starting Life in Another World", "value": "1531" }, { "label": "Rimworld", "value": "1894" }, { "label": "The Second Coming of Gluttony / The Second Coming of Avarice", "value": "1236" }, { "label": "Vfhdbk", "value": "1884" }, { "label": "XCOM: Враг внутри / XCOM: Enemy Unknown", "value": "476" }, { "label": "Xenus: Точка кипения / Boiling point: Road To Hell / Xenus: Boiling Point", "value": "695" }], "inputType": filterInputs_1.FilterInputs.Checkbox }, { "key": "atmosphere", "label": "Атмосфера:", "values": [{ "label": "Неважно", "value": "0" }, { "label": "Позитивная", "value": "1" }, { "label": "Dark", "value": "2" }], "inputType": filterInputs_1.FilterInputs.Picker }, { "key": "adult", "label": "Возрастные ограничения:", "values": [{ "label": "Все", "value": "0" }, { "label": "Только 18+", "value": "2" }, { "label": "Убрать 18+", "value": "1" }], "inputType": filterInputs_1.FilterInputs.Picker }]; diff --git a/js/plugins/russian/authortoday.js b/js/plugins/russian/authortoday.js deleted file mode 100644 index 926268a..0000000 --- a/js/plugins/russian/authortoday.js +++ /dev/null @@ -1,327 +0,0 @@ -"use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.filters = exports.fetchImage = exports.searchNovels = exports.parseChapter = exports.parseNovelAndChapters = exports.popularNovels = exports.icon = exports.version = exports.site = exports.name = exports.id = void 0; -const filterInputs_1 = require("@libs/filterInputs"); -const defaultCover_1 = require("@libs/defaultCover"); -const fetch_1 = require("@libs/fetch"); -const novelStatus_1 = require("@libs/novelStatus"); -const cheerio_1 = require("cheerio"); -const dayjs_1 = __importDefault(require("dayjs")); -exports.id = "AT"; -exports.name = "Автор Тудей"; -exports.site = "https://author.today"; -exports.version = "1.0.0"; -exports.icon = "src/ru/authortoday/icon.png"; -const apiUrl = "https://api.author.today/"; -const token = "Bearer guest"; -const popularNovels = function (page, { showLatestNovels, filters }) { - var _a; - return __awaiter(this, void 0, void 0, function* () { - let url = apiUrl + "v1/catalog/search?page=" + page; - if (filters === null || filters === void 0 ? void 0 : filters.genre) { - url += "&genre=" + filters.genre; - } - url += - "&sorting=" + (showLatestNovels ? "recent" : (filters === null || filters === void 0 ? void 0 : filters.sort) || "popular"); - url += "&form=" + ((filters === null || filters === void 0 ? void 0 : filters.form) || "any"); - url += "&state=" + ((filters === null || filters === void 0 ? void 0 : filters.state) || "any"); - url += "&series=" + ((filters === null || filters === void 0 ? void 0 : filters.series) || "any"); - url += "&access=" + ((filters === null || filters === void 0 ? void 0 : filters.access) || "any"); - url += "&promo=" + ((filters === null || filters === void 0 ? void 0 : filters.promo) || "hide"); - const result = yield (0, fetch_1.fetchApi)(url, { - headers: { - Authorization: token, - }, - }); - const json = (yield result.json()); - if ((json === null || json === void 0 ? void 0 : json.code) === "NotFound") { - return []; - } - let novels = []; - (_a = json === null || json === void 0 ? void 0 : json.searchResults) === null || _a === void 0 ? void 0 : _a.forEach((novel) => novels.push({ - name: novel.title, - cover: (novel === null || novel === void 0 ? void 0 : novel.coverUrl) - ? "https://cm.author.today/content/" + novel.coverUrl - : defaultCover_1.defaultCover, - url: exports.site + "/work/" + novel.id, - })); - return novels; - }); -}; -exports.popularNovels = popularNovels; -const parseNovelAndChapters = function (novelUrl) { - var _a; - return __awaiter(this, void 0, void 0, function* () { - const workID = novelUrl.split("/")[4]; - let result = yield (0, fetch_1.fetchApi)(`${apiUrl}v1/work/${workID}/details`, { - headers: { - Authorization: token, - }, - }); - let json = (yield result.json()); - let novel = { - url: novelUrl, - name: json.title, - cover: (json === null || json === void 0 ? void 0 : json.coverUrl) ? json.coverUrl.split("?")[0] : defaultCover_1.defaultCover, - author: (json === null || json === void 0 ? void 0 : json.originalAuthor) || - (json === null || json === void 0 ? void 0 : json.authorFIO) || - (json === null || json === void 0 ? void 0 : json.coAuthorFIO) || - (json === null || json === void 0 ? void 0 : json.secondCoAuthorFIO) || - (json === null || json === void 0 ? void 0 : json.translator) || - "", - genres: (_a = json === null || json === void 0 ? void 0 : json.tags) === null || _a === void 0 ? void 0 : _a.join(", "), - status: (json === null || json === void 0 ? void 0 : json.isFinished) ? novelStatus_1.NovelStatus.Completed : novelStatus_1.NovelStatus.Ongoing, - }; - novel.summary = ""; - novel.summary += (json === null || json === void 0 ? void 0 : json.annotation) ? json.annotation + "\n" : ""; - novel.summary += (json === null || json === void 0 ? void 0 : json.authorNotes) - ? "Примечания автора:\n" + json.authorNotes - : ""; - // all chapters - let chaptersRaw = yield (0, fetch_1.fetchApi)(`${apiUrl}v1/work/${workID}/content`, { - headers: { - Authorization: token, - }, - }); - let chaptersJSON = (yield chaptersRaw.json()); - let chapters = []; - chaptersJSON === null || chaptersJSON === void 0 ? void 0 : chaptersJSON.forEach((chapter, index) => { - if ((chapter === null || chapter === void 0 ? void 0 : chapter.isAvailable) && !(chapter === null || chapter === void 0 ? void 0 : chapter.isDraft)) { - chapters.push({ - name: (chapter === null || chapter === void 0 ? void 0 : chapter.title) || `Глава ${index + 1}`, - releaseTime: (0, dayjs_1.default)((chapter === null || chapter === void 0 ? void 0 : chapter.publishTime) || chapter.lastModificationTime).format("LLL"), - url: `${apiUrl}v1/work/${workID}/chapter/${chapter.id}/text`, - }); - } - }); - novel.chapters = chapters; - return novel; - }); -}; -exports.parseNovelAndChapters = parseNovelAndChapters; -const parseChapter = function (chapterUrl) { - return __awaiter(this, void 0, void 0, function* () { - const result = yield (0, fetch_1.fetchApi)(chapterUrl, { - headers: { - Authorization: token, - }, - }); - const json = (yield result.json()); - if (json === null || json === void 0 ? void 0 : json.code) { - return json.code + "\n" + (json === null || json === void 0 ? void 0 : json.message); - } - let key = json.key.split("").reverse().join("") + "@_@"; - let text = ""; - for (let i = 0; i < json.text.length; i++) { - text += String.fromCharCode(json.text.charCodeAt(i) ^ key.charCodeAt(Math.floor(i % key.length))); - } - const loadedCheerio = (0, cheerio_1.load)(text); - loadedCheerio("img").each(function () { - var _a; - if (!((_a = loadedCheerio(this).attr("src")) === null || _a === void 0 ? void 0 : _a.startsWith("http"))) { - const src = loadedCheerio(this).attr("src"); - loadedCheerio(this).attr("src", exports.site + src); - } - }); - const chapterText = loadedCheerio.html(); - return chapterText; - }); -}; -exports.parseChapter = parseChapter; -const searchNovels = function (searchTerm) { - return __awaiter(this, void 0, void 0, function* () { - const url = `${exports.site}/search?category=works&q=${searchTerm}`; - const result = yield (0, fetch_1.fetchApi)(url); - const body = yield result.text(); - const loadedCheerio = (0, cheerio_1.load)(body); - let novels = []; - loadedCheerio("div.book-row").each(function () { - var _a; - const name = loadedCheerio(this) - .find('div[class="book-title"] a') - .text() - .trim(); - let cover = loadedCheerio(this).find("img").attr("src"); - const url = exports.site + - "/work/" + - ((_a = loadedCheerio(this) - .find('div[class="book-title"] a') - .attr("href")) === null || _a === void 0 ? void 0 : _a.split("/")[2]); - if (cover) { - cover = cover.split("?")[0]; - } - else { - cover = defaultCover_1.defaultCover; - } - novels.push({ name, cover, url }); - }); - return novels; - }); -}; -exports.searchNovels = searchNovels; -exports.fetchImage = fetch_1.fetchFile; -exports.filters = [ - { - key: "sort", - label: "Сортировка", - values: [ - { label: "По популярности", value: "popular" }, - { label: "По количеству лайков", value: "likes" }, - { label: "По комментариям", value: "comments" }, - { label: "По новизне", value: "recent" }, - { label: "По просмотрам", value: "views" }, - { label: "Набирающие популярность", value: "trending" }, - ], - inputType: filterInputs_1.FilterInputs.Picker, - }, - { - key: "genre", - label: "Жанры", - values: [ - { label: "Альтернативная история", value: "sf-history" }, - { label: "Антиутопия", value: "dystopia" }, - { label: "Бизнес-литература", value: "biznes-literatura" }, - { label: "Боевая фантастика", value: "sf-action" }, - { label: "Боевик", value: "action" }, - { label: "Боевое фэнтези", value: "fantasy-action" }, - { label: "Бояръ-Аниме", value: "boyar-anime" }, - { label: "Героическая фантастика", value: "sf-heroic" }, - { label: "Героическое фэнтези", value: "heroic-fantasy" }, - { label: "Городское фэнтези", value: "urban-fantasy" }, - { label: "Детектив", value: "detective" }, - { label: "Детская литература", value: "detskaya-literatura" }, - { label: "Документальная проза", value: "non-fiction" }, - { label: "Историческая проза", value: "historical-fiction" }, - { - label: "Исторические приключения", - value: "historical-adventure", - }, - { label: "Исторический детектив", value: "historical-mystery" }, - { - label: "Исторический любовный роман", - value: "historical-romance", - }, - { label: "Историческое фэнтези", value: "historical-fantasy" }, - { label: "Киберпанк", value: "cyberpunk" }, - { label: "Короткий любовный роман", value: "short-romance" }, - { label: "Космическая фантастика", value: "sf-space" }, - { label: "ЛитРПГ", value: "litrpg" }, - { label: "Любовное фэнтези", value: "love-fantasy" }, - { label: "Любовные романы", value: "romance" }, - { label: "Мистика", value: "paranormal" }, - { label: "Назад в СССР", value: "back-to-ussr" }, - { label: "Научная фантастика", value: "science-fiction" }, - { label: "Подростковая проза", value: "teen-prose" }, - { label: "Политический роман", value: "political-fiction" }, - { label: "Попаданцы", value: "popadantsy" }, - { label: "Попаданцы в космос", value: "popadantsy-v-kosmos" }, - { - label: "Попаданцы в магические миры", - value: "popadantsy-v-magicheskie-miry", - }, - { label: "Попаданцы во времени", value: "popadantsy-vo-vremeni" }, - { label: "Постапокалипсис", value: "postapocalyptic" }, - { label: "Поэзия", value: "poetry" }, - { label: "Приключения", value: "adventure" }, - { label: "Публицистика", value: "publicism" }, - { label: "Развитие личности", value: "razvitie-lichnosti" }, - { label: "Разное", value: "other" }, - { label: "РеалРПГ", value: "realrpg" }, - { label: "Романтическая эротика", value: "romantic-erotika" }, - { label: "Сказка", value: "fairy-tale" }, - { label: "Современная проза", value: "modern-prose" }, - { - label: "Современный любовный роман", - value: "contemporary-romance", - }, - { label: "Социальная фантастика", value: "sf-social" }, - { label: "Стимпанк", value: "steampunk" }, - { label: "Темное фэнтези", value: "dark-fantasy" }, - { label: "Триллер", value: "thriller" }, - { label: "Ужасы", value: "horror" }, - { label: "Фантастика", value: "sci-fi" }, - { - label: "Фантастический детектив", - value: "detective-science-fiction", - }, - { label: "Фанфик", value: "fanfiction" }, - { label: "Фэнтези", value: "fantasy" }, - { label: "Шпионский детектив", value: "spy-mystery" }, - { label: "Эпическое фэнтези", value: "epic-fantasy" }, - { label: "Эротика", value: "erotica" }, - { label: "Эротическая фантастика", value: "sf-erotika" }, - { label: "Эротический фанфик", value: "fanfiction-erotika" }, - { label: "Эротическое фэнтези", value: "fantasy-erotika" }, - { label: "Юмор", value: "humor" }, - { label: "Юмористическая фантастика", value: "sf-humor" }, - { label: "Юмористическое фэнтези", value: "ironical-fantasy" }, - ], - inputType: filterInputs_1.FilterInputs.Picker, - }, - { - key: "form", - label: "Форма произведения", - values: [ - { label: "Любой", value: "any" }, - { label: "Перевод", value: "translation" }, - { label: "Повесть", value: "tale" }, - { label: "Рассказ", value: "story" }, - { label: "Роман", value: "novel" }, - { label: "Сборник поэзии", value: "poetry" }, - { label: "Сборник рассказов", value: "story-book" }, - ], - inputType: filterInputs_1.FilterInputs.Picker, - }, - { - key: "state", - label: "Статус произведения", - values: [ - { label: "Любой статус", value: "any" }, - { label: "В процессе", value: "in-progress" }, - { label: "Завершено", value: "finished" }, - ], - inputType: filterInputs_1.FilterInputs.Picker, - }, - { - key: "series", - label: "Статус цикла", - values: [ - { label: "Не важно", value: "any" }, - { label: "Вне цикла", value: "out" }, - { label: "Цикл завершен", value: "finished" }, - { label: "Цикл не завершен", value: "unfinished" }, - ], - inputType: filterInputs_1.FilterInputs.Picker, - }, - { - key: "access", - label: "Тип доступа", - values: [ - { label: "Любой", value: "any" }, - { label: "Платный", value: "paid" }, - { label: "Бесплатный", value: "free" }, - ], - inputType: filterInputs_1.FilterInputs.Picker, - }, - { - key: "promo", - label: "Промо-фрагмент", - values: [ - { label: "Скрывать", value: "hide" }, - { label: "Показывать", value: "show" }, - ], - inputType: filterInputs_1.FilterInputs.Picker, - }, -]; diff --git a/js/plugins/russian/bookriver.js b/js/plugins/russian/bookriver.js deleted file mode 100644 index 1d15591..0000000 --- a/js/plugins/russian/bookriver.js +++ /dev/null @@ -1,222 +0,0 @@ -"use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.filters = exports.fetchImage = exports.searchNovels = exports.parseChapter = exports.parseNovelAndChapters = exports.popularNovels = exports.icon = exports.version = exports.site = exports.name = exports.id = void 0; -const filterInputs_1 = require("@libs/filterInputs"); -const fetch_1 = require("@libs/fetch"); -const novelStatus_1 = require("@libs/novelStatus"); -const cheerio_1 = require("cheerio"); -const dayjs_1 = __importDefault(require("dayjs")); -exports.id = "bookriver"; -exports.name = "Bookriver"; -exports.site = "https://bookriver.ru"; -exports.version = "1.0.0"; -exports.icon = "src/ru/bookriver/icon.png"; -const popularNovels = function (page, { showLatestNovels, filters }) { - var _a, _b, _c; - return __awaiter(this, void 0, void 0, function* () { - let url = exports.site + `/genre?page=${page}&perPage=24&sortingType=`; - url += showLatestNovels ? "last-update" : (filters === null || filters === void 0 ? void 0 : filters.sort) || "bestseller"; - if (filters) { - if (Array.isArray(filters.genres) && filters.genres.length) { - url += "&g=" + filters.genres.join(","); - } - } - const result = yield (0, fetch_1.fetchApi)(url); - const body = yield result.text(); - const loadedCheerio = (0, cheerio_1.load)(body); - let novels = []; - const jsonRaw = loadedCheerio("#__NEXT_DATA__").html(); - if (jsonRaw) { - let json = JSON.parse(jsonRaw); - (_c = (_b = (_a = json.props.pageProps.state.pagesFilter) === null || _a === void 0 ? void 0 : _a.genre) === null || _b === void 0 ? void 0 : _b.books) === null || _c === void 0 ? void 0 : _c.forEach((novel) => novels.push({ - name: novel.name, - cover: novel.coverImages[0].url, - url: exports.site + "/book/" + novel.slug, - })); - } - return novels; - }); -}; -exports.popularNovels = popularNovels; -const parseNovelAndChapters = function (novelUrl) { - var _a, _b, _c, _d, _e; - return __awaiter(this, void 0, void 0, function* () { - const result = yield (0, fetch_1.fetchApi)(novelUrl); - const body = yield result.text(); - const loadedCheerio = (0, cheerio_1.load)(body); - const jsonRaw = loadedCheerio("#__NEXT_DATA__").html(); - const json = JSON.parse(jsonRaw || '{}'); - let book = (_a = json.props.pageProps.state.book) === null || _a === void 0 ? void 0 : _a.bookPage; - let novel = { - url: novelUrl, - name: book === null || book === void 0 ? void 0 : book.name, - cover: book === null || book === void 0 ? void 0 : book.coverImages[0].url, - summary: book === null || book === void 0 ? void 0 : book.annotation, - author: (_b = book === null || book === void 0 ? void 0 : book.author) === null || _b === void 0 ? void 0 : _b.name, - genres: (_c = book === null || book === void 0 ? void 0 : book.tags) === null || _c === void 0 ? void 0 : _c.map((item) => item.name).join(", "), - status: (book === null || book === void 0 ? void 0 : book.statusComplete) === "writing" - ? novelStatus_1.NovelStatus.Ongoing - : novelStatus_1.NovelStatus.Completed, - }; - let chapters = []; - (_e = (_d = book === null || book === void 0 ? void 0 : book.ebook) === null || _d === void 0 ? void 0 : _d.chapters) === null || _e === void 0 ? void 0 : _e.forEach((chapter) => { - if (chapter.available) { - chapters.push({ - name: chapter.name, - releaseTime: (0, dayjs_1.default)((chapter === null || chapter === void 0 ? void 0 : chapter.firstPublishedAt) || chapter.createdAt).format("LLL"), - url: exports.site + "/reader/" + (book === null || book === void 0 ? void 0 : book.slug) + "/" + chapter.chapterId, - }); - } - }); - novel.chapters = chapters; - return novel; - }); -}; -exports.parseNovelAndChapters = parseNovelAndChapters; -const parseChapter = function (chapterUrl) { - var _a, _b; - return __awaiter(this, void 0, void 0, function* () { - const url = "https://api.bookriver.ru/api/v1/books/chapter/text/"; - const result = yield (0, fetch_1.fetchApi)(url + chapterUrl.split("/").pop()); - const json = (yield result.json()); - let chapterText = json.data.content || "Конец произведения"; - if ((_b = (_a = json.data) === null || _a === void 0 ? void 0 : _a.audio) === null || _b === void 0 ? void 0 : _b.available) { - chapterText += "\n" + json.data.audio.url; - } - return chapterText; - }); -}; -exports.parseChapter = parseChapter; -const searchNovels = function (searchTerm) { - var _a, _b; - return __awaiter(this, void 0, void 0, function* () { - const url = `https://api.bookriver.ru/api/v1/search/autocomplete?keyword=${searchTerm}&page=1&perPage=10`; - const result = yield (0, fetch_1.fetchApi)(url); - const json = (yield result.json()); - let novels = []; - (_b = (_a = json === null || json === void 0 ? void 0 : json.data) === null || _a === void 0 ? void 0 : _a.books) === null || _b === void 0 ? void 0 : _b.forEach((novel) => novels.push({ - name: novel.name, - cover: novel.coverImages[0].url, - url: exports.site + "/book/" + novel.slug, - })); - return novels; - }); -}; -exports.searchNovels = searchNovels; -exports.fetchImage = fetch_1.fetchFile; -exports.filters = [ - { - key: "sort", - label: "Сортировка", - values: [ - { label: "Бестселлеры", value: "bestseller" }, - { label: "Дате добавления", value: "newest" }, - { label: "Дате обновления", value: "last-update" }, - ], - inputType: filterInputs_1.FilterInputs.Picker, - }, - { - key: "genres", - label: "жанры", - values: [ - { - label: "Альтернативная история", - value: "alternativnaya-istoriya", - }, - { label: "Боевая фантастика", value: "boevaya-fantastika" }, - { label: "Боевое фэнтези", value: "boevoe-fentezi" }, - { label: "Бытовое фэнтези", value: "bytovoe-fentezi" }, - { - label: "Героическая фантастика", - value: "geroicheskaya-fantastika", - }, - { label: "Героическое фэнтези", value: "geroicheskoe-fentezi" }, - { label: "Городское фэнтези", value: "gorodskoe-fentezi" }, - { label: "Детектив", value: "detektiv" }, - { - label: "Детективная фантастика", - value: "detektivnaya-fantastika", - }, - { label: "Жёсткая эротика", value: "zhyostkaya-erotika" }, - { label: "Исторический детектив", value: "istoricheskii-detektiv" }, - { - label: "Исторический любовный роман", - value: "istoricheskii-lyubovnyi-roman", - }, - { label: "Историческое фэнтези", value: "istoricheskoe-fentezi" }, - { label: "Киберпанк", value: "kiberpank" }, - { label: "Классический детектив", value: "klassicheskii-detektiv" }, - { - label: "Короткий любовный роман", - value: "korotkii-lyubovnyi-roman", - }, - { - label: "Космическая фантастика", - value: "kosmicheskaya-fantastika", - }, - { label: "Криминальный детектив", value: "kriminalnyi-detektiv" }, - { label: "ЛитРПГ", value: "litrpg" }, - { label: "Любовная фантастика", value: "lyubovnaya-fantastika" }, - { label: "Любовное фэнтези", value: "lyubovnoe-fentezi" }, - { label: "Любовный роман", value: "lyubovnyi-roman" }, - { label: "Мистика", value: "mistika" }, - { label: "Молодежная проза", value: "molodezhnaya-proza" }, - { label: "Научная фантастика", value: "nauchnaya-fantastika" }, - { - label: "Остросюжетный любовный роман", - value: "ostrosyuzhetnyi-lyubovnyi-roman", - }, - { label: "Политический детектив", value: "politicheskii-detektiv" }, - { label: "Попаданцы", value: "popadantsy" }, - { label: "Постапокалипсис", value: "postapokalipsis" }, - { - label: "Приключенческое фэнтези", - value: "priklyuchencheskoe-fentezi", - }, - { - label: "Романтическая эротика", - value: "romanticheskaya-erotika", - }, - { label: "С элементами эротики", value: "s-elementami-erotiki" }, - { label: "Славянское фэнтези", value: "slavyanskoe-fentezi" }, - { - label: "Современный любовный роман", - value: "sovremennyi-lyubovnyi-roman", - }, - { label: "Социальная фантастика", value: "sotsialnaya-fantastika" }, - { label: "Тёмное фэнтези", value: "temnoe-fentezi" }, - { label: "Фантастика", value: "fantastika" }, - { label: "Фэнтези", value: "fentezi" }, - { label: "Шпионский детектив", value: "shpionskii-detektiv" }, - { label: "Эпическое фэнтези", value: "epicheskoe-fentezi" }, - { label: "Эротика", value: "erotika" }, - { - label: "Эротическая фантастика", - value: "eroticheskaya-fantastika", - }, - { label: "Эротический фанфик", value: "eroticheskii-fanfik" }, - { label: "Эротическое фэнтези", value: "eroticheskoe-fentezi" }, - { - label: "Юмористический детектив", - value: "yumoristicheskii-detektiv", - }, - { - label: "Юмористическое фэнтези", - value: "yumoristicheskoe-fentezi", - }, - ], - inputType: filterInputs_1.FilterInputs.Checkbox, - }, -]; diff --git a/js/plugins/russian/ficbook.js b/js/plugins/russian/ficbook.js deleted file mode 100644 index 4ebdaba..0000000 --- a/js/plugins/russian/ficbook.js +++ /dev/null @@ -1,2596 +0,0 @@ -"use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.fetchImage = exports.filters = exports.searchNovels = exports.parseChapter = exports.parseNovelAndChapters = exports.popularNovels = exports.icon = exports.version = exports.site = exports.name = exports.id = void 0; -const filterInputs_1 = require("@libs/filterInputs"); -const fetch_1 = require("@libs/fetch"); -const novelStatus_1 = require("@libs/novelStatus"); -const cheerio_1 = require("cheerio"); -const defaultCover_1 = require("@libs/defaultCover"); -exports.id = "ficbook"; -exports.name = "ficbook"; -exports.site = "https://ficbook.net"; -exports.version = "1.0.0"; -exports.icon = "src/ru/ficbook/icon.png"; -const popularNovels = function (page, { filters }) { - return __awaiter(this, void 0, void 0, function* () { - let url = exports.site; - if (filters === null || filters === void 0 ? void 0 : filters.directions) { - url += "/popular-fanfics/" + filters.directions; - } - else if (filters === null || filters === void 0 ? void 0 : filters.tags) { - url += "/tags/" + filters.tags + "?p=" + page; - } - else { - url += "/" + ((filters === null || filters === void 0 ? void 0 : filters.sort) || "fanfiction") + "?p=" + page; - } - const result = yield (0, fetch_1.fetchApi)(url); - const body = yield result.text(); - const loadedCheerio = (0, cheerio_1.load)(body); - const novels = []; - loadedCheerio("article.fanfic-inline").each(function () { - const name = loadedCheerio(this).find("h3 > a").text().trim(); - let cover = loadedCheerio(this).find("picture > img").attr("src"); - const url = loadedCheerio(this).find("h3 > a").attr("href"); - cover = cover - ? cover.replace(/covers\/m_|covers\/d_/g, "covers/") - : defaultCover_1.defaultCover; - if (!name || !url) - return; - novels.push({ name, cover, url: exports.site + url.replace(/\?.*/g, "") }); - }); - return novels; - }); -}; -exports.popularNovels = popularNovels; -const parseNovelAndChapters = function (novelUrl) { - var _a; - return __awaiter(this, void 0, void 0, function* () { - const result = yield (0, fetch_1.fetchApi)(novelUrl); - const body = yield result.text(); - const loadedCheerio = (0, cheerio_1.load)(body); - const novel = { - url: novelUrl, - }; - novel.name = (loadedCheerio('h1[itemprop="headline"]').text() || - loadedCheerio('h1[itemprop="name"]').text()).trim(); - novel.cover = loadedCheerio('meta[property="og:image"]').attr("content"); - novel.summary = loadedCheerio('div[itemprop="description"]').text().trim(); - novel.author = loadedCheerio('a[itemprop="author"]').text(); - novel.status = - loadedCheerio("div.fanfic-main-info > section:nth-child(3) > div:nth-child(3) > span:nth-child(2)").text() === "В процессе" - ? novelStatus_1.NovelStatus.Ongoing - : novelStatus_1.NovelStatus.Completed; - const tags = loadedCheerio('div[class="tags"] > a') - .map((index, element) => loadedCheerio(element).text()) - .get(); - if (tags) { - novel.genres = tags.join(","); - } - if (!novel.cover || ((_a = novel.cover) === null || _a === void 0 ? void 0 : _a.includes("/design/"))) { - novel.cover = defaultCover_1.defaultCover; - } - else { - novel.cover = novel.cover.replace(/covers\/m_|covers\/d_/g, "covers/"); - } - const chapters = []; - if (loadedCheerio("#content").length == 1) { - const name = loadedCheerio(".title-area > h2").text(); - const releaseTime = loadedCheerio(".part-date > span").attr("title"); - if (name) - chapters.push({ name, releaseTime, url: novelUrl }); - } - else { - loadedCheerio("li.part").each(function () { - const name = loadedCheerio(this).find("h3").text(); - const releaseTime = loadedCheerio(this) - .find("div > span") - .attr("title"); - const url = loadedCheerio(this).find("a:nth-child(1)").attr("href"); - if (!name || !url) - return; - chapters.push({ name, releaseTime, url: exports.site + url }); - }); - } - novel.chapters = chapters; - return novel; - }); -}; -exports.parseNovelAndChapters = parseNovelAndChapters; -const parseChapter = function (chapterUrl) { - var _a, _b; - return __awaiter(this, void 0, void 0, function* () { - const result = yield (0, fetch_1.fetchApi)(chapterUrl); - const body = yield result.text(); - const loadedCheerio = (0, cheerio_1.load)(body); - let chapterText = ""; - (_b = (_a = loadedCheerio("#content").text()) === null || _a === void 0 ? void 0 : _a.split("\n")) === null || _b === void 0 ? void 0 : _b.forEach((line) => { - if (line.trim()) { - chapterText += "

" + line + "

"; - } - else { - chapterText += "
"; - } - }); - return chapterText; - }); -}; -exports.parseChapter = parseChapter; -const searchNovels = function (searchTerm) { - var _a, _b; - return __awaiter(this, void 0, void 0, function* () { - const formData = new FormData(); - formData.append("term", searchTerm); - formData.append("page", "1"); - const result = yield (0, fetch_1.fetchApi)(exports.site + "/search/fanfic", { - method: "POST", - body: formData, - }); - const json = (yield result.json()); - const novels = []; - (_b = (_a = json.data) === null || _a === void 0 ? void 0 : _a.data) === null || _b === void 0 ? void 0 : _b.forEach((novel) => { - const name = novel.title.trim(); - const url = exports.site + "/readfic/" + novel.slug; - const cover = novel.cover - ? "https://images.ficbook.net/fanfic-covers/" + novel.cover - : defaultCover_1.defaultCover; - novels.push({ name, cover, url }); - }); - return novels; - }); -}; -exports.searchNovels = searchNovels; -exports.filters = [ - { - key: "sort", - label: "Сортировка:", - values: [ - { label: "Горячие работы", value: "fanfiction" }, - { label: "Популярные ", value: "popular-fanfics" }, - ], - inputType: filterInputs_1.FilterInputs.Picker, - }, - { - key: "directions", - label: "Направление:", - values: [ - { label: "Джен", value: "gen" }, - { label: "Гет", value: "het" }, - { label: "Слэш", value: "slash-fics-3712917" }, - { label: "Фемслэш", value: "femslash-fanfics-9374932" }, - { label: "Статьи", value: "article" }, - { label: "Смешанный", value: "mixed" }, - { label: "Другой", value: "other" }, - ], - inputType: filterInputs_1.FilterInputs.Picker, - }, - { - key: "tags", - label: "Тэги:", - values: [ - { label: "#1fic1week", value: "884" }, - { label: "#7daystowrite", value: "2961" }, - { label: "#Бинго_ТФ", value: "1458" }, - { label: "#миниатюры3days", value: "2118" }, - { label: "#Не_Тайный_Санта", value: "2760" }, - { label: "#Писательские фанты-блиц", value: "2613" }, - { label: "#cosmowrite", value: "2284" }, - { label: "#femKHRweek", value: "2658" }, - { label: "#FourShips", value: "2588" }, - { label: "#Goretober", value: "1861" }, - { label: "#InternationalVampireDay / #WorldDraculaDay", value: "2048" }, - { label: "#KattWeek", value: "2717" }, - { label: "#Kinktober", value: "1867" }, - { label: "#LotorWeek", value: "2657" }, - { label: "#MerMay", value: "1122" }, - { label: "#NaNoWriMo", value: "1852" }, - { label: "#nsfweruriweek", value: "2944" }, - { label: "#RCMiaChallenge", value: "2700" }, - { label: "#SheithMonth", value: "2432" }, - { label: "#SixDrabbles", value: "2293" }, - { label: "#Writober", value: "1831" }, - { label: "1900-е годы", value: "369" }, - { label: "1910-е годы", value: "213" }, - { label: "1920-е годы", value: "81" }, - { label: "1930-е годы", value: "82" }, - { label: "1940-е годы", value: "83" }, - { label: "1950-е годы", value: "84" }, - { label: "1960-е годы", value: "85" }, - { label: "1970-е годы", value: "86" }, - { label: "1980-е годы", value: "87" }, - { label: "1990-е годы", value: "88" }, - { label: "2000-е годы", value: "590" }, - { label: "2010-е годы", value: "2562" }, - { label: "2014 год", value: "2977" }, - { label: "2P", value: "1910" }, - { label: "9 мая", value: "1019" }, - { label: "Аборт / Выкидыш", value: "306" }, - { label: "Аватары", value: "2401" }, - { label: "Авиатранспорт", value: "962" }, - { label: "Авиация", value: "455" }, - { label: "Аврорат", value: "1906" }, - { label: "Австралия", value: "767" }, - { label: "Австрия", value: "1024" }, - { label: "Автомастерские", value: "788" }, - { label: "Авторская пунктуация", value: "2886" }, - { label: "Авторские неологизмы", value: "1123" }, - { label: "Автоспорт", value: "856" }, - { label: "Автостоп", value: "1429" }, - { label: "Аддикции", value: "1230" }, - { label: "Адреналиновая зависимость", value: "1480" }, - { label: "Азартные игры", value: "1009" }, - { label: "Азкабан", value: "1922" }, - { label: "Аквакинез", value: "1380" }, - { label: "Аквапарки", value: "789" }, - { label: "Акростих", value: "911" }, - { label: "Актеры", value: "408" }, - { label: "Акустикофилия", value: "903" }, - { label: "Алекситимия", value: "2020" }, - { label: "Алкоголь", value: "201" }, - { label: "Алкогольные игры", value: "1534" }, - { label: "Аллергии", value: "746" }, - { label: "Алхимия", value: "1174" }, - { label: "Альбинизм", value: "1213" }, - { label: "Альпинизм", value: "1448" }, - { label: "Альтернативная мировая история", value: "442" }, - { label: "Альтернативное размножение", value: "2751" }, - { label: "Альтернативные судьбы", value: "2839" }, - { label: "Амазонки", value: "1424" }, - { label: "Амегакуре", value: "2571" }, - { label: "Американский футбол", value: "808" }, - { label: "Ампутация", value: "704" }, - { label: "Амфибии", value: "2792" }, - { label: "Анальгезия", value: "1254" }, - { label: "Анальный оргазм", value: "999" }, - { label: "Анальный секс", value: "215" }, - { label: "Анархия", value: "1175" }, - { label: "Анахронизмы", value: "780" }, - { label: "Ангелы", value: "91" }, - { label: "Ангелы-хранители", value: "1044" }, - { label: "Ангст", value: "1665" }, - { label: "Андрогинная внешность", value: "2602" }, - { label: "Андроиды", value: "155" }, - { label: "Анимагия", value: "2519" }, - { label: "Анимализм", value: "1443" }, - { label: "Аномальные зоны", value: "822" }, - { label: "Анонимный секс", value: "112" }, - { label: "Анрождение", value: "1246" }, - { label: "Антарктида", value: "2205" }, - { label: "Анти-Сью (Анти-Стью)", value: "1150" }, - { label: "Антигерои", value: "418" }, - { label: "Антизлодеи", value: "1833" }, - { label: "Антикварные магазины", value: "1496" }, - { label: "Антисоциальное расстройство личности", value: "734" }, - { label: "Антиутопия", value: "1700" }, - { label: "Античность", value: "237" }, - { label: "Апатия", value: "1850" }, - { label: "Аптеки", value: "1240" }, - { label: "Аргентина", value: "1146" }, - { label: "Арены", value: "940" }, - { label: "Аристократия", value: "16" }, - { label: "Арктика", value: "2426" }, - { label: "Армия", value: "22" }, - { label: "Аромантичные персонажи", value: "339" }, - { label: "Артефакты", value: "924" }, - { label: "Археологи", value: "405" }, - { label: "Архивы", value: "2594" }, - { label: "Архитекторы", value: "1011" }, - { label: "Асексофобия", value: "1120" }, - { label: "Асексуальные персонажи", value: "168" }, - { label: "Аскетизм", value: "606" }, - { label: "Асоциальность", value: "2019" }, - { label: "Ассистенты", value: "2641" }, - { label: "Астма", value: "1121" }, - { label: "Астральное проецирование", value: "2530" }, - { label: "Астральные миры", value: "1379" }, - { label: "Астрология", value: "476" }, - { label: "Астронавты", value: "2220" }, - { label: "Астрономия", value: "1372" }, - { label: "Асфиксия", value: "104" }, - { label: "Атеисты", value: "669" }, - { label: "Атлантида", value: "1144" }, - { label: "Атмокинез", value: "1964" }, - { label: "Атмосферная зарисовка", value: "2802" }, - { label: "Атомные электростанции", value: "2192" }, - { label: "Аудиокинез", value: "2849" }, - { label: "Аукционы", value: "607" }, - { label: "Аутоассасинофилия", value: "2025" }, - { label: "Аутоканнибализм", value: "2593" }, - { label: "Аутофелляция / Аутокуннилингус", value: "610" }, - { label: "Африка", value: "791" }, - { label: "Афродизиаки", value: "103" }, - { label: "Аффект", value: "938" }, - { label: "Аэрокинез", value: "2850" }, - { label: "Байкеры", value: "522" }, - { label: "Байронические герои", value: "2900" }, - { label: "Балет", value: "404" }, - { label: "Баллада", value: "2318" }, - { label: "Банки / Биржи", value: "937" }, - { label: "Банши", value: "250" }, - { label: "Барти Крауч-младший — не Пожиратель Смерти", value: "2795" }, - { label: "Бары", value: "142" }, - { label: "Баскетбол", value: "829" }, - { label: "Баски", value: "1763" }, - { label: "Бастарды", value: "603" }, - { label: "Батохаки", value: "2830" }, - { label: "Бедность", value: "979" }, - { label: "Без Волдеморта", value: "2160" }, - { label: "Без диалогов (стилизация)", value: "2885" }, - { label: "Без золотого трио", value: "2648" }, - { label: "Без Избранного (Гарри Поттер)", value: "2762" }, - { label: "Без канонических персонажей", value: "2694" }, - { label: "Без Таноса", value: "2381" }, - { label: "БезГражданки", value: "2418" }, - { label: "Бездомные", value: "916" }, - { label: "Безответственность", value: "2152" }, - { label: "Безумные ученые", value: "2559" }, - { label: "Безэмоциональность", value: "1488" }, - { label: "Бейсбол", value: "1489" }, - { label: "Беларусь", value: "1030" }, - { label: "Белый день", value: "683" }, - { label: "Белый стих", value: "1998" }, - { label: "Бельгия", value: "1039" }, - { label: "Беременность", value: "1712" }, - { label: "Бермудский треугольник", value: "1158" }, - { label: "Берсерки", value: "566" }, - { label: "Бесконтактный секс", value: "2214" }, - { label: "Бесплодие", value: "719" }, - { label: "Беспокойство", value: "2888" }, - { label: "Беспризорники", value: "604" }, - { label: "Беспричудный Изуку", value: "2422" }, - { label: "Бессмертие", value: "219" }, - { label: "Бессмертный конкурс 2023", value: "3016" }, - { label: "Бестелесность", value: "2607" }, - { label: "Би-персонажи", value: "300" }, - { label: "Библейские темы и мотивы", value: "1468" }, - { label: "Библиотекари", value: "2631" }, - { label: "Библиотеки", value: "310" }, - { label: "Бизнесмены / Бизнесвумен", value: "573" }, - { label: "Биологическое оружие", value: "1188" }, - { label: "Биопанк", value: "281" }, - { label: "Биороботы", value: "2256" }, - { label: "Биполярное расстройство", value: "690" }, - { label: "Битва за Хогвартс", value: "2774" }, - { label: "Битва Историй", value: "2960" }, - { label: "Благородные разбойники", value: "952" }, - { label: "Благотворительность", value: "613" }, - { label: "Бладплей", value: "109" }, - { label: "Ближний Восток", value: "1041" }, - { label: "Близкие враги", value: "721" }, - { label: "Близнецы", value: "295" }, - { label: "Блиц-свидания", value: "2511" }, - { label: "Блогеры", value: "1471" }, - { label: "Блокадный Ленинград", value: "1111" }, - { label: "Блэкигуд", value: "2905" }, - { label: "Богачи", value: "1549" }, - { label: "Боги / Божественные сущности", value: "149" }, - { label: "Боди-арт", value: "2260" }, - { label: "Бодипозитив", value: "1153" }, - { label: "Боевая пара", value: "1919" }, - { label: "Боевые искусства", value: "918" }, - { label: "Бои без правил", value: "1390" }, - { label: "Бокс", value: "765" }, - { label: "Болгария", value: "1786" }, - { label: "Болезнь Альцгеймера", value: "2533" }, - { label: "Боль", value: "1803" }, - { label: "Больницы", value: "20" }, - { label: "Большая Игра профессора Дамблдора", value: "2890" }, - { label: "Бордели", value: "120" }, - { label: "Борьба за власть", value: "2300" }, - { label: "Борьба за отношения", value: "1251" }, - { label: "Борьба за справедливость", value: "2335" }, - { label: "Боязнь боли", value: "2441" }, - { label: "Боязнь воды", value: "1084" }, - { label: "Боязнь врачей", value: "2063" }, - { label: "Боязнь высоты", value: "1085" }, - { label: "Боязнь грозы", value: "1124" }, - { label: "Боязнь громких звуков", value: "1090" }, - { label: "Боязнь грязи", value: "1277" }, - { label: "Боязнь замкнутых пространств", value: "821" }, - { label: "Боязнь зеркал", value: "2739" }, - { label: "Боязнь клоунов", value: "2970" }, - { label: "Боязнь крови", value: "1312" }, - { label: "Боязнь людей", value: "1082" }, - { label: "Боязнь мужчин", value: "1264" }, - { label: "Боязнь насекомых / Боязнь пауков", value: "1119" }, - { label: "Боязнь неудачи", value: "2713" }, - { label: "Боязнь огня", value: "1258" }, - { label: "Боязнь одиночества", value: "1491" }, - { label: "Боязнь открытых пространств", value: "965" }, - { label: "Боязнь привязанности", value: "1343" }, - { label: "Боязнь призраков", value: "2770" }, - { label: "Боязнь прикосновений", value: "823" }, - { label: "Боязнь сексуальных домогательств", value: "2319" }, - { label: "Боязнь смерти", value: "1515" }, - { label: "Боязнь сна", value: "2262" }, - { label: "Боязнь темноты", value: "1494" }, - { label: "Боязнь тишины", value: "2233" }, - { label: "Бразилия", value: "833" }, - { label: "Брак по договоренности", value: "35" }, - { label: "Брак по расчету", value: "303" }, - { label: "БРД", value: "2907" }, - { label: "Бродячие артисты", value: "2661" }, - { label: "Бродячие певцы", value: "1497" }, - { label: "Броманс", value: "171" }, - { label: "Будущее", value: "227" }, - { label: "Буллёзный эпидермолиз", value: "2725" }, - { label: "Буллинг", value: "436" }, - { label: "Бухгалтеры", value: "2509" }, - { label: "Буч и фэм", value: "486" }, - { label: "Бывшие", value: "311" }, - { label: "Бывшие враги", value: "2812" }, - { label: "Бывшие серийные убийцы", value: "2498" }, - { label: "Бытовое фэнтези", value: "2702" }, - { label: "В одном теле", value: "1425" }, - { label: "В поисках отношений", value: "1576" }, - { label: "В. А. О. Н.", value: "2377" }, - { label: "Вагинальный секс", value: "395" }, - { label: "Ваканда", value: "2668" }, - { label: "Валькирии", value: "557" }, - { label: "Вампиры", value: "27" }, - { label: "Василиски", value: "863" }, - { label: "Вдовство", value: "2030" }, - { label: "Вебкам-модели", value: "2299" }, - { label: "Вегетарианцы / Веганы", value: "577" }, - { label: "Ведьмы / Колдуны", value: "33" }, - { label: "Великая депрессия", value: "2224" }, - { label: "Великая французская революция", value: "2000" }, - { label: "Великобритания", value: "673" }, - { label: "Великое Княжество Литовское", value: "2587" }, - { label: "Великолепный мерзавец", value: "1244" }, - { label: "Велоспорт", value: "2978" }, - { label: "Венгрия", value: "1432" }, - { label: "Вендиго", value: "251" }, - { label: "Верность", value: "459" }, - { label: "Вертикальный инцест", value: "337" }, - { label: "Вестерн", value: "2329" }, - { label: "Ветераны", value: "555" }, - { label: "Ветеринары", value: "629" }, - { label: "Вечеринки", value: "854" }, - { label: "Вечная молодость", value: "2405" }, - { label: "Вещие сны", value: "1993" }, - { label: "Взаимопонимание", value: "2887" }, - { label: "Взросление", value: "909" }, - { label: "Вигиланты", value: "1514" }, - { label: "Видеоигры", value: "2508" }, - { label: "Визажисты / Гримеры", value: "1801" }, - { label: "Викинги", value: "676" }, - { label: "Виктимблейминг", value: "331" }, - { label: "Викторианская эпоха", value: "469" }, - { label: "Виртуальная реальность", value: "803" }, - { label: "Виртуальный секс", value: "268" }, - { label: "Витилиго", value: "1167" }, - { label: "Вице-королевство Новая Испания", value: "2603" }, - { label: "ВИЧ / СПИД", value: "542" }, - { label: "Влюбленность", value: "1303" }, - { label: "Вне закона", value: "1089" }, - { label: "Внутренний сексизм", value: "2155" }, - { label: "Внутренняя гомофобия", value: "2154" }, - { label: "Внутренняя трансфобия", value: "2716" }, - { label: "Водители / Шоферы", value: "879" }, - { label: "Военные", value: "313" }, - { label: "Военные городки", value: "2095" }, - { label: "Военные преступления", value: "2356" }, - { label: "Возвращение", value: "1522" }, - { label: "Возвращение Артура", value: "2570" }, - { label: "Воздержание", value: "921" }, - { label: "Воздушная атлетика", value: "2811" }, - { label: "Война", value: "232" }, - { label: "Война в Афганистане", value: "1050" }, - { label: "Война во Вьетнаме", value: "1332" }, - { label: "Война за независимость США", value: "2065" }, - { label: "Война миров", value: "1222" }, - { label: "Волдигуд", value: "1874" }, - { label: "Волейбол", value: "1095" }, - { label: "Волк в овечьей шкуре", value: "2228" }, - { label: "Волонтеры", value: "900" }, - { label: "Волшебники / Волшебницы", value: "93" }, - { label: "Воображаемые друзья", value: "738" }, - { label: "Ворарефилия", value: "157" }, - { label: "Воры", value: "320" }, - { label: "Воскрешение", value: "256" }, - { label: "Воспоминания", value: "1118" }, - { label: "Воссоединение", value: "498" }, - { label: "Восстание машин", value: "817" }, - { label: "Восточное побережье", value: "770" }, - { label: "Восьмое марта", value: "493" }, - { label: "Вражда", value: "681" }, - { label: "Вражда семей", value: "2867" }, - { label: "Врачи", value: "374" }, - { label: "Времена Мародеров", value: "1872" }, - { label: "Времена Основателей", value: "1891" }, - { label: "Временная смерть персонажа", value: "439" }, - { label: "Временное бессмертие", value: "2755" }, - { label: "Временное воскрешение персонажей", value: "2649" }, - { label: "Временные петли", value: "147" }, - { label: "Временные превращения", value: "927" }, - { label: "Врожденные заболевания", value: "1781" }, - { label: "Всадники Апокалипсиса", value: "1326" }, - { label: "Все живы / Никто не умер", value: "535" }, - { label: "Все за Одного — отец Изуку", value: "2421" }, - { label: "Всезнающий рассказчик", value: "1368" }, - { label: "Вселение в тело", value: "1181" }, - { label: "Вторая мировая", value: "488" }, - { label: "Вторжение пришельцев", value: "755" }, - { label: "Вторичный стыд", value: "1393" }, - { label: "Второй шанс", value: "1799" }, - { label: "Второстепенные оригинальные персонажи", value: "1536" }, - { label: "Вуайеризм", value: "174" }, - { label: "Вуду", value: "678" }, - { label: "Выбор", value: "2808" }, - { label: "Выгорание", value: "2914" }, - { label: "Выживание", value: "216" }, - { label: "Вымирающий вид", value: "2373" }, - { label: "Вымышленная анатомия", value: "1317" }, - { label: "Вымышленная география", value: "1294" }, - { label: "Вымышленная религия", value: "2062" }, - { label: "Вымышленная физика", value: "2132" }, - { label: "Вымышленные виды спорта", value: "1777" }, - { label: "Вымышленные заболевания", value: "1295" }, - { label: "Вымышленные науки", value: "1333" }, - { label: "Вымышленные праздники", value: "1769" }, - { label: "Вымышленные профессии", value: "1391" }, - { label: "Вымышленные существа", value: "1685" }, - { label: "Вымышленные языки", value: "536" }, - { label: "Выпускные", value: "717" }, - { label: "Высшее общество", value: "1093" }, - { label: "Высшие учебные заведения", value: "97" }, - { label: "Выученная беспомощность", value: "2772" }, - { label: "Выхаживание", value: "511" }, - { label: "Выход из нездоровых отношений", value: "2891" }, - { label: "Гадалки / Ясновидящие", value: "2662" }, - { label: "Гадкий утенок", value: "1225" }, - { label: "Газлайтинг", value: "1418" }, - { label: "Галлюцинации / Иллюзии", value: "365" }, - { label: "Гаремник", value: "50" }, - { label: "Гаремы", value: "115" }, - { label: "Гарпии", value: "1482" }, - { label: "Гарри Поттер и Драко Малфой — друзья", value: "1923" }, - { label: "Гастроли", value: "2487" }, - { label: "Гедонизм", value: "736" }, - { label: "Гей-клубы", value: "2482" }, - { label: "Геймеры", value: "356" }, - { label: "Геймлит", value: "23" }, - { label: "Гейши / Кисэн", value: "332" }, - { label: "Гемофилия", value: "1341" }, - { label: "Гендерная дисфория", value: "431" }, - { label: "Гендерная интрига", value: "55" }, - { label: "Гендерное неравенство", value: "2568" }, - { label: "Гендерный нонконформизм", value: "1417" }, - { label: "Гендерсвап", value: "1691" }, - { label: "Генетика / Эволюция", value: "2131" }, - { label: "Гении", value: "445" }, - { label: "Генитальные пытки", value: "2104" }, - { label: "Геноцид", value: "720" }, - { label: "Геокинез", value: "2889" }, - { label: "Геологи / Географы", value: "934" }, - { label: "Германия", value: "688" }, - { label: "Германия — не Священная Римская Империя", value: "2470" }, - { label: "Герой поневоле", value: "2145" }, - { label: "Геронтофилия", value: "162" }, - { label: "Гетерохромия", value: "1210" }, - { label: "Гетто", value: "1783" }, - { label: "Гибристофилия", value: "1843" }, - { label: "Гиганты", value: "735" }, - { label: "Гидра трэш-пати", value: "2804" }, - { label: "Гики", value: "482" }, - { label: "Гильдии", value: "957" }, - { label: "Гимнастика", value: "1974" }, - { label: "Гиперакузия", value: "2866" }, - { label: "Гиперсексуальность", value: "945" }, - { label: "Гипноз", value: "700" }, - { label: "Гладиаторы", value: "677" }, - { label: "Глобальные катастрофы", value: "525" }, - { label: "Глухота", value: "595" }, - { label: "Гнев", value: "2806" }, - { label: "Гнездование", value: "1452" }, - { label: "Гномы", value: "138" }, - { label: "Гоблины", value: "188" }, - { label: "Големы", value: "1208" }, - { label: "Голод", value: "868" }, - { label: "Голодные Фэндомные Игры", value: "2895" }, - { label: "Гомофобия", value: "428" }, - { label: "Гомункулы", value: "1366" }, - { label: "Горе / Утрата", value: "1113" }, - { label: "Горизонтальный инцест", value: "338" }, - { label: "Городские легенды", value: "1832" }, - { label: "Горы", value: "702" }, - { label: "Горячие источники", value: "2813" }, - { label: "Гостевой брак", value: "1354" }, - { label: "Гостиницы", value: "384" }, - { label: "Готический роман", value: "963" }, - { label: "Готы", value: "575" }, - { label: "Гравиокинез", value: "1985" }, - { label: "Гражданская война", value: "370" }, - { label: "Гражданская война в России", value: "1282" }, - { label: "Гражданская война в США", value: "1018" }, - { label: "Графичные описания", value: "2854" }, - { label: "Грейнджергад", value: "1892" }, - { label: "Грейромантичные персонажи", value: "707" }, - { label: "Гремлины", value: "189" }, - { label: "Греция", value: "1040" }, - { label: "Грифоны", value: "335" }, - { label: "Громкий секс", value: "1184" }, - { label: "Грубый секс", value: "121" }, - { label: "Грудное кормление", value: "296" }, - { label: "Групи", value: "2925" }, - { label: "Групповое изнасилование", value: "2203" }, - { label: "Групповой секс", value: "1654" }, - { label: "Грязный реализм", value: "634" }, - { label: "Гувернантки", value: "1179" }, - { label: "Гули", value: "367" }, - { label: "Гэвин Рид — андроид", value: "2692" }, - { label: "Даб-кон", value: "57" }, - { label: "Даби — не Тойя Тодороки", value: "2821" }, - { label: "Даби — Тойя Тодороки", value: "2423" }, - { label: "Дадзава", value: "2915" }, - { label: "Дадмайт", value: "2917" }, - { label: "Дайверы", value: "939" }, - { label: "Дайвинг", value: "2823" }, - { label: "Дама в беде", value: "1259" }, - { label: "Дамбигад", value: "1863" }, - { label: "Дамбигуд", value: "1873" }, - { label: "Дампиры", value: "2860" }, - { label: "Дандэрэ", value: "1364" }, - { label: "Дарк", value: "1678" }, - { label: "Даркнет", value: "1287" }, - { label: "Дачи", value: "930" }, - { label: "Двойники", value: "305" }, - { label: "Двойное проникновение", value: "107" }, - { label: "Двойной кноттинг", value: "2619" }, - { label: "Двойные агенты", value: "441" }, - { label: "Дворцовые интриги", value: "2075" }, - { label: "Девиантное поведение", value: "1814" }, - { label: "Девичники / Мальчишники", value: "1191" }, - { label: "Девочки из Эквестрии", value: "2912" }, - { label: "Дежавю", value: "2049" }, - { label: "Декаданс", value: "2353" }, - { label: "Деконструкция", value: "1322" }, - { label: "Деми-персонажи", value: "723" }, - { label: "Демиурги", value: "819" }, - { label: "Демонология", value: "2485" }, - { label: "Демоны", value: "73" }, - { label: "Демоны-хранители", value: "2045" }, - { label: "Дендрофилия", value: "491" }, - { label: "День благодарения", value: "754" }, - { label: "День знаний", value: "1075" }, - { label: "День матери", value: "2979" }, - { label: "День мертвых", value: "1074" }, - { label: "День независимости США", value: "1008" }, - { label: "День рождения", value: "298" }, - { label: "День святого Валентина", value: "204" }, - { label: "День святого Патрика", value: "1129" }, - { label: "День смерти", value: "2251" }, - { label: "День учителя", value: "1076" }, - { label: "Деперсонализация", value: "1197" }, - { label: "Депрессия", value: "354" }, - { label: "Депривация сна", value: "551" }, - { label: "Дереализация", value: "1198" }, - { label: "Деревни", value: "364" }, - { label: "Дерматозойный бред", value: "2779" }, - { label: "Деспоты / Тираны", value: "1345" }, - { label: "Детектив", value: "1672" }, - { label: "Дети", value: "217" }, - { label: "Детоненавистничество", value: "1836" }, - { label: "Детская влюбленность", value: "186" }, - { label: "Детские дома", value: "355" }, - { label: "Детские лагеря", value: "222" }, - { label: "Детские сады", value: "567" }, - { label: "Дефекты зрения", value: "2639" }, - { label: "Дефекты речи", value: "737" }, - { label: "Джинны / Пери", value: "456" }, - { label: "Джон Ватсон — преступник", value: "1932" }, - { label: "Джуманджи — не игровой мир", value: "2799" }, - { label: "Диабет", value: "820" }, - { label: "Диалоги (стилизация)", value: "1139" }, - { label: "Дизайнеры", value: "1875" }, - { label: "Дизельпанк", value: "294" }, - { label: "Дикие животные", value: "622" }, - { label: "Дикий Запад", value: "293" }, - { label: "Дилетанты", value: "2443" }, - { label: "Динозавры", value: "670" }, - { label: "Дипломатия", value: "1790" }, - { label: "Дисбаланс власти", value: "732" }, - { label: "Дискриминация", value: "2230" }, - { label: "Дискриминация по внешности", value: "1414" }, - { label: "Дискриминация по возрасту", value: "2843" }, - { label: "Дислексия", value: "860" }, - { label: "Дисморфофобия", value: "1108" }, - { label: "Диссоциативное расстройство идентичности", value: "2127" }, - { label: "Дистанционное обучение", value: "2592" }, - { label: "Дисфункциональные семьи", value: "602" }, - { label: "Дневники (стилизация)", value: "214" }, - { label: "Добрый Сальери", value: "2522" }, - { label: "Доверие", value: "1117" }, - { label: "Договоры / Сделки", value: "2137" }, - { label: "Документы / Отчеты (стилизация)", value: "752" }, - { label: "Долголетие", value: "2130" }, - { label: "Домашнее насилие", value: "42" }, - { label: "Домашние животные", value: "517" }, - { label: "Домашний арест", value: "2526" }, - { label: "Домашний ремонт", value: "867" }, - { label: "Домовые", value: "1423" }, - { label: "Допросы", value: "2654" }, - { label: "Дорожное приключение", value: "47" }, - { label: "Драббл", value: "2935" }, - { label: "Драки", value: "1367" }, - { label: "Драконы", value: "43" }, - { label: "Драма", value: "1668" }, - { label: "Драуги", value: "2264" }, - { label: "Древний Восток", value: "1940" }, - { label: "Древний Египет", value: "474" }, - { label: "Древний Китай", value: "1438" }, - { label: "Древняя Русь", value: "466" }, - { label: "Дремлющее зло", value: "2719" }, - { label: "Дремлющие способности", value: "2084" }, - { label: "Другая магическая школа", value: "1864" }, - { label: "Другие планеты", value: "1415" }, - { label: "Другой избранный", value: "2054" }, - { label: "Другой факультет", value: "1866" }, - { label: "Дружба", value: "1701" }, - { label: "Дружба втайне", value: "2303" }, - { label: "Дружба по расчету", value: "2331" }, - { label: "Друзья детства", value: "343" }, - { label: "Друзья по переписке", value: "1466" }, - { label: "Друзья поневоле", value: "627" }, - { label: "Друзья с привилегиями", value: "113" }, - { label: "Друиды", value: "1199" }, - { label: "Дрэг (субкультура)", value: "1248" }, - { label: "Дурмстранг", value: "2389" }, - { label: "Дурслигуд", value: "2058" }, - { label: "Духи природы", value: "503" }, - { label: "Духовенство", value: "478" }, - { label: "Духовная связь", value: "2090" }, - { label: "Духокинез", value: "2500" }, - { label: "Дуэли", value: "446" }, - { label: "Дьяволы", value: "2369" }, - { label: "Дэдди-кинк", value: "165" }, - { label: "Еда / Кулинария", value: "1195" }, - { label: "Единороги", value: "373" }, - { label: "Ёкаи", value: "416" }, - { label: "Естественные враги", value: "728" }, - { label: "Жамевю", value: "2050" }, - { label: "Жаргон", value: "1016" }, - { label: "Ждун Фест", value: "2936" }, - { label: "Железнодорожники", value: "2680" }, - { label: "Железные дороги", value: "811" }, - { label: "Женская дружба", value: "2156" }, - { label: "Жертвы обстоятельств", value: "1475" }, - { label: "Жестокое обращение с животными", value: "722" }, - { label: "Жестокость", value: "1710" }, - { label: "Живой сосуд", value: "2072" }, - { label: "Животные-компаньоны", value: "2371" }, - { label: "Живые машины", value: "961" }, - { label: "ЖиП", value: "143" }, - { label: "Журналисты", value: "438" }, - { label: "Заболевания", value: "1268" }, - { label: "Заболевания крови", value: "2254" }, - { label: "Заболевания сердца", value: "1767" }, - { label: "Забота / Поддержка", value: "1302" }, - { label: "Заброшенные города", value: "1276" }, - { label: "Заброшенные здания", value: "1483" }, - { label: "Забытый герой", value: "2337" }, - { label: "Завещание", value: "1262" }, - { label: "Зависимое расстройство личности", value: "2349" }, - { label: "Зависть", value: "990" }, - { label: "Завоевание", value: "978" }, - { label: "Загробный мир", value: "275" }, - { label: "Закавказье", value: "2819" }, - { label: "Заклятые друзья", value: "1316" }, - { label: "Закрытые города", value: "1481" }, - { label: "Закрытые учебные заведения", value: "98" }, - { label: "Закрытый детектив", value: "2616" }, - { label: "Заложники", value: "845" }, - { label: "Замки", value: "654" }, - { label: "Замкнутое пространство", value: "2306" }, - { label: "Замкнутый мир", value: "874" }, - { label: "Занавесочная история", value: "1688" }, - { label: "Запахи", value: "1385" }, - { label: "Заповедники", value: "618" }, - { label: "Запредельно одаренный персонаж", value: "1241" }, - { label: "Запрет на магию", value: "2663" }, - { label: "Запретные отношения", value: "362" }, - { label: "Засосы / Укусы", value: "913" }, - { label: "Застенчивость", value: "2807" }, - { label: "Затворники", value: "1059" }, - { label: "Затерянные миры", value: "2448" }, - { label: "Защита любимого", value: "2492" }, - { label: "Защитники природы", value: "628" }, - { label: "Защищенный секс", value: "636" }, - { label: "Звездные слезы", value: "2971" }, - { label: "Здоровые механизмы преодоления", value: "2147" }, - { label: "Здоровые отношения", value: "1853" }, - { label: "Зеркала", value: "724" }, - { label: "Зимняя Фандомная Битва", value: "254" }, - { label: "Злобные бывшие", value: "518" }, - { label: "Зловещая находка", value: "2275" }, - { label: "Знаки зодиака", value: "643" }, - { label: "Знаменитости", value: "1360" }, - { label: "Золотая клетка", value: "480" }, - { label: "Золотая молодежь", value: "796" }, - { label: "Золотая Орда", value: "1143" }, - { label: "Золушка", value: "1226" }, - { label: "Зомби", value: "31" }, - { label: "Зоопарки", value: "792" }, - { label: "Зоофилия", value: "1662" }, - { label: "Зоофобии", value: "2715" }, - { label: "ЗППП", value: "630" }, - { label: "ЗПР", value: "2259" }, - { label: "Зрелые персонажи", value: "851" }, - { label: "Иван Купала", value: "1068" }, - { label: "Игровое расстройство", value: "949" }, - { label: "Игрушки", value: "1346" }, - { label: "Игры на выживание", value: "554" }, - { label: "Игры на раздевание", value: "1535" }, - { label: "Игры с сосками", value: "423" }, - { label: "Игры с температурой", value: "230" }, - { label: "Идеализация", value: "1540" }, - { label: "Иерархический строй", value: "652" }, - { label: "Избранные", value: "847" }, - { label: "Избыточный физиологизм", value: "2334" }, - { label: "Изгнанники", value: "871" }, - { label: "Измена", value: "62" }, - { label: "Измененное состояние сознания", value: "2242" }, - { label: "Изменились за лето", value: "1908" }, - { label: "Изнасилование", value: "1650" }, - { label: "Изоляция", value: "1296" }, - { label: "Израиль", value: "1094" }, - { label: "Изуку Мидория — злодей", value: "2472" }, - { label: "Иллюзионисты", value: "532" }, - { label: "Имейджин", value: "838" }, - { label: "Импотенция", value: "632" }, - { label: "Импринтинг", value: "635" }, - { label: "Импрореал", value: "2955" }, - { label: "Импрофест", value: "2947" }, - { label: "Имя вместо цвета", value: "2919" }, - { label: "Инвалидность", value: "197" }, - { label: "Индия", value: "1002" }, - { label: "Инквизиция", value: "1130" }, - { label: "Инопланетяне", value: "58" }, - { label: "Инсектоиды / Арахноиды", value: "953" }, - { label: "Инсектофилия / Арахнофилия", value: "664" }, - { label: "Инсценированная смерть персонажа", value: "440" }, - { label: "Интерактивная работа", value: "419" }, - { label: "Интервью (стилизация)", value: "2446" }, - { label: "Интернет", value: "1286" }, - { label: "Интерсекс-персонажи", value: "299" }, - { label: "Интрамаммарный секс", value: "840" }, - { label: "Инфантильность", value: "1300" }, - { label: "Инцест", value: "1651" }, - { label: "Ипохондрия", value: "2178" }, - { label: "Ирландия", value: "1035" }, - { label: "Иронический детектив", value: "2638" }, - { label: "Искра Стайлз Стилински", value: "1975" }, - { label: "Искупление", value: "877" }, - { label: "Искусственно вызванные чувства", value: "626" }, - { label: "Искусственные интеллекты", value: "150" }, - { label: "Искусственные существа", value: "2277" }, - { label: "Искусство", value: "2257" }, - { label: "Искусствоведы", value: "2873" }, - { label: "Искушение", value: "776" }, - { label: "Испания", value: "1020" }, - { label: "Исповеди", value: "1342" }, - { label: "Исправительные лагеря", value: "2439" }, - { label: "Истинные", value: "1855" }, - { label: "Историческая Хеталия", value: "1865" }, - { label: "Исторические эпохи", value: "1698" }, - { label: "Исторический Кантриболс", value: "2913" }, - { label: "Историческое допущение", value: "2681" }, - { label: "Исцеление", value: "802" }, - { label: "Италия", value: "1003" }, - { label: "Ихтиоморфы", value: "972" }, - { label: "Йога", value: "483" }, - { label: "Йоль", value: "2143" }, - { label: "Кабаре", value: "457" }, - { label: "Кабэ-дон", value: "2626" }, - { label: "Казахстан", value: "1260" }, - { label: "Казино", value: "620" }, - { label: "Казнь", value: "548" }, - { label: "Как ориджинал", value: "1032" }, - { label: "Каламбуры", value: "881" }, - { label: "Каминг-аут", value: "559" }, - { label: "Канада", value: "695" }, - { label: "Каникулы", value: "805" }, - { label: "Каннибализм", value: "1706" }, - { label: "Канонная смерть персонажа", value: "564" }, - { label: "Капитан Гидра", value: "1928" }, - { label: "Карантинные зоны", value: "1290" }, - { label: "Карантины", value: "2734" }, - { label: "Караоке", value: "886" }, - { label: "Карательная психиатрия", value: "730" }, - { label: "Карибский бассейн", value: "1172" }, - { label: "Карма", value: "647" }, - { label: "Карьеризм", value: "956" }, - { label: "Каскадеры", value: "2267" }, - { label: "Катарсис", value: "824" }, - { label: "Кафе / Кофейни / Чайные", value: "13" }, - { label: "Квай-Гад", value: "2894" }, - { label: "Квантовая физика", value: "2744" }, - { label: "Квисины", value: "2722" }, - { label: "Кемономими", value: "997" }, - { label: "Кемпинг", value: "182" }, - { label: "Кентавры", value: "64" }, - { label: "Кибербуллинг", value: "1858" }, - { label: "Киберпанк", value: "24" }, - { label: "Киберспорт", value: "745" }, - { label: "Кибертрон", value: "2775" }, - { label: "Киборги", value: "154" }, - { label: "Киевская Русь", value: "515" }, - { label: "Кинк на беременность", value: "2281" }, - { label: "Кинк на волосы", value: "2089" }, - { label: "Кинк на волосы на теле", value: "1337" }, - { label: "Кинк на девственность", value: "2282" }, - { label: "Кинк на инвалидность", value: "633" }, - { label: "Кинк на интеллект", value: "2798" }, - { label: "Кинк на клыки", value: "2325" }, - { label: "Кинк на колготки", value: "2644" }, - { label: "Кинк на крылья", value: "2035" }, - { label: "Кинк на латекс", value: "134" }, - { label: "Кинк на мольбы", value: "1543" }, - { label: "Кинк на наручники", value: "1065" }, - { label: "Кинк на нижнее белье", value: "145" }, - { label: "Кинк на очки", value: "1723" }, - { label: "Кинк на ошейники", value: "388" }, - { label: "Кинк на полноту", value: "552" }, - { label: "Кинк на похвалу", value: "1042" }, - { label: "Кинк на протезы", value: "2682" }, - { label: "Кинк на рога", value: "2320" }, - { label: "Кинк на руки", value: "915" }, - { label: "Кинк на сердцебиение", value: "941" }, - { label: "Кинк на силу", value: "1476" }, - { label: "Кинк на слезы", value: "1373" }, - { label: "Кинк на служение", value: "2980" }, - { label: "Кинк на страх", value: "2246" }, - { label: "Кинк на стыд", value: "747" }, - { label: "Кинк на унижение", value: "2291" }, - { label: "Кинк на униформу", value: "1350" }, - { label: "Кинк на уши", value: "2370" }, - { label: "Кинк на формальную одежду", value: "1064" }, - { label: "Кинк на чужую одежду", value: "2920" }, - { label: "Кинк на чулки", value: "810" }, - { label: "Кинк на шрамы", value: "2831" }, - { label: "Кинк на щекотку", value: "2396" }, - { label: "Кинк-бинго", value: "2290" }, - { label: "Кинки / Фетиши", value: "1659" }, - { label: "Кинотеатры", value: "981" }, - { label: "Киригакуре", value: "2475" }, - { label: "Китай", value: "757" }, - { label: "Кладбища", value: "501" }, - { label: "Кланы", value: "2879" }, - { label: "Классизм", value: "1927" }, - { label: "Клейма", value: "1548" }, - { label: "Клептомания", value: "1160" }, - { label: "Клетка Люцифера", value: "1884" }, - { label: "Клетки", value: "1069" }, - { label: "Клиническая смерть", value: "2068" }, - { label: "Клокпанк / Ветропанк", value: "1812" }, - { label: "Клоны", value: "358" }, - { label: "Клоуны", value: "1520" }, - { label: "Клубы по интересам", value: "1369" }, - { label: "Клюква", value: "1001" }, - { label: "Кляпы / Затыкание рта", value: "379" }, - { label: "Книги", value: "2746" }, - { label: "Книжные магазины", value: "444" }, - { label: "Кноттинг", value: "99" }, - { label: "Ковбои", value: "330" }, - { label: "Кода", value: "1943" }, - { label: "Кожаная одежда", value: "1517" }, - { label: "Колдовстворец", value: "2600" }, - { label: "Кома", value: "516" }, - { label: "Командная работа", value: "708" }, - { label: "Комики", value: "1315" }, - { label: "Комиксисты / Мангаки", value: "576" }, - { label: "Коммунальные квартиры", value: "1437" }, - { label: "Коммуны", value: "797" }, - { label: "Комнатные растения", value: "1792" }, - { label: "Комплекс Бога", value: "2087" }, - { label: "Комплекс превосходства", value: "2191" }, - { label: "Комплексы", value: "2529" }, - { label: "Конкурс от BUBBLE", value: "2937" }, - { label: "Конный спорт", value: "1378" }, - { label: "Конохагакуре", value: "2477" }, - { label: "Конспирология", value: "1911" }, - { label: "Контрабандисты", value: "2363" }, - { label: "Контроль / Подчинение", value: "932" }, - { label: "Контроль памяти", value: "2540" }, - { label: "Контроль сознания", value: "257" }, - { label: "Конфликт мировоззрений", value: "2678" }, - { label: "Концентрационные лагеря", value: "547" }, - { label: "Концерты / Выступления", value: "1236" }, - { label: "Конюшни", value: "514" }, - { label: "Копирование сознания", value: "1231" }, - { label: "Копирование способностей", value: "1825" }, - { label: "Копро-кинк", value: "763" }, - { label: "Корё", value: "1142" }, - { label: "Корейская война", value: "2187" }, - { label: "Коренные народы", value: "1505" }, - { label: "Королевства", value: "2794" }, - { label: "Корпорация BOBSOC", value: "2940" }, - { label: "Корректирующее изнасилование", value: "2856" }, - { label: "Коррупция", value: "2150" }, - { label: "Косвенные убийства", value: "2846" }, - { label: "Космоопера", value: "48" }, - { label: "Космос", value: "236" }, - { label: "Косплееры", value: "944" }, - { label: "Кочевники", value: "1793" }, - { label: "Кошмары", value: "1228" }, - { label: "Красная нить судьбы", value: "608" }, - { label: "Крепости / Башни", value: "2321" }, - { label: "Крестовые походы", value: "2070" }, - { label: "Крестражи", value: "2238" }, - { label: "Кризис гендера", value: "1406" }, - { label: "Кризис ориентации", value: "1405" }, - { label: "Криминалистическая экспертиза", value: "2361" }, - { label: "Криминальная пара", value: "1920" }, - { label: "Криокинез", value: "1804" }, - { label: "Криптиды", value: "60" }, - { label: "Криптоистория", value: "179" }, - { label: "Кровь / Травмы", value: "800" }, - { label: "Кроссдрессинг", value: "65" }, - { label: "Кроссовер", value: "10" }, - { label: "Кроули — Архангел Рафаэль", value: "2471" }, - { label: "Круизы", value: "2488" }, - { label: "Крушение «Титаника»", value: "2200" }, - { label: "Крылатые", value: "92" }, - { label: "Крэк", value: "1408" }, - { label: "Ксенофилия", value: "1711" }, - { label: "Ксенофобия", value: "589" }, - { label: "Куба", value: "773" }, - { label: "Кудэрэ", value: "1216" }, - { label: "Куклы", value: "1221" }, - { label: "Куколдинг", value: "524" }, - { label: "Культ Дракона", value: "2244" }, - { label: "Кумогакуре", value: "2474" }, - { label: "Куннилингус", value: "172" }, - { label: "Купальни", value: "964" }, - { label: "Курение", value: "202" }, - { label: "Курортный роман", value: "181" }, - { label: "Курьеры", value: "2735" }, - { label: "Лабиринты", value: "1981" }, - { label: "Лаборатории", value: "1115" }, - { label: "Лабораторные опыты", value: "146" }, - { label: "Лав-отели", value: "801" }, - { label: "Лавандовый брак", value: "1357" }, - { label: "Лакросс", value: "830" }, - { label: "Лапслок", value: "267" }, - { label: "Латентная гомосексуальность", value: "2339" }, - { label: "ЛГБТ-родители", value: "2723" }, - { label: "Лебединая верность", value: "537" }, - { label: "Левитация", value: "1281" }, - { label: "Легкая атлетика", value: "1797" }, - { label: "Лекарственная зависимость", value: "2632" }, - { label: "Леса", value: "703" }, - { label: "Летние ОтМетки", value: "2956" }, - { label: "Летние школы", value: "2803" }, - { label: "Лето девяносто девятого", value: "1990" }, - { label: "Лжебоги", value: "2869" }, - { label: "Лингвистический кинк", value: "2042" }, - { label: "Лирика", value: "2005" }, - { label: "Лихтенштейн", value: "1023" }, - { label: "Личность против системы", value: "1912" }, - { label: "Ложная беременность", value: "1428" }, - { label: "Ложные воспоминания", value: "376" }, - { label: "Ложные обвинения", value: "1204" }, - { label: "Локальный постапокалипсис", value: "2455" }, - { label: "Лолита (субкультура)", value: "1207" }, - { label: "Ломка", value: "1846" }, - { label: "Лошади", value: "1083" }, - { label: "Лугнасад", value: "2621" }, - { label: "Лудомания", value: "947" }, - { label: "Лучники", value: "1521" }, - { label: "Любить луну", value: "2901" }, - { label: "Любовная магия", value: "2317" }, - { label: "Любовный магнит", value: "1407" }, - { label: "Любовный многоугольник", value: "63" }, - { label: "Любовь с первого взгляда", value: "813" }, - { label: "Любовь/Ненависть", value: "1703" }, - { label: "Люди", value: "1538" }, - { label: "Людоеды", value: "1288" }, - { label: "Магазины", value: "1063" }, - { label: "Магическая связь", value: "2720" }, - { label: "Магические клятвы", value: "2245" }, - { label: "Магические лавки", value: "2629" }, - { label: "Магические учебные заведения", value: "1338" }, - { label: "Магический реализм", value: "9" }, - { label: "Магия", value: "1419" }, - { label: "Магия крови", value: "2857" }, - { label: "Маленькие города", value: "221" }, - { label: "Малфоигуд", value: "1890" }, - { label: "Мамми-кинк", value: "273" }, - { label: "Мандалорцы", value: "2870" }, - { label: "Манекены", value: "1509" }, - { label: "Манипуляции", value: "992" }, - { label: "Марафонный секс", value: "316" }, - { label: "Маргиналы", value: "394" }, - { label: "Марди Гра", value: "2407" }, - { label: "Маскарады / Балы", value: "443" }, - { label: "Массаж", value: "2218" }, - { label: "Мастурбация", value: "226" }, - { label: "Матриархат", value: "706" }, - { label: "Матчасть", value: "2328" }, - { label: "Махотокоро", value: "2943" }, - { label: "Маяки", value: "1356" }, - { label: "Мегаломания", value: "985" }, - { label: "Мегаполисы", value: "451" }, - { label: "Медицинский кинк", value: "748" }, - { label: "Медицинское использование наркотиков", value: "925" }, - { label: "Медовый месяц", value: "2235" }, - { label: "Медсестры / Медбратья", value: "2236" }, - { label: "Межбедренный секс", value: "931" }, - { label: "Междумирье", value: "2280" }, - { label: "Межэтнические отношения", value: "2121" }, - { label: "Мейлдом", value: "59" }, - { label: "Мексика", value: "768" }, - { label: "Меланхолия", value: "2108" }, - { label: "Мелодрама", value: "2881" }, - { label: "Менструация", value: "1570" }, - { label: "Ментальная тюрьма", value: "2294" }, - { label: "Месть", value: "907" }, - { label: "Металлисты", value: "1206" }, - { label: "Металлокинез", value: "1532" }, - { label: "Метафизические существа", value: "2097" }, - { label: "Метки", value: "1398" }, - { label: "Метросексуалы", value: "558" }, - { label: "Механофилия / Технофилия", value: "587" }, - { label: "Мечники", value: "2783" }, - { label: "Мечты", value: "993" }, - { label: "Миддлпанк", value: "2076" }, - { label: "Мизофилия", value: "1970" }, - { label: "Микро / Макро", value: "407" }, - { label: "Микрофикшен", value: "417" }, - { label: "Мимикрия", value: "2083" }, - { label: "Минет", value: "231" }, - { label: "Министерство Магии", value: "1917" }, - { label: "Минотавры", value: "2820" }, - { label: "Мир без гомофобии", value: "2660" }, - { label: "Мир Желаний (Однажды в сказке)", value: "2923" }, - { label: "Мир Института Войны", value: "2379" }, - { label: "Мироустройство", value: "989" }, - { label: "Мистерия", value: "2012" }, - { label: "Мистика", value: "1671" }, - { label: "Мистическая беременность", value: "1784" }, - { label: "Мистические защитники", value: "2162" }, - { label: "Мифы и мифология", value: "18" }, - { label: "Мнимая беременность", value: "1096" }, - { label: "Мнимая проза", value: "1098" }, - { label: "Мнимая свобода", value: "2708" }, - { label: "Многодетные семьи", value: "2785" }, - { label: "Множественное проникновение", value: "2059" }, - { label: "Множественные оргазмы", value: "317" }, - { label: "Множественные финалы", value: "312" }, - { label: "Могучие Рейнджеры: Дино Заряд", value: "2931" }, - { label: "Могучие Рейнджеры: Мегафорс", value: "2930" }, - { label: "Могучие Рейнджеры: Мистическая Сила", value: "2933" }, - { label: "Могучие Рейнджеры: Самураи", value: "2929" }, - { label: "Могучие Рейнджеры: Успеть на помощь", value: "2934" }, - { label: "Могучие Рейнджеры: Ярость Джунглей", value: "2932" }, - { label: "Модели", value: "399" }, - { label: "Модельеры", value: "598" }, - { label: "Модельный бизнес", value: "435" }, - { label: "Модификации тела", value: "890" }, - { label: "Молдова", value: "2967" }, - { label: "Молчание", value: "2465" }, - { label: "Монастыри", value: "352" }, - { label: "Монахи", value: "353" }, - { label: "Монолог", value: "2333" }, - { label: "Монстрофилия", value: "94" }, - { label: "Монстры", value: "529" }, - { label: "Моральные дилеммы", value: "959" }, - { label: "Морлед", value: "2255" }, - { label: "Моря / Океаны", value: "955" }, - { label: "Моряки", value: "406" }, - { label: "Мотоспорт", value: "1461" }, - { label: "Мужская беременность", value: "1660" }, - { label: "Мужская дружба", value: "2157" }, - { label: "Мужское грудное кормление", value: "297" }, - { label: "Музеи / Галереи", value: "795" }, - { label: "Музы", value: "2001" }, - { label: "Музыканты", value: "141" }, - { label: "Муковисцидоз", value: "2764" }, - { label: "Мультикроссовер", value: "2247" }, - { label: "Мумии", value: "579" }, - { label: "Мутанты", value: "740" }, - { label: "Мэри Сью (Марти Стью)", value: "1655" }, - { label: "Мятежи / Восстания", value: "584" }, - { label: "На грани жизни и смерти", value: "2545" }, - { label: "Наблюдатели", value: "1816" }, - { label: "Навязчивая опека", value: "954" }, - { label: "Навязчивые мысли", value: "2851" }, - { label: "Наги", value: "90" }, - { label: "Надежда", value: "2627" }, - { label: "Наемники", value: "512" }, - { label: "Наемные убийцы", value: "192" }, - { label: "Названные сиблинги", value: "2927" }, - { label: "Намеки на отношения", value: "1387" }, - { label: "Намеки на секс", value: "1382" }, - { label: "Напарники", value: "1291" }, - { label: "Наперегонки со временем", value: "2240" }, - { label: "НапиСанта", value: "2946" }, - { label: "Наполеоновские войны", value: "470" }, - { label: "Нарколепсия", value: "586" }, - { label: "Наркоторговля", value: "1116" }, - { label: "Нарушение этических норм", value: "968" }, - { label: "Нарциссизм", value: "546" }, - { label: "Насекомые", value: "2358" }, - { label: "Насилие", value: "1649" }, - { label: "Насилие над детьми", value: "726" }, - { label: "Наследие (Гарри Поттер)", value: "1935" }, - { label: "Наследство", value: "2172" }, - { label: "Наставничество", value: "935" }, - { label: "Настольные игры", value: "1513" }, - { label: "Настольные ролевые игры", value: "644" }, - { label: "Натуризм / Нудизм", value: "1810" }, - { label: "Наука", value: "2624" }, - { label: "Научная фантастика", value: "596" }, - { label: "Научно-исследовательские организации", value: "1503" }, - { label: "Научное фэнтези", value: "180" }, - { label: "Начало отношений", value: "1328" }, - { label: "Небинарные персонажи", value: "314" }, - { label: "Невезение", value: "2689" }, - { label: "Невзаимные предначертанные", value: "1484" }, - { label: "Невзаимные чувства", value: "105" }, - { label: "Невидимость", value: "359" }, - { label: "Невидимый мир", value: "2286" }, - { label: "Неграфичные описания", value: "2855" }, - { label: "Недоверие", value: "1842" }, - { label: "Недопонимания", value: "614" }, - { label: "Недостатки внешности", value: "923" }, - { label: "Нежелательная беременность", value: "715" }, - { label: "Нежелательные сверхспособности", value: "1335" }, - { label: "Нежелательные чувства", value: "2078" }, - { label: "Нежный секс", value: "280" }, - { label: "Незащищенный секс", value: "497" }, - { label: "Нездоровые механизмы преодоления", value: "1528" }, - { label: "Нездоровые отношения", value: "71" }, - { label: "Нездоровый образ жизни", value: "2148" }, - { label: "Нездоровый BDSM", value: "1062" }, - { label: "Неидеальный омегаверс", value: "2712" }, - { label: "Неизвестность", value: "2826" }, - { label: "Неизвестные родственники", value: "2752" }, - { label: "Неизлечимые заболевания", value: "1269" }, - { label: "Нейтрализация сверхспособностей", value: "2343" }, - { label: "Некромаги", value: "679" }, - { label: "Некрофилия", value: "1663" }, - { label: "Нелинейное повествование", value: "1699" }, - { label: "Неловкий секс", value: "2883" }, - { label: "Неловкость", value: "2459" }, - { label: "Нелюбящие родители", value: "2817" }, - { label: "Немертвые", value: "495" }, - { label: "Немота", value: "414" }, - { label: "Ненависть", value: "685" }, - { label: "Ненависть к себе", value: "1441" }, - { label: "Ненависть с первого взгляда", value: "814" }, - { label: "Ненадежный рассказчик", value: "322" }, - { label: "Ненасильственная смерть", value: "2531" }, - { label: "Необитаемые острова", value: "1196" }, - { label: "Необратимые превращения", value: "926" }, - { label: "Неозвученные чувства", value: "258" }, - { label: "Неприятие отношений", value: "2056" }, - { label: "Неравные отношения", value: "545" }, - { label: "Неравный брак", value: "409" }, - { label: "Неразрывная связь", value: "2569" }, - { label: "Нервный срыв", value: "1190" }, - { label: "Нерды", value: "481" }, - { label: "Нереалистичность", value: "2350" }, - { label: "Несексуальная близость", value: "2874" }, - { label: "Нестандартная поэзия", value: "1704" }, - { label: "Несчастливые отношения", value: "2080" }, - { label: "Несчастливый финал", value: "61" }, - { label: "Несчастные случаи", value: "499" }, - { label: "Нетаймори", value: "2323" }, - { label: "Неторопливое повествование", value: "1815" }, - { label: "Нетрадиционное использование Силы", value: "2520" }, - { - label: "Неумышленное употребление наркотических веществ", - value: "1192", - }, - { label: "Неуставные отношения", value: "1396" }, - { label: "Нефилимы", value: "1086" }, - { label: "Неформальный брак", value: "1355" }, - { label: "Нецензурная лексика", value: "1653" }, - { label: "Нечеловеческая мораль", value: "2551" }, - { label: "Нечеловеческие виды", value: "995" }, - { label: "Нечистая сила", value: "1464" }, - { label: "Нидерланды", value: "1141" }, - { label: "Низкая самооценка", value: "2014" }, - { label: "Низкое фэнтези", value: "2007" }, - { label: "Нимфы", value: "1477" }, - { label: "Ниндзя", value: "471" }, - { label: "Новая жизнь", value: "2018" }, - { label: "Новая Зеландия", value: "1789" }, - { label: "Новеллизация", value: "262" }, - { label: "Новые отношения", value: "1827" }, - { label: "Новый год", value: "206" }, - { label: "Новый канон ЗВ", value: "1948" }, - { label: "Норны", value: "2206" }, - { label: "Ностальгия", value: "878" }, - { label: "Ночное видение", value: "2006" }, - { label: "Ночные клубы", value: "531" }, - { label: "Нуар", value: "137" }, - { label: "Няни", value: "570" }, - { label: "Обездвиживание", value: "116" }, - { label: "Обещания / Клятвы", value: "1823" }, - { label: "Обиды", value: "905" }, - { label: "Обман / Заблуждение", value: "650" }, - { label: "Обмен квами", value: "2572" }, - { label: "Обмен ролями", value: "1055" }, - { label: "Обмен телами", value: "49" }, - { label: "Обмороки", value: "2484" }, - { label: "Обнажение", value: "970" }, - { label: "Оборотни", value: "28" }, - { label: "Обоснованный ООС", value: "2549" }, - { label: "Образ тела", value: "2289" }, - { label: "Обратный омегаверс", value: "2435" }, - { label: "Обретенные семьи", value: "601" }, - { label: "Обреченные отношения", value: "653" }, - { label: "Обскуры", value: "2237" }, - { label: "Обсуждение кинков", value: "1072" }, - { label: "Обусловленная контекстом гомофобия", value: "2685" }, - { label: "Обусловленный контекстом расизм", value: "2686" }, - { label: "Обусловленный контекстом сексизм", value: "2687" }, - { label: "Общежития", value: "534" }, - { label: "Общественный транспорт", value: "615" }, - { label: "Объективация", value: "1837" }, - { label: "Объектофилия", value: "366" }, - { label: "Овипозиция", value: "269" }, - { label: "Огнестрельное оружие", value: "1189" }, - { label: "Ограбления", value: "2269" }, - { label: "Одержимость", value: "2248" }, - { label: "Одержимые", value: "496" }, - { label: "Один день", value: "2647" }, - { label: "Одиночество", value: "1015" }, - { label: "Одичавшие дети", value: "835" }, - { label: "Однолюбы", value: "2146" }, - { label: "Одноминутный канонический персонаж", value: "2184" }, - { label: "Однополый мир", value: "1462" }, - { label: "Ожидание", value: "2909" }, - { label: "ОЖП", value: "1657" }, - { label: "Окаменение", value: "2052" }, - { label: "Океания", value: "1058" }, - { label: "Оккультизм", value: "2374" }, - { label: "ОКР", value: "594" }, - { label: "Окулолинктус", value: "1470" }, - { label: "Олимпийские игры", value: "1127" }, - { label: "Олфактофилия", value: "1945" }, - { label: "Омегаверс", value: "1693" }, - { label: "Омегаверс: Альфа/Альфа", value: "2437" }, - { label: "Омегаверс: Альфа/Бета", value: "2741" }, - { label: "Омегаверс: Альфа/Бета/Омега", value: "2898" }, - { label: "Омегаверс: Альфа/Омега/Альфа", value: "2436" }, - { label: "Омегаверс: Бета/Бета", value: "2966" }, - { label: "Омегаверс: Больше трех полов", value: "2782" }, - { label: "Омегаверс: Омега/Альфа/Омега", value: "2544" }, - { label: "Омегаверс: Омега/Бета", value: "2965" }, - { label: "Омегаверс: Омега/Омега", value: "2564" }, - { label: "Омегаверс: Смена второго пола", value: "2776" }, - { label: "Омегаверс: f!Альфа/m!Омега", value: "2777" }, - { label: "ОМП", value: "1656" }, - { label: "Онейрокинез", value: "2067" }, - { label: "Онкологические заболевания", value: "540" }, - { label: "ООС", value: "1648" }, - { label: "Опасность", value: "2847" }, - { label: "Опера", value: "549" }, - { label: "Опричнина", value: "2252" }, - { label: "Оптимизм", value: "2420" }, - { label: "Оракулы / Провидцы", value: "2221" }, - { label: "Оральная фиксация", value: "2523" }, - { label: "Оргазм без стимуляции", value: "1000" }, - { label: "Организаторы свадеб", value: "858" }, - { label: "Орден Феникса", value: "1907" }, - { label: "Орки", value: "187" }, - { label: "Оружие массового поражения", value: "1193" }, - { label: "Освоение земель", value: "1824" }, - { label: "Оседлание", value: "1223" }, - { label: "Османская империя", value: "527" }, - { label: "Особняки / Резиденции", value: "500" }, - { label: "Осознанные сновидения", value: "530" }, - { label: "Остеокинез", value: "2845" }, - { label: "Острова", value: "799" }, - { label: "От антигероя к герою", value: "2173" }, - { label: "От антигероя к злодею", value: "2213" }, - { label: "От божественного существа к смертному", value: "2664" }, - { label: "От возлюбленных к врагам", value: "783" }, - { label: "От возлюбленных к друзьям", value: "782" }, - { label: "От врагов к возлюбленным", value: "346" }, - { label: "От врагов к друзьям", value: "347" }, - { label: "От врагов к друзьям к возлюбленным", value: "345" }, - { label: "От героя к антигерою", value: "2546" }, - { label: "От героя к злодею", value: "1027" }, - { label: "От героя к монстру", value: "2659" }, - { label: "От героя к обычному персонажу", value: "2584" }, - { label: "От друзей к возлюбленным", value: "344" }, - { label: "От друзей к врагам", value: "463" }, - { label: "От друзей к незнакомцам", value: "1870" }, - { label: "От злодея к антигерою", value: "2640" }, - { label: "От злодея к герою", value: "1026" }, - { label: "От напарников к друзьям к возлюбленным", value: "2460" }, - { label: "От нездоровых отношений к здоровым", value: "2301" }, - { label: "От незнакомцев к возлюбленным", value: "372" }, - { label: "От простонародья к аристократу", value: "2816" }, - { label: "От сексуальных партнеров к возлюбленным", value: "2069" }, - { label: "От смертного к божественному существу", value: "2665" }, - { label: "От супругов к возлюбленным", value: "2359" }, - { label: "Ответвление от канона", value: "2336" }, - { label: "Ответственность", value: "2468" }, - { label: "Отдаю на вдохновение", value: "2288" }, - { label: "Отечественная война 1812 года", value: "1162" }, - { label: "Отказ от чувств", value: "2227" }, - { label: "Отклонения от канона", value: "5" }, - { label: "Открытый финал", value: "185" }, - { label: "ОтМетки", value: "2945" }, - { label: "Отношения втайне", value: "285" }, - { label: "Отношения на расстоянии", value: "37" }, - { label: "Отношения на спор", value: "383" }, - { label: "Отношения наполовину", value: "1573" }, - { label: "Отпуск", value: "1828" }, - { label: "Отрицание", value: "1868" }, - { label: "Отрицание чувств", value: "648" }, - { label: "Отрицательный протагонист", value: "1442" }, - { label: "Отсутствие души", value: "1897" }, - { label: "Отшельники", value: "543" }, - { label: "Офисы", value: "74" }, - { label: "Официанты / Официантки", value: "2560" }, - { label: "Охота", value: "825" }, - { label: "Охота на разумных существ", value: "2784" }, - { label: "Охотники", value: "2036" }, - { label: "Охотники за головами", value: "2103" }, - { label: "Охотники на нечисть", value: "46" }, - { label: "Охранники", value: "1173" }, - { label: "Ошибки", value: "2554" }, - { label: "Ошибочная идентификация", value: "2490" }, - { label: "Паладины", value: "1194" }, - { label: "Пан-персонажи", value: "302" }, - { label: "Пандемия COVID-19", value: "2724" }, - { label: "Панические атаки", value: "751" }, - { label: "Паническое расстройство", value: "733" }, - { label: "Панки", value: "625" }, - { label: "Паразиты", value: "1877" }, - { label: "Паралич", value: "1941" }, - { label: "Параллельные миры", value: "378" }, - { label: "Паранойя", value: "1253" }, - { label: "Пари", value: "778" }, - { label: "Парки / Зоны отдыха", value: "1005" }, - { label: "Парки аттракционов / Ярмарки", value: "793" }, - { label: "Паркур", value: "553" }, - { label: "Пародия", value: "1676" }, - { label: "Партизаны", value: "850" }, - { label: "Парфюмеры", value: "1384" }, - { label: "Пасха", value: "562" }, - { label: "Патологическое бесстрашие", value: "1498" }, - { label: "Патологическое накопительство", value: "2691" }, - { label: "Патологоанатомы", value: "502" }, - { label: "Патриархат", value: "705" }, - { label: "Патриотические темы и мотивы", value: "2231" }, - { label: "Патронусы", value: "2390" }, - { label: "Патрули", value: "1819" }, - { label: "Пафос", value: "2589" }, - { label: "Пацифисты", value: "1939" }, - { label: "Пегасы", value: "1047" }, - { label: "Пеггинг", value: "159" }, - { label: "Пейзажная лирика", value: "2330" }, - { label: "Пекарни", value: "78" }, - { label: "Первая мировая", value: "487" }, - { label: "Первая чеченская война", value: "2428" }, - { label: "Первобытные времена", value: "465" }, - { label: "Первое апреля", value: "2315" }, - { label: "Первопроходцы", value: "351" }, - { label: "Первый контакт", value: "2093" }, - { label: "Первый поцелуй", value: "2790" }, - { label: "Первый раз", value: "1292" }, - { label: "Передача магических способностей", value: "2497" }, - { label: "Переезд", value: "658" }, - { label: "Перезапуск мира", value: "2710" }, - { label: "Перемирие", value: "1331" }, - { label: "Переписки и чаты (стилизация)", value: "38" }, - { label: "Перерыв в отношениях", value: "519" }, - { label: "Переселение душ", value: "1237" }, - { label: "Перестрелки", value: "2268" }, - { label: "Переходный возраст", value: "1297" }, - { label: "Период Эдо", value: "1140" }, - { label: "Персекуторный бред", value: "2136" }, - { label: "Персонажи-геи", value: "2141" }, - { label: "Персонажи-лесбиянки", value: "2142" }, - { label: "Персонификация", value: "994" }, - { label: "Персонификация смерти", value: "1046" }, - { label: "Перу", value: "2017" }, - { label: "Перфекционизм", value: "2730" }, - { label: "Пессимизм", value: "2709" }, - { label: "Пет-плей", value: "391" }, - { label: "Петербург: бикейм #Чимин Сергеевич", value: "1859" }, - { label: "Петтинг", value: "301" }, - { label: "Пещеры", value: "655" }, - { label: "Пижамные вечеринки", value: "1340" }, - { label: "Пикацизм", value: "1227" }, - { label: "Пикники", value: "1165" }, - { label: "Пионеры", value: "668" }, - { label: "Пираты", value: "72" }, - { label: "Пирокинез", value: "1180" }, - { label: "Пиромания", value: "899" }, - { label: "Пирсинг", value: "507" }, - { label: "Писатели", value: "196" }, - { label: "Письма", value: "2298" }, - { label: "Письма (стилизация)", value: "266" }, - { label: "Пиццерии / Дайнеры", value: "593" }, - { label: "Плавание", value: "1135" }, - { label: "Плантокинез", value: "2029" }, - { label: "Пластические операции", value: "1847" }, - { label: "Платонические отношения", value: "385" }, - { label: "Племена", value: "1336" }, - { label: "Плен", value: "290" }, - { label: "Плененные путешествием", value: "2615" }, - { label: "Плохая компания", value: "1502" }, - { label: "Плохие друзья", value: "2445" }, - { label: "Плохой хороший финал", value: "1265" }, - { label: "Плюшефилия", value: "520" }, - { label: "Пляжи", value: "766" }, - { label: "По разные стороны", value: "897" }, - { label: "Побег", value: "661" }, - { label: "Побег из дома", value: "2309" }, - { label: "Победа Волдеморта", value: "1887" }, - { label: "Победа Гриндевальда", value: "2398" }, - { label: "Повара", value: "2853" }, - { label: "Повелитель смерти", value: "1909" }, - { label: "Повествование в будущем времени", value: "2633" }, - { label: "Повествование в настоящем времени", value: "1826" }, - { label: "Повествование во втором лице", value: "166" }, - { label: "Повествование от нескольких лиц", value: "1157" }, - { label: "Повествование от первого лица", value: "1681" }, - { label: "Повседневность", value: "1677" }, - { label: "Повстанцы", value: "659" }, - { label: "Повторение судьбы", value: "1997" }, - { label: "Поглощение способностей", value: "2605" }, - { label: "Погони / Преследования", value: "1996" }, - { label: "Пограничный синдром", value: "710" }, - { label: "Погребение заживо", value: "1279" }, - { label: "Под одной крышей", value: "462" }, - { label: "Под старину (стилизация)", value: "2486" }, - { label: "Подарки", value: "1109" }, - { label: "Подвешивание", value: "914" }, - { label: "Подводный мир", value: "901" }, - { label: "Подземелья", value: "2314" }, - { label: "Подземный мир", value: "1453" }, - { label: "Подлость", value: "2625" }, - { label: "Подменыши", value: "2250" }, - { label: "Подпольные бои", value: "1389" }, - { label: "Подразумеваемая смерть персонажа", value: "2204" }, - { label: "Подростки", value: "218" }, - { label: "Подростковая беременность", value: "986" }, - { label: "Подростковая влюбленность", value: "581" }, - { label: "Подсознание", value: "2273" }, - { label: "Поедание разумных существ", value: "1795" }, - { label: "Пожарные", value: "2557" }, - { label: "Пожилые персонажи", value: "852" }, - { label: "Поза 69", value: "699" }, - { label: "Поиск работы", value: "2646" }, - { label: "Поиск родителей", value: "2033" }, - { label: "Поклонение телу", value: "712" }, - { label: "Покровительство", value: "2223" }, - { label: "Покушение на жизнь", value: "1057" }, - { label: "Покушение на свободу", value: "2655" }, - { label: "Полиамория", value: "1705" }, - { label: "Полиандрия", value: "761" }, - { label: "Полигиния", value: "760" }, - { label: "Политика", value: "1835" }, - { label: "Политики", value: "711" }, - { label: "Политические интриги", value: "183" }, - { label: "Полицейские", value: "14" }, - { label: "Половой диморфизм", value: "1780" }, - { label: "Полубоги", value: "437" }, - { label: "Полудемоны", value: "2872" }, - { label: "Полудраконы", value: "2859" }, - { label: "Полукровки", value: "368" }, - { label: "Польша", value: "777" }, - { label: "Полярные станции", value: "1493" }, - { label: "Помощь врагу", value: "1325" }, - { label: "Попаданцы: В реальный мир", value: "1499" }, - { label: "Попаданцы: В своем теле", value: "1412" }, - { label: "Попаданцы: В чужом теле", value: "1413" }, - { label: "Попаданцы: Из одного фандома в другой", value: "2699" }, - { label: "Попаданцы: Из фандома в ориджинал", value: "2193" }, - { label: "Попаданцы: По обмену", value: "2196" }, - { label: "Попаданчество", value: "1695" }, - { label: "Популярность", value: "2581" }, - { label: "Попытка изнасилования", value: "1440" }, - { label: "Порноактеры", value: "289" }, - { label: "Португалия", value: "1749" }, - { label: "Порты", value: "1028" }, - { label: "Поселки", value: "1298" }, - { label: "После таймскипа (Haikyuu!!)", value: "2906" }, - { label: "После таймскипа (Shingeki no Kyojin)", value: "2903" }, - { label: "Послевоенное время", value: "1080" }, - { label: "Последний раз", value: "2645" }, - { label: "Последний рубеж", value: "1178" }, - { label: "Последний шанс", value: "1209" }, - { label: "Последствия", value: "2491" }, - { label: "Последствия болезни", value: "2612" }, - { label: "Послеродовая депрессия", value: "988" }, - { label: "Посмертная любовь", value: "2670" }, - { label: "Посмертный персонаж", value: "2653" }, - { label: "Пост-Пацифист", value: "2408" }, - { label: "Пост-Рейхенбах", value: "1903" }, - { label: "Пост-третий сезон (Шерлок)", value: "1977" }, - { label: "Постапокалиптика", value: "1697" }, - { label: "ПостВБ", value: "2386" }, - { label: "Постканон", value: "6" }, - { label: "ПостРагнарек", value: "2537" }, - { label: "ПостХог", value: "1883" }, - { label: "ПостЭндгейм", value: "2179" }, - { label: "Потеря девственности", value: "1234" }, - { label: "Потеря конечностей", value: "1289" }, - { label: "Потеря магических способностей", value: "1430" }, - { label: "Потеря памяти", value: "36" }, - { label: "Потеря сверхспособностей", value: "1051" }, - { label: "Поттергад", value: "2417" }, - { label: "Похищение", value: "224" }, - { label: "Похороны", value: "786" }, - { label: "Почтовые работники", value: "1821" }, - { label: "Пошлый юмор", value: "1362" }, - { label: "Поэма", value: "1938" }, - { label: "Поэты", value: "357" }, - { label: "Пояс верности", value: "1779" }, - { label: "Правда или действие", value: "1982" }, - { label: "Практопия", value: "2249" }, - { label: "Пре-гет", value: "209" }, - { label: "Пре-Рош", value: "2047" }, - { label: "Пре-слэш", value: "207" }, - { label: "Пре-фемслэш", value: "208" }, - { label: "Предательство", value: "361" }, - { label: "Предвидение", value: "1876" }, - { label: "Предложение руки и сердца", value: "1081" }, - { label: "Предопределенность", value: "411" }, - { label: "Предрассудки", value: "2046" }, - { label: "Предсмертные сообщения", value: "2174" }, - { label: "Преканон", value: "7" }, - { label: "ПреКербер", value: "2726" }, - { label: "Прекрасная эпоха", value: "1809" }, - { label: "Прелюдия", value: "2395" }, - { label: "Пренебрежение гигиеной", value: "2921" }, - { label: "Пренебрежение жизнью", value: "2216" }, - { label: "Преодоление комплексов", value: "588" }, - { label: "Преподаватели", value: "403" }, - { label: "Преподаватель/Обучающийся", value: "2507" }, - { label: "Преступники", value: "1446" }, - { label: "Преступный мир", value: "12" }, - { label: "Прибрежные города", value: "984" }, - { label: "Приватный танец", value: "2786" }, - { label: "Привязанность", value: "2372" }, - { label: "Пригород", value: "452" }, - { label: "Приемные семьи", value: "844" }, - { label: "Признания в любви", value: "1049" }, - { label: "Призраки", value: "26" }, - { label: "Приключения", value: "21" }, - { label: "Приметы / Суеверия", value: "612" }, - { label: "Примирение", value: "660" }, - { label: "Принудительная феминизация", value: "656" }, - { label: "Принудительное лечение", value: "971" }, - { label: "Принудительные отношения", value: "2302" }, - { label: "Принудительный брак", value: "307" }, - { label: "Принудительный инцест", value: "2942" }, - { label: "Принуждение", value: "1323" }, - { label: "Принятие себя", value: "2754" }, - { label: "Прислуга", value: "804" }, - { label: "Прист-кинк", value: "342" }, - { label: "Приступы агрессии", value: "2788" }, - { label: "Притча", value: "1088" }, - { label: "Приюты для животных", value: "2345" }, - { label: "ПРЛ", value: "1092" }, - { label: "Проблемы доверия", value: "2208" }, - { label: "Проблемы с законом", value: "1007" }, - { label: "Проводники душ", value: "2348" }, - { label: "Программисты", value: "574" }, - { label: "Прогрессорство", value: "449" }, - { label: "Прогулки", value: "2462" }, - { label: "Продажа души", value: "887" }, - { label: "Прозопагнозия", value: "2013" }, - { label: "Производственный роман", value: "2119" }, - { label: "Проклятия", value: "875" }, - { label: "Пролапс", value: "2926" }, - { label: "Промискуитет", value: "1817" }, - { label: "Промышленные предприятия", value: "1456" }, - { label: "Пропавшие без вести", value: "2073" }, - { label: "Пропущенная сцена", value: "1702" }, - { label: "Пророчества", value: "834" }, - { label: "Просмотр порно", value: "2341" }, - { label: "Проституция", value: "178" }, - { label: "Протезы", value: "1581" }, - { label: "Противоположности", value: "948" }, - { label: "Противоречивые чувства", value: "2528" }, - { label: "Прошлое", value: "983" }, - { label: "Прощение", value: "1545" }, - { label: "Псевдо-инцест", value: "336" }, - { label: "Псевдо-мистика", value: "2159" }, - { label: "Псевдоисторический сеттинг", value: "1479" }, - { label: "Псионика", value: "2023" }, - { label: "Психиатрические больницы", value: "135" }, - { label: "Психические расстройства", value: "69" }, - { label: "Психоз", value: "1339" }, - { label: "Психологи / Психоаналитики", value: "611" }, - { label: "Психологическая война", value: "2595" }, - { label: "Психологические пытки", value: "2825" }, - { label: "Психологические травмы", value: "40" }, - { label: "Психологический мазохизм", value: "2212" }, - { label: "Психологический ужас", value: "1261" }, - { label: "Психологическое насилие", value: "836" }, - { label: "Психология", value: "1674" }, - { label: "Психопатия", value: "869" }, - { label: "Психосоматические расстройства", value: "1834" }, - { label: "Психотерапия", value: "958" }, - { label: "ПТСР", value: "425" }, - { label: "Публичное обнажение", value: "319" }, - { label: "Пурпурная проза", value: "599" }, - { label: "Пустоши", value: "1114" }, - { label: "Пустыни", value: "692" }, - { label: "Путешественники-исследователи", value: "888" }, - { label: "Путешествия", value: "894" }, - { label: "Пытки", value: "210" }, - { label: "Пьеса", value: "434" }, - { label: "Рабочие", value: "1771" }, - { label: "Рабство", value: "51" }, - { label: "Равнодушие", value: "2516" }, - { label: "Равные отношения", value: "2728" }, - { label: "Радикальная медицина", value: "731" }, - { label: "Радио", value: "974" }, - { label: "Разбойники", value: "473" }, - { label: "Развитие отношений", value: "1404" }, - { label: "Развод", value: "200" }, - { label: "Разговоры", value: "1401" }, - { label: "Раздвоение личности", value: "287" }, - { label: "Раздельное обучение", value: "1959" }, - { label: "Разлука / Прощания", value: "1104" }, - { label: "Разница в возрасте", value: "2" }, - { label: "Разница культур", value: "1079" }, - { label: "Разновозрастная дружба", value: "2402" }, - { label: "Разнополая дружба", value: "806" }, - { label: "Разоблачения", value: "2684" }, - { label: "Разочарования", value: "646" }, - { label: "Разрушение стереотипов", value: "2805" }, - { label: "Разрушение четвертой стены", value: "381" }, - { label: "Разрыв связи", value: "2582" }, - { label: "Разум роя", value: "1459" }, - { label: "Разумное оружие", value: "2675" }, - { label: "Разумные животные", value: "895" }, - { label: "Разумные растения", value: "1037" }, - { label: "Раптофилия", value: "729" }, - { label: "Расизм", value: "433" }, - { label: "Раскрытие личностей", value: "2120" }, - { label: "Раскрытие магии", value: "1878" }, - { label: "Расплата", value: "2464" }, - { label: "Рассказ в рассказе", value: "2077" }, - { label: "Расставание", value: "506" }, - { label: "Расстройства аутистического спектра", value: "541" }, - { label: "Расстройства цветового восприятия", value: "1330" }, - { label: "Расстройства шизофренического спектра", value: "912" }, - { label: "Растаманы", value: "857" }, - { label: "Расширенная Вселенная ЗВ", value: "1950" }, - { label: "Реабилитационные центры", value: "1467" }, - { label: "Реактивное расстройство привязанности", value: "2576" }, - { label: "Реакции (стилизация)", value: "1283" }, - { label: "Реализм", value: "1201" }, - { label: "Реалити-шоу", value: "2312" }, - { label: "Ревность", value: "544" }, - { label: "Революции", value: "585" }, - { label: "Регенерация", value: "1530" }, - { label: "Регресс", value: "450" }, - { label: "Регрессия возраста", value: "102" }, - { label: "Редкие заболевания", value: "1856" }, - { label: "Реинкарнация", value: "101" }, - { label: "Рейтинг за лексику", value: "276" }, - { label: "Рейтинг за насилие и/или жестокость", value: "277" }, - { label: "Рейтинг за секс", value: "278" }, - { label: "Религиозная нетерпимость", value: "2451" }, - { label: "Религиозные войны", value: "2911" }, - { label: "Религиозные темы и мотивы", value: "198" }, - { label: "Религиозный фанатизм", value: "2548" }, - { label: "Ренессанс", value: "239" }, - { label: "Репетиторы", value: "2413" }, - { label: "Репетиции", value: "2241" }, - { label: "Репродуктивное насилие", value: "2310" }, - { label: "Реставраторы", value: "2239" }, - { label: "Рестораны", value: "412" }, - { label: "Ретеллинг", value: "52" }, - { label: "Ретрофутуризм", value: "727" }, - { label: "Реформация", value: "2199" }, - { label: "Речь Посполитая", value: "1529" }, - { label: "Риветхеды", value: "2904" }, - { label: "Римминг", value: "170" }, - { label: "Риск", value: "2467" }, - { label: "Рискованная беременность", value: "998" }, - { label: "Ритуалы", value: "749" }, - { label: "Ритуальные услуги", value: "2362" }, - { label: "Роботы", value: "513" }, - { label: "Родео", value: "1314" }, - { label: "Родители-одиночки", value: "325" }, - { label: "Родительские чувства", value: "2308" }, - { label: "Родомагия", value: "1899" }, - { label: "Роды", value: "991" }, - { label: "Рождество", value: "211" }, - { label: "Розыгрыши", value: "1807" }, - { label: "Рокеры", value: "861" }, - { label: "Роковая женщина / Роковой мужчина", value: "982" }, - { label: "Роковое усилие", value: "2604" }, - { label: "Роллер-дерби", value: "1014" }, - { label: "Романтизация", value: "1898" }, - { label: "Романтика", value: "1664" }, - { label: "Романтическая дружба", value: "2307" }, - { label: "Ромком", value: "2768" }, - { label: "Российская империя", value: "475" }, - { label: "Россия", value: "701" }, - { label: "РПП", value: "286" }, - { label: "Румыния", value: "862" }, - { label: "Русалки", value: "32" }, - { label: "Русальная неделя", value: "1067" }, - { label: "Русреал", value: "53" }, - { label: "Руферы", value: "578" }, - { label: "Рыбалка", value: "855" }, - { label: "Рыцари", value: "426" }, - { label: "Рыцарские турниры", value: "2759" }, - { label: "С чистого листа", value: "987" }, - { label: "Савойя", value: "1036" }, - { label: "Садизм / Мазохизм", value: "461" }, - { label: "Садовники", value: "1348" }, - { label: "Сайз-кинк", value: "100" }, - { label: "Самобытные культуры", value: "663" }, - { label: "Самовнушение", value: "2169" }, - { label: "Самовставка", value: "1689" }, - { label: "Самозванцы", value: "1811" }, - { label: "Самоистязание", value: "1386" }, - { label: "Самоопределение / Самопознание", value: "1278" }, - { label: "Самопожертвование", value: "750" }, - { label: "Самосуд", value: "1402" }, - { label: "Самоуничижение", value: "2667" }, - { label: "Самураи", value: "472" }, - { label: "Санатории", value: "223" }, - { label: "Сандалпанк", value: "1986" }, - { label: "Сарказм", value: "2225" }, - { label: "Сатира", value: "1944" }, - { label: "Сатиры", value: "264" }, - { label: "Сахарный диабет", value: "2609" }, - { label: "Сборник драбблов", value: "39" }, - { label: "Сборник лимериков", value: "1989" }, - { label: "Сборник пирожков", value: "743" }, - { label: "Сборник стихотворений", value: "600" }, - { label: "Сборник японской поэзии", value: "1351" }, - { label: "Свадьба", value: "184" }, - { label: "Сверхразумы", value: "966" }, - { label: "Сверхскорость", value: "1902" }, - { label: "Сверхспособности", value: "597" }, - { label: "Светлые властелины", value: "2596" }, - { label: "Светские мероприятия", value: "973" }, - { label: "Свидание вслепую", value: "741" }, - { label: "Свидания", value: "1235" }, - { label: "Свидетели", value: "1242" }, - { label: "Свингерство", value: "203" }, - { label: "Свобода", value: "2166" }, - { label: "Свободные отношения", value: "255" }, - { label: "Сводничество", value: "568" }, - { label: "Сводные родственники", value: "1445" }, - { label: "Святые", value: "393" }, - { label: "Сгенерировано ИИ", value: "3014" }, - { label: "СДВГ", value: "539" }, - { label: "Севвитус", value: "1871" }, - { label: "Северная Корея", value: "2767" }, - { label: "Северус Снейп жив", value: "2406" }, - { label: "Сегрегация", value: "2158" }, - { label: "Секретари", value: "1170" }, - { label: "Секретные миссии", value: "1829" }, - { label: "Секс без обязательств", value: "387" }, - { label: "Секс в воде", value: "718" }, - { label: "Секс в нетрезвом виде", value: "1110" }, - { label: "Секс в одежде", value: "1013" }, - { label: "Секс в публичных местах", value: "123" }, - { label: "Секс в транспорте", value: "124" }, - { label: "Секс в церкви", value: "2968" }, - { label: "Секс во время беременности", value: "279" }, - { label: "Секс во время болезни", value: "1365" }, - { label: "Секс во время менструации", value: "153" }, - { label: "Секс на камеру", value: "1101" }, - { label: "Секс на природе", value: "1256" }, - { label: "Секс перед зеркалом", value: "1255" }, - { label: "Секс по расчету", value: "1212" }, - { label: "Секс по телефону", value: "133" }, - { label: "Секс при посторонних", value: "2514" }, - { label: "Секс с воображаемыми партнерами", value: "2276" }, - { label: "Секс с использованием магии", value: "1563" }, - { label: "Секс с использованием одурманивающих веществ", value: "2635" }, - { label: "Секс с использованием посторонних предметов", value: "1661" }, - { label: "Секс с использованием сверхспособностей", value: "2610" }, - { label: "Секс со смертельным исходом", value: "1171" }, - { label: "Секс-игрушки", value: "176" }, - { label: "Секс-индустрия", value: "447" }, - { label: "Секс-клубы / Секс-вечеринки", value: "936" }, - { label: "Секс-куклы", value: "1202" }, - { label: "Секс-магия", value: "1131" }, - { label: "Секс-машины", value: "1112" }, - { label: "Секс-шопы", value: "739" }, - { label: "Сексизм", value: "464" }, - { label: "Сексомния", value: "2024" }, - { label: "Секстинг", value: "2215" }, - { label: "Сексуальная неопытность", value: "1717" }, - { label: "Сексуальное насилие", value: "2495" }, - { label: "Сексуальное обучение", value: "967" }, - { label: "Сексуальное рабство", value: "1353" }, - { label: "Сексуальные фобии", value: "1537" }, - { label: "Селфхарм", value: "76" }, - { label: "Селфцест", value: "1708" }, - { label: "Семейная сага", value: "920" }, - { label: "Семейные тайны", value: "779" }, - { label: "Семейный бизнес", value: "2338" }, - { label: "Семьи", value: "220" }, - { label: "Сенсорная депривация", value: "282" }, - { label: "Сенсорная перегрузка", value: "2351" }, - { label: "Сентиментальность", value: "2567" }, - { label: "Серая мораль", value: "839" }, - { label: "Серая мышь", value: "1250" }, - { label: "Серая реальность", value: "2278" }, - { label: "Серийные насильники", value: "1942" }, - { label: "Серийные убийцы", value: "193" }, - { label: "Серфинг", value: "764" }, - { label: "Сиамские близнецы", value: "1252" }, - { label: "Сибари", value: "131" }, - { label: "Сиблинги", value: "617" }, - { label: "Сидение на лице", value: "713" }, - { label: "Силкпанк", value: "1813" }, - { label: "Симбиоз", value: "849" }, - { label: "Символизм", value: "538" }, - { label: "Симфорофилия", value: "492" }, - { label: "Синдром восьмиклассника", value: "2032" }, - { label: "Синдром выжившего", value: "1100" }, - { label: "Синдром Дауна", value: "2106" }, - { label: "Синдром Котара", value: "2765" }, - { label: "Синдром Питера Пэна", value: "687" }, - { label: "Синдром Туретта", value: "946" }, - { label: "Синестезия", value: "960" }, - { label: "Сирены", value: "1830" }, - { label: "Сириус Блэк жив", value: "2617" }, - { label: "Сироты", value: "689" }, - { label: "Ситком", value: "2553" }, - { label: "Сказка", value: "288" }, - { label: "Скайпанк", value: "976" }, - { label: "Скандинавия", value: "781" }, - { label: "Скандинавская мифология", value: "2304" }, - { label: "Сквиртинг", value: "950" }, - { label: "Сквозное видение", value: "1280" }, - { label: "Скейтбординг", value: "1395" }, - { label: "Скелеты", value: "1766" }, - { label: "Скинхэды", value: "1757" }, - { label: "Скрытая беременность", value: "2580" }, - { label: "Скрытность", value: "2577" }, - { label: "Скрытые способности", value: "2579" }, - { label: "Скрытый Этаж", value: "2763" }, - { label: "Скульпторы", value: "2976" }, - { label: "Слатшейминг", value: "2910" }, - { label: "Следующее поколение", value: "698" }, - { label: "Слежка", value: "2102" }, - { label: "Слепота", value: "413" }, - { label: "Слияние", value: "2324" }, - { label: "Словакия", value: "2938" }, - { label: "Словения", value: "1788" }, - { label: "Сложные отношения", value: "326" }, - { label: "Слом личности", value: "623" }, - { label: "Слоуберн", value: "19" }, - { label: "Служебные животные", value: "1506" }, - { label: "Служебные отношения", value: "1347" }, - { label: "Служебный роман", value: "75" }, - { label: "Слухи / Сплетни", value: "2809" }, - { label: "Случайные убийства", value: "2673" }, - { label: "Случайный брак", value: "304" }, - { label: "Случайный поцелуй", value: "2852" }, - { label: "Случайный секс", value: "1275" }, - { label: "Смена имени", value: "2094" }, - { label: "Смена мировоззрения", value: "2865" }, - { label: "Смена сущности", value: "1707" }, - { label: "Смертельные заболевания", value: "1132" }, - { label: "Смерть антагониста", value: "2650" }, - { label: "Смерть всех персонажей", value: "2611" }, - { label: "Смерть второстепенных персонажей", value: "1713" }, - { label: "Смерть животных", value: "2210" }, - { label: "Смерть основных персонажей", value: "1647" }, - { label: "СМИ", value: "2656" }, - { label: "Смирение", value: "2272" }, - { label: "Смотрины", value: "1495" }, - { label: "Смутное время", value: "2002" }, - { label: "Снайперы", value: "1762" }, - { label: "Сновидения", value: "490" }, - { label: "Сноубординг", value: "2180" }, - { label: "Соблазнение / Ухаживания", value: "616" }, - { label: "Собственничество", value: "908" }, - { label: "Советпанк", value: "397" }, - { label: "Советский Союз", value: "468" }, - { label: "Совместная кровать", value: "1229" }, - { label: "Совместное купание", value: "1301" }, - { label: "Современное искусство", value: "1087" }, - { label: "Современность", value: "80" }, - { label: "Согласование с каноном", value: "1388" }, - { label: "Сожаления", value: "550" }, - { label: "Создание общества", value: "2643" }, - { label: "Созидание", value: "2590" }, - { label: "Сокровища", value: "893" }, - { label: "Сокрытие убийства", value: "2311" }, - { label: "Солянка из Сансов", value: "2515" }, - { label: "Сомелье / Бармены", value: "865" }, - { label: "Сомнамбулизм", value: "1394" }, - { label: "Сомнения", value: "1544" }, - { label: "Сомнофилия", value: "95" }, - { label: "Сонный паралич", value: "1203" }, - { label: "Соперничество", value: "671" }, - { label: "Сорванная свадьба", value: "2044" }, - { label: "Сострадание", value: "885" }, - { label: "Состязания", value: "910" }, - { label: "Состязания с участием животных", value: "1154" }, - { label: "Сотриголова — отец Хитоши Шинсо", value: "2877" }, - { label: "Соулмейты", value: "1696" }, - { label: "Соулмейты: Действия", value: "2575" }, - { label: "Соулмейты: Изменение восприятия", value: "1400" }, - { label: "Соулмейты: Контакт через кожу", value: "2608" }, - { label: "Соулмейты: Ментальная связь", value: "2841" }, - { label: "Соулмейты: Общая боль", value: "2583" }, - { label: "Соулмейты: Общие эмоции", value: "2637" }, - { label: "Соулмейты: Опознавательные фразы", value: "1399" }, - { label: "Соулмейты: Предметы", value: "2563" }, - { label: "Соулмейты: Предпочтения", value: "2521" }, - { label: "Соулмейты: Разноцветные глаза", value: "2461" }, - { label: "Соулмейты: Ранения", value: "2134" }, - { label: "Соулмейты: Сны", value: "2414" }, - { label: "Соулмейты: Тактильный контакт", value: "2190" }, - { label: "Соулмейты: Татуировки", value: "2711" }, - { label: "Соулмейты: Физические проявления", value: "2864" }, - { label: "Социальная фантастика", value: "591" }, - { label: "Социальные темы и мотивы", value: "1017" }, - { label: "Социальные эксперименты", value: "2756" }, - { label: "Социальный паразитизм", value: "2444" }, - { label: "Социофобия", value: "826" }, - { label: "Спарринги", value: "1575" }, - { label: "Спасатели", value: "392" }, - { label: "Спасение жизни", value: "1299" }, - { label: "Спасение мира", value: "812" }, - { label: "Спектрофилия", value: "2634" }, - { label: "Спецагенты", value: "401" }, - { label: "Спиритизм", value: "1478" }, - { label: "Сплошинг", value: "424" }, - { label: "Спонтанный секс", value: "2918" }, - { label: "Спорт", value: "15" }, - { label: "Спортзалы", value: "1359" }, - { label: "Сражения", value: "2868" }, - { label: "Средневековье", value: "238" }, - { label: "Ссоры / Конфликты", value: "645" }, - { label: "Стаи", value: "2884" }, - { label: "Сталкеры / Диггеры (субкультура)", value: "1029" }, - { label: "Сталкинг", value: "605" }, - { label: "Становление героя", value: "680" }, - { label: "Стёб", value: "1690" }, - { label: "Стереотипы", value: "809" }, - { label: "Стимпанк", value: "25" }, - { label: "Стимуляция руками", value: "225" }, - { label: "Стихи", value: "1692" }, - { label: "Стихийные бедствия", value: "1352" }, - { label: "Стихотворные вставки", value: "2404" }, - { label: "СтихоТворцы", value: "3015" }, - { label: "Стокгольмский синдром / Лимский синдром", value: "1217" }, - { label: "Столетняя война", value: "2243" }, - { label: "Сторонний рассказчик", value: "1383" }, - { label: "Стоунпанк", value: "1987" }, - { label: "Страдания", value: "2009" }, - { label: "Странногеддон", value: "1882" }, - { label: "Страны Балтии", value: "1031" }, - { label: "Страпоны", value: "380" }, - { label: "Страсть", value: "1955" }, - { label: "Страх перед родителями", value: "2332" }, - { label: "Стрельба из лука", value: "1791" }, - { label: "Стримеры / Ютуберы", value: "1473" }, - { label: "Стрип-клубы", value: "79" }, - { label: "Стрит-арт", value: "1012" }, - { label: "Строители", value: "1774" }, - { label: "Студенты", value: "274" }, - { label: "Студенты по обмену", value: "859" }, - { label: "Студенческие городки", value: "753" }, - { label: "Субкультуры", value: "1061" }, - { label: "Субординация", value: "1099" }, - { label: "Суд", value: "827" }, - { label: "Суккубы / Инкубы", value: "334" }, - { label: "Сумасшествие", value: "1239" }, - { label: "Сунагакуре", value: "2476" }, - { label: "Супергерои", value: "67" }, - { label: "Суперзлодеи", value: "1205" }, - { label: "Супермаркеты", value: "843" }, - { label: "Суррогатная беременность", value: "1427" }, - { label: "Сухой закон", value: "2100" }, - { label: "Сухой оргазм", value: "2818" }, - { label: "Сфера ИТ", value: "2534" }, - { label: "Сфинксы", value: "1349" }, - { label: "Сценарий (стилизация)", value: "323" }, - { label: "Счастливый финал", value: "3" }, - { label: "США", value: "640" }, - { label: "Съемочная площадка", value: "410" }, - { label: "Сын Тьмы", value: "2175" }, - { label: "Сэнгоку Джидай", value: "2380" }, - { label: "Сэнгоку Дзидай", value: "2834" }, - { label: "Сэцубун", value: "2969" }, - { label: "Сюрреализм / Фантасмагория", value: "872" }, - { label: "Т/И / Л/И", value: "167" }, - { label: "Таджикистан", value: "2974" }, - { label: "Таиланд", value: "1034" }, - { label: "Тайна происхождения", value: "662" }, - { label: "Тайная личность", value: "194" }, - { label: "Тайная сущность", value: "1512" }, - { label: "Тайны / Секреты", value: "906" }, - { label: "Тайные друзья (игра)", value: "2908" }, - { label: "Тайные организации", value: "572" }, - { label: "Тайные поклонники", value: "1374" }, - { label: "Тайный НапиСанта", value: "2972" }, - { label: "Таксисты", value: "2679" }, - { label: "Тактильный голод", value: "2197" }, - { label: "Тактильный контакт", value: "2875" }, - { label: "Танабата", value: "2340" }, - { label: "Танцы", value: "108" }, - { label: "Танцы на пилоне", value: "1370" }, - { label: "Таро", value: "642" }, - { label: "Тату-салоны", value: "324" }, - { label: "Татуировки", value: "327" }, - { label: "Твинцест", value: "1652" }, - { label: "Творческий кризис", value: "2107" }, - { label: "Театры", value: "195" }, - { label: "Телекинез", value: "951" }, - { label: "Телепатия", value: "127" }, - { label: "Телепортация", value: "1794" }, - { label: "Телесные жидкости", value: "1220" }, - { label: "Телесные наказания", value: "132" }, - { label: "Телесный хоррор", value: "212" }, - { label: "Телохранители", value: "400" }, - { label: "Темная сторона (Гарри Поттер)", value: "1937" }, - { label: "Темная сторона Силы", value: "1946" }, - { label: "Темная Эра (Bungou Stray Dogs)", value: "2494" }, - { label: "Темное прошлое", value: "2229" }, - { label: "Темное фэнтези", value: "1963" }, - { label: "Темные властелины", value: "1224" }, - { label: "Темные эльфы", value: "2597" }, - { label: "Темный романтизм", value: "2128" }, - { label: "Темы ментального здоровья", value: "2344" }, - { label: "Темы этики и морали", value: "1106" }, - { label: "Теннис", value: "1066" }, - { label: "Тентакли", value: "129" }, - { label: "Теория инверсии", value: "1980" }, - { label: "Теория Одурманивания", value: "2493" }, - { label: "Термокинез", value: "2793" }, - { label: "Террористы", value: "556" }, - { label: "Теслапанк", value: "1988" }, - { label: "Техники", value: "1272" }, - { label: "Техногенные катастрофы", value: "526" }, - { label: "Технокинез", value: "1271" }, - { label: "Технологии", value: "1232" }, - { label: "Технотриллер", value: "649" }, - { label: "Течка / Гон", value: "283" }, - { label: "Тим Дрейк — Джокер-младший", value: "2454" }, - { label: "Тим Дрейк — Кэтлэд", value: "2453" }, - { label: "Тихий секс", value: "1185" }, - { label: "Товарищи по несчастью", value: "2666" }, - { label: "Токсичные родственники", value: "2008" }, - { label: "Том Реддл — не Темный Лорд", value: "2394" }, - { label: "Томбои", value: "565" }, - { label: "Томгерлз", value: "848" }, - { label: "Торговля органами", value: "1358" }, - { label: "Торговцы", value: "2098" }, - { label: "Торговые центры", value: "1416" }, - { label: "Тоталитаризм", value: "1169" }, - { label: "Травники / Травницы", value: "1211" }, - { label: "Трагедия", value: "919" }, - { label: "Трагикомедия", value: "1454" }, - { label: "Традиции", value: "1463" }, - { label: "Трансгендерные персонажи", value: "175" }, - { label: "Трансплантация", value: "2364" }, - { label: "Трансфобия", value: "420" }, - { label: "Тревожное расстройство личности", value: "1914" }, - { label: "Тревожность", value: "1318" }, - { label: "Трейлеры", value: "785" }, - { label: "Тренировки / Обучение", value: "876" }, - { label: "Третий лишний", value: "1176" }, - { label: "Третья мировая", value: "624" }, - { label: "Три корейских государства", value: "2322" }, - { label: "Трикстеры", value: "1507" }, - { label: "Триллер", value: "169" }, - { label: "Трилогия Юникрона", value: "2378" }, - { label: "Трипофобия", value: "2342" }, - { label: "Трисам", value: "758" }, - { label: "Трихотилломания", value: "2185" }, - { label: "Тролли", value: "190" }, - { label: "Трудные отношения с родителями", value: "1490" }, - { label: "Трудный характер", value: "2123" }, - { label: "Трудоголизм", value: "1848" }, - { label: "Трущобы", value: "2822" }, - { label: "Туалетный юмор", value: "1247" }, - { label: "Туберкулез", value: "2163" }, - { label: "Турция", value: "794" }, - { label: "Тщеславие", value: "2578" }, - { label: "Тюрьмы / Темницы", value: "117" }, - { label: "Тяжелое детство", value: "2614" }, - { label: "Убийства", value: "621" }, - { label: "Убийственная пара", value: "1918" }, - { label: "Убийца поневоле", value: "2671" }, - { label: "Уважение", value: "2688" }, - { label: "Ужасы", value: "1679" }, - { label: "Узбекистан", value: "1293" }, - { label: "Уизлигады", value: "1862" }, - { label: "Украина", value: "716" }, - { label: "Укрытия", value: "199" }, - { label: "Уличные артисты", value: "2550" }, - { label: "Уличные гонки", value: "880" }, - { label: "Умбракинез", value: "2355" }, - { label: "Универсалы", value: "657" }, - { label: "Унижения", value: "1319" }, - { label: "Упоминания аддикций", value: "2848" }, - { label: "Упоминания алкоголя", value: "2415" }, - { label: "Упоминания беременности", value: "2057" }, - { label: "Упоминания войны", value: "2707" }, - { label: "Упоминания жестокости", value: "2447" }, - { label: "Упоминания зоофилии", value: "2620" }, - { label: "Упоминания измены", value: "2876" }, - { label: "Упоминания изнасилования", value: "521" }, - { label: "Упоминания инвалидности", value: "2705" }, - { label: "Упоминания инцеста", value: "2285" }, - { label: "Упоминания каннибализма", value: "2427" }, - { label: "Упоминания курения", value: "2450" }, - { label: "Упоминания мужской беременности", value: "2226" }, - { label: "Упоминания наркотиков", value: "144" }, - { label: "Упоминания насилия", value: "2207" }, - { label: "Упоминания нездоровых отношений", value: "2892" }, - { label: "Упоминания проституции", value: "2618" }, - { label: "Упоминания пыток", value: "2410" }, - { label: "Упоминания расизма", value: "2737" }, - { label: "Упоминания религии", value: "1048" }, - { label: "Упоминания самоубийства", value: "77" }, - { label: "Упоминания секса", value: "2747" }, - { label: "Упоминания селфхарма", value: "2105" }, - { label: "Упоминания смертей", value: "2081" }, - { label: "Упоминания смертей животных", value: "2211" }, - { label: "Упоминания телесного хоррора", value: "2466" }, - { label: "Упоминания терроризма", value: "774" }, - { label: "Упоминания убийств", value: "1501" }, - { label: "Управление оргазмом", value: "118" }, - { label: "Управление стихиями", value: "2091" }, - { label: "Уретральное проникновение", value: "1469" }, - { label: "Уро-кинк", value: "762" }, - { label: "Условное бессмертие", value: "2117" }, - { label: "Уся / Сянься", value: "2714" }, - { label: "Утопия", value: "350" }, - { label: "Утраченная тройка", value: "2535" }, - { label: "Утренний секс", value: "2882" }, - { label: "Уход за персонажами с инвалидностью", value: "2133" }, - { label: "Ухудшение отношений", value: "1219" }, - { label: "Учебные заведения", value: "1694" }, - { label: "Ученые", value: "402" }, - { label: "Уют", value: "2738" }, - { label: "Фавориты", value: "2135" }, - { label: "Фамильяры", value: "1045" }, - { label: "Фан-Бинго", value: "2957" }, - { label: "Фан-Фанты", value: "2953" }, - { label: "Фандомная аналитика", value: "742" }, - { label: "Фандомная Битва", value: "253" }, - { label: "Фансервис", value: "2483" }, - { label: "Фантастика", value: "1670" }, - { label: "Фастберн", value: "2016" }, - { label: "Фастфуд / Закусочные", value: "1025" }, - { label: "Феи", value: "191" }, - { label: "Фельчинг", value: "2368" }, - { label: "Фемдом", value: "54" }, - { label: "Феминистские темы и мотивы", value: "523" }, - { label: "Феминитивы", value: "390" }, - { label: "Фениксы", value: "1215" }, - { label: "Феодализм", value: "1504" }, - { label: "Фермы / Ранчо", value: "329" }, - { label: "Фестивали", value: "1006" }, - { label: "Фехтование", value: "1775" }, - { label: "Фиггинг", value: "1439" }, - { label: "Фигурное катание", value: "460" }, - { label: "Физиотерапия", value: "2222" }, - { label: "Физическая сверхсила", value: "2880" }, - { label: "Фикрайтеры / Фикридеры", value: "1284" }, - { label: "Фиксированная раскладка", value: "1344" }, - { label: "Фиктивные отношения", value: "308" }, - { label: "Фиктивный брак", value: "34" }, - { label: "Философия", value: "1675" }, - { label: "Финляндия", value: "1133" }, - { label: "Фистинг", value: "151" }, - { label: "Флафф", value: "1667" }, - { label: "Флирт", value: "349" }, - { label: "Флот", value: "846" }, - { label: "Фобии", value: "977" }, - { label: "Фольклор и предания", value: "1273" }, - { label: "Форнифилия", value: "580" }, - { label: "Фотографы", value: "348" }, - { label: "Фотокинез", value: "1805" }, - { label: "Франция", value: "691" }, - { label: "Фред Уизли жив", value: "2941" }, - { label: "Фроттаж", value: "96" }, - { label: "Фуд-плей", value: "509" }, - { label: "Фуд-фетиш", value: "2168" }, - { label: "Фурри", value: "996" }, - { label: "Фут-фетиш", value: "432" }, - { label: "Футбол", value: "458" }, - { label: "Фэйри", value: "2028" }, - { label: "Фэнтези", value: "1669" }, - { label: "Хакеры", value: "340" }, - { label: "Ханами", value: "1155" }, - { label: "Ханахаки", value: "45" }, - { label: "Ханжество", value: "882" }, - { label: "Характерная для канона жестокость", value: "896" }, - { label: "Харассмент", value: "477" }, - { label: "Хиерофилия", value: "2366" }, - { label: "Химеры", value: "816" }, - { label: "Химическое оружие", value: "1186" }, - { label: "Химэдэрэ / Оджидэрэ", value: "1363" }, - { label: "Хип-хоп (субкультура)", value: "1822" }, - { label: "Хиппи", value: "784" }, - { label: "Хиромантия", value: "2749" }, - { label: "Хирургическая коррекция пола", value: "1249" }, - { label: "Хирургические операции", value: "1845" }, - { label: "Хобби", value: "1161" }, - { label: "Хогсмид", value: "2388" }, - { label: "Хоккей", value: "828" }, - { label: "Холодная война", value: "2140" }, - { label: "Холодное оружие", value: "1187" }, - { label: "Хорватия", value: "1433" }, - { label: "Хороший плохой финал", value: "1266" }, - { label: "Хронические заболевания", value: "1267" }, - { label: "Хронокинез", value: "1447" }, - { label: "Хронофантастика", value: "56" }, - { label: "Хтонические существа", value: "504" }, - { label: "Художники", value: "140" }, - { label: "Хуманизация", value: "177" }, - { label: "Хэллоуин", value: "205" }, - { label: "Хюльдры", value: "1397" }, - { label: "Цветочные магазины", value: "164" }, - { label: "Целители", value: "1107" }, - { label: "Церкви", value: "533" }, - { label: "Цикличность", value: "1979" }, - { label: "Цирки", value: "259" }, - { label: "Цукими", value: "1798" }, - { label: "Цундэрэ", value: "1137" }, - { label: "Цыгане", value: "1091" }, - { label: "Чайлдфри", value: "592" }, - { label: "Чайные церемонии", value: "2416" }, - { label: "Частичный ООС", value: "1409" }, - { label: "Частные детективы", value: "427" }, - { label: "Черная археология", value: "2503" }, - { label: "Черная мораль", value: "2438" }, - { label: "Чернобыльская катастрофа", value: "775" }, - { label: "Черный юмор", value: "66" }, - { label: "Чехия", value: "1021" }, - { label: "Чиновники", value: "1991" }, - { label: "Чирлидинг", value: "1431" }, - { label: "Чистокровные AU (Гарри Поттер)", value: "1905" }, - { label: "Чосон", value: "571" }, - { label: "Чувство вины", value: "902" }, - { label: "Чумные доктора", value: "1125" }, - { label: "Чхусок", value: "2973" }, - { label: "Шаманы", value: "484" }, - { label: "Шантаж", value: "569" }, - { label: "Шармбатон", value: "2733" }, - { label: "Швейцария", value: "1022" }, - { label: "Шейпшифтеры", value: "29" }, - { label: "Шелки", value: "2431" }, - { label: "Шифры", value: "2232" }, - { label: "Школьная иерархия", value: "2787" }, - { label: "Школьники", value: "2566" }, - { label: "Школьные годы Тома Реддла", value: "1913" }, - { label: "Школьные ОтМетки", value: "3017" }, - { label: "Школьные поездки", value: "2481" }, - { label: "Школьный роман", value: "2440" }, - { label: "Шопинг", value: "864" }, - { label: "Шоу-бизнес", value: "17" }, - { label: "Шпионы", value: "148" }, - { label: "Шрамирование", value: "891" }, - { label: "Шрамы", value: "328" }, - { label: "Эвтаназия", value: "1102" }, - { label: "Эгоизм", value: "2071" }, - { label: "Эдвардианская эпоха", value: "2975" }, - { label: "Эзотерические темы и мотивы", value: "2801" }, - { label: "Эйблизм", value: "453" }, - { label: "Эйдетическая память", value: "975" }, - { label: "Эйфория", value: "2458" }, - { label: "Экзамены", value: "2591" }, - { label: "Экзистенциальный кризис", value: "1200" }, - { label: "Экзорцизм", value: "494" }, - { label: "Экологи / Биологи", value: "631" }, - { label: "Экологический кризис", value: "485" }, - { label: "Экономический кризис", value: "1547" }, - { label: "Эксаудиризм", value: "2151" }, - { label: "Эксгибиционизм", value: "489" }, - { label: "Эксперимент", value: "1686" }, - { label: "Экстрасенсы", value: "371" }, - { label: "Экшн", value: "1673" }, - { label: "Электрокинез", value: "1857" }, - { label: "Электростимуляция", value: "807" }, - { label: "Элементы ангста", value: "2696" }, - { label: "Элементы гета", value: "1714" }, - { label: "Элементы дарка", value: "2703" }, - { label: "Элементы детектива", value: "2698" }, - { label: "Элементы драмы", value: "2697" }, - { label: "Элементы других видов отношений", value: "454" }, - { label: "Элементы мистики", value: "1324" }, - { label: "Элементы психологии", value: "2824" }, - { label: "Элементы романтики", value: "2742" }, - { label: "Элементы слэша", value: "1715" }, - { label: "Элементы ужасов", value: "2721" }, - { label: "Элементы фемслэша", value: "1716" }, - { label: "Элементы флаффа", value: "2731" }, - { label: "Элементы юмора / Элементы стёба", value: "2011" }, - { label: "Эльфы", value: "44" }, - { label: "Эметофилия", value: "1434" }, - { label: "Эмо", value: "641" }, - { label: "Эмоциональная одержимость", value: "1270" }, - { label: "Эмпатия", value: "1177" }, - { label: "Энергетический вампиризм", value: "818" }, - { label: "Эпидемии", value: "619" }, - { label: "Эпизод 23.5", value: "2469" }, - { label: "Эпилепсия", value: "1511" }, - { label: "Эпилог? Какой эпилог?", value: "2651" }, - { label: "Эпоха Бакумацу", value: "1472" }, - { label: "Эпоха Мэйдзи", value: "1435" }, - { label: "Эпоха Тайсё", value: "2015" }, - { label: "Эрик Киллмонгер жив", value: "2897" }, - { label: "Эрогуро", value: "1731" }, - { label: "Эротическая дрессировка", value: "2026" }, - { label: "Эротическая лактация", value: "284" }, - { label: "Эротическая мумификация", value: "415" }, - { label: "Эротическая сверхстимуляция", value: "1245" }, - { label: "Эротические наказания", value: "125" }, - { label: "Эротические ролевые игры", value: "111" }, - { label: "Эротические сны", value: "128" }, - { label: "Эротические фантазии", value: "561" }, - { label: "Эротический массаж", value: "1518" }, - { label: "Эротический перенос", value: "744" }, - { label: "Эротомания", value: "2922" }, - { label: "Эскапизм", value: "1552" }, - { label: "Эскорты", value: "922" }, - { label: "Эстетика", value: "2021" }, - { label: "ЭТЕРНА", value: "2948" }, - { label: "Этнические анклавы", value: "2732" }, - { label: "Этническое фэнтези", value: "667" }, - { label: "Эффект бабочки", value: "1572" }, - { label: "Ювелиры", value: "2964" }, - { label: "Южная Америка", value: "832" }, - { label: "Южная готика", value: "1077" }, - { label: "Южная Корея", value: "674" }, - { label: "Юмор", value: "1666" }, - { label: "Юристы", value: "333" }, - { label: "Я никогда не... (игра)", value: "1436" }, - { label: "Явное согласие", value: "1569" }, - { label: "Ядерная война", value: "889" }, - { label: "Язык жестов", value: "2962" }, - { label: "Язык животных", value: "1327" }, - { label: "Язык растений", value: "2622" }, - { label: "Язык цветов", value: "272" }, - { label: "Ямадад", value: "2916" }, - { label: "Янгирэ", value: "1257" }, - { label: "Яндэрэ", value: "1136" }, - { label: "Яогуаи", value: "2347" }, - { label: "Япония", value: "665" }, - { label: "Японские фестивали", value: "2555" }, - { label: "Ящеролюди", value: "682" }, - { label: "Abuse/Comfort", value: "2599" }, - { label: "Aged down", value: "229" }, - { label: "Aged up", value: "4" }, - { label: "Artfic", value: "68" }, - { label: "AU", value: "1683" }, - { label: "AU: Альтернативные способности", value: "2086" }, - { label: "AU: Без апокалипсиса", value: "2051" }, - { label: "AU: Без войны", value: "2305" }, - { label: "AU: Без магии", value: "1052" }, - { label: "AU: Без мистики", value: "2489" }, - { label: "AU: Без сверхспособностей", value: "1053" }, - { label: "AU: Без супергероев", value: "1152" }, - { label: "AU: Все гражданские", value: "2797" }, - { label: "AU: Все друзья", value: "2552" }, - { label: "AU: Все люди", value: "1151" }, - { label: "AU: Все хорошо", value: "2124" }, - { label: "AU: Другая страна", value: "2165" }, - { label: "AU: Другая эпоха", value: "2452" }, - { label: "AU: Другое детство", value: "2360" }, - { label: "AU: Другое знакомство", value: "2217" }, - { label: "AU: Другое семейное положение", value: "2902" }, - { label: "AU: Не родственники", value: "2167" }, - { label: "AU: Профессиональные герои (BNHA)", value: "2924" }, - { label: "AU: Родственники", value: "2164" }, - { label: "AU: Школа", value: "2532" }, - { label: "AU: Age swap", value: "917" }, - { label: "AU: Kitty Gang", value: "2928" }, - { label: "AU: Race swap", value: "933" }, - { label: "AU: Reverse", value: "1156" }, - { label: "AU: Role swap", value: "1054" }, - { label: "Authors Time", value: "2959" }, - { label: "BDSM", value: "1646" }, - { label: "BDSM-вселенная", value: "1078" }, - { label: "BDSM: Домспейс", value: "1444" }, - { label: "BDSM: Дроп", value: "1411" }, - { label: "BDSM: Сабспейс", value: "1410" }, - { label: "BDSM: Aftercare", value: "1523" }, - { label: "BEAST (Bungou Stray Dogs)", value: "2457" }, - { label: "Blackwatch", value: "2116" }, - { label: "Body inflation", value: "389" }, - { label: "Character study", value: "363" }, - { label: "Cockwarming", value: "318" }, - { label: "Dark academia", value: "2430" }, - { label: "DDLG / DDLB / MDLG / MDLB", value: "1033" }, - { label: "Dirty talk", value: "139" }, - { label: "Doggy style", value: "1361" }, - { label: "Dollification", value: "2780" }, - { label: "Dramione Authors Tournament", value: "2950" }, - { label: "EIQ", value: "271" }, - { label: "ER", value: "1687" }, - { label: "Final Haikyuu Quest", value: "2652" }, - { label: "Fix-it", value: "1" }, - { label: "Frenemies", value: "666" }, - { label: "Gangbang", value: "315" }, - { label: "Glory hole", value: "2188" }, - { label: "Golden Age Overwatch", value: "2112" }, - { label: "GOLockdown", value: "2391" }, - { label: "Gun play", value: "252" }, - { label: "Hurt/Comfort", value: "1682" }, - { label: "Hydra!AU", value: "1931" }, - { label: "Ironqrow week", value: "2209" }, - { label: "Kimetsu Gakuen", value: "2574" }, - { label: "Knife play", value: "152" }, - { label: "KPOP-AUFEST", value: "1851" }, - { label: "LARP", value: "1510" }, - { label: "LOVE ОтМетки", value: "2981" }, - { label: "Maleval week", value: "2382" }, - { label: "Marvel ГФИ", value: "2896" }, - { label: "Mate or die", value: "375" }, - { label: "Mirror!verse (Звездный путь)", value: "2899" }, - { label: "Moresome", value: "759" }, - { label: "N раз", value: "263" }, - { label: "Omnic Crisis Era", value: "2111" }, - { label: "ORIGINAL'S 2021", value: "2939" }, - { label: "Parentlock", value: "2053" }, - { label: "Patronus of Dramione", value: "2958" }, - { label: "Post-Fall of Overwatch", value: "2114" }, - { label: "Post-Recall", value: "2115" }, - { label: "PWP", value: "1680" }, - { label: "Rape/Revenge", value: "2195" }, - { label: "Reverse Falls", value: "1879" }, - { label: "RofR ДраМиВояж", value: "2954" }, - { label: "RST", value: "815" }, - { label: "RTFM", value: "2327" }, - { label: "Service top / Power bottom", value: "563" }, - { label: "Shingeki no Kyojin High School AU", value: "2037" }, - { label: "Shingeki! Kyojin Chuugakkou", value: "2038" }, - { label: "Sickfic", value: "422" }, - { label: "Songfic", value: "1684" }, - { label: "Spider-son & Iron-dad", value: "1885" }, - { label: "Sugar daddy", value: "106" }, - { label: "Sugar mommy", value: "160" }, - { label: "Superfamily (Мстители)", value: "2623" }, - { label: "Superior Iron Man", value: "2676" }, - { label: "Talon (Overwatch)", value: "2110" }, - { label: "The Big Four / The Super Six", value: "1954" }, - { label: "Trench AU", value: "2387" }, - { label: "TYL", value: "1933" }, - { label: "Underage", value: "1658" }, - { label: "URT", value: "2761" }, - { label: "UST", value: "1709" }, - { label: "Versefic", value: "2729" }, - { label: "Videofic", value: "2480" }, - { label: "Womance", value: "265" }, - { label: "X век", value: "240" }, - { label: "XI век", value: "241" }, - { label: "XII век", value: "242" }, - { label: "XIII век", value: "243" }, - { label: "XIV век", value: "244" }, - { label: "XIX век", value: "249" }, - { label: "XV век", value: "245" }, - { label: "XVI век", value: "246" }, - { label: "XVII век", value: "247" }, - { label: "XVIII век", value: "248" }, - { label: "XX век", value: "1004" }, - ], - inputType: filterInputs_1.FilterInputs.Picker, - }, -]; -exports.fetchImage = fetch_1.fetchFile; diff --git a/js/plugins/russian/jaomix.js b/js/plugins/russian/jaomix.js deleted file mode 100644 index dcb05fc..0000000 --- a/js/plugins/russian/jaomix.js +++ /dev/null @@ -1,299 +0,0 @@ -"use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.fetchImage = exports.filters = exports.searchNovels = exports.parseChapter = exports.parseNovelAndChapters = exports.popularNovels = exports.icon = exports.version = exports.site = exports.name = exports.id = void 0; -const filterInputs_1 = require("@libs/filterInputs"); -const fetch_1 = require("@libs/fetch"); -const novelStatus_1 = require("@libs/novelStatus"); -const cheerio_1 = require("cheerio"); -exports.id = "jaomix.ru"; -exports.name = "Jaomix"; -exports.site = "https://jaomix.ru"; -exports.version = "1.0.0"; -exports.icon = "src/ru/jaomix/icon.png"; -const popularNovels = function (page, { showLatestNovels, filters }) { - return __awaiter(this, void 0, void 0, function* () { - let url = exports.site + "/?searchrn"; - if ((filters === null || filters === void 0 ? void 0 : filters.lang) instanceof Array) { - url += filters.lang.map((lang, idx) => `&lang[${idx}]=${lang}`).join(""); - } - if ((filters === null || filters === void 0 ? void 0 : filters.genre) instanceof Array) { - url += filters.genre.map((genre, idx) => `&genre[${idx}]=${genre}`).join(""); - } - if ((filters === null || filters === void 0 ? void 0 : filters.delgenre) instanceof Array) { - url += filters.delgenre.map((genre, idx) => `&delgenre[${idx}]=del ${genre}`).join(""); - } - url += "&sortcountchapt=" + ((filters === null || filters === void 0 ? void 0 : filters.sortcountchapt) || "1"); - url += "&sortdaycreate=" + ((filters === null || filters === void 0 ? void 0 : filters.sortdaycreate) || "1"); - url += "&sortby=" + (showLatestNovels ? "upd" : (filters === null || filters === void 0 ? void 0 : filters.sortby) || "topweek"); - url += "&gpage=" + page; - const result = yield (0, fetch_1.fetchApi)(url); - let body = yield result.text(); - const loadedCheerio = (0, cheerio_1.load)(body); - let novels = []; - loadedCheerio('div[class="block-home"] > div[class="one"]').each(function () { - var _a; - const name = loadedCheerio(this) - .find('div[class="img-home"] > a') - .attr("title"); - const cover = (_a = loadedCheerio(this) - .find('div[class="img-home"] > a > img') - .attr("src")) === null || _a === void 0 ? void 0 : _a.replace("-150x150", ""); - const url = loadedCheerio(this) - .find('div[class="img-home"] > a') - .attr("href"); - if (!name || !url) - return; - novels.push({ name, cover, url }); - }); - return novels; - }); -}; -exports.popularNovels = popularNovels; -const parseNovelAndChapters = function (novelUrl) { - return __awaiter(this, void 0, void 0, function* () { - const result = yield (0, fetch_1.fetchApi)(novelUrl); - const body = yield result.text(); - const loadedCheerio = (0, cheerio_1.load)(body); - let novel = { - url: novelUrl, - }; - novel.name = loadedCheerio('div[class="desc-book"] > h1').text().trim(); - novel.cover = loadedCheerio('div[class="img-book"] > img').attr("src"); - novel.summary = loadedCheerio('div[id="desc-tab"]').text().trim(); - loadedCheerio("#info-book > p").each(function () { - let text = loadedCheerio(this).text().replace(/,/g, "").split(" "); - if (text[0] === "Автор:") { - novel.author = text.splice(1).join(" "); - } - else if (text[0] === "Жанры:") { - novel.genres = text.splice(1).join(","); - } - else if (text[0] === "Статус:") { - novel.status = text.includes("продолжается") - ? novelStatus_1.NovelStatus.Ongoing - : novelStatus_1.NovelStatus.Completed; - } - }); - const chapters = []; - loadedCheerio(".download-chapter div.title").each(function () { - const name = loadedCheerio(this).find("a").attr("title"); - const releaseTime = loadedCheerio(this).find("time").text(); - const url = loadedCheerio(this).find("a").attr("href"); - if (!name || !url) - return; - chapters.push({ name, releaseTime, url }); - }); - novel.chapters = chapters.reverse(); - return novel; - }); -}; -exports.parseNovelAndChapters = parseNovelAndChapters; -const parseChapter = function (chapterUrl) { - return __awaiter(this, void 0, void 0, function* () { - const result = yield (0, fetch_1.fetchApi)(chapterUrl); - const body = yield result.text(); - const loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('div[class="adblock-service"]').remove(); - const chapterText = loadedCheerio('div[class="entry-content"]').html(); - return chapterText; - }); -}; -exports.parseChapter = parseChapter; -const searchNovels = function (searchTerm) { - return __awaiter(this, void 0, void 0, function* () { - const url = `${exports.site}/?searchrn=${searchTerm}&but=Поиск по названию&sortby=upd`; - const result = yield (0, fetch_1.fetchApi)(url); - let body = yield result.text(); - const loadedCheerio = (0, cheerio_1.load)(body); - let novels = []; - loadedCheerio('div[class="block-home"] > div[class="one"]').each(function () { - var _a; - const name = loadedCheerio(this) - .find('div[class="img-home"] > a') - .attr("title"); - const cover = (_a = loadedCheerio(this) - .find('div[class="img-home"] > a > img') - .attr("src")) === null || _a === void 0 ? void 0 : _a.replace("-150x150", ""); - const url = loadedCheerio(this) - .find('div[class="img-home"] > a') - .attr("href"); - if (!name || !url) - return; - novels.push({ name, cover, url }); - }); - return novels; - }); -}; -exports.searchNovels = searchNovels; -exports.filters = [ - { - key: "sortby", - label: "Сортировка:", - values: [ - { label: "Топ недели", value: "topweek" }, - { label: "По алфавиту", value: "alphabet" }, - { label: "По дате обновления", value: "upd" }, - { label: "По дате создания", value: "new" }, - { label: "По просмотрам", value: "count" }, - { label: "Топ года", value: "topyear" }, - { label: "Топ дня", value: "topday" }, - { label: "Топ за все время", value: "alltime" }, - { label: "Топ месяца", value: "topmonth" }, - ], - inputType: filterInputs_1.FilterInputs.Picker, - }, - { - key: "sortdaycreate", - label: "Дата добавления:", - values: [ - { label: "Любое", value: "1" }, - { label: "От 120 до 180 дней", value: "1218" }, - { label: "От 180 до 365 дней", value: "1836" }, - { label: "От 30 до 60 дней", value: "3060" }, - { label: "От 365 дней", value: "365" }, - { label: "От 60 до 90 дней", value: "6090" }, - { label: "От 90 до 120 дней", value: "9012" }, - { label: "Послед. 30 дней", value: "30" }, - ], - inputType: filterInputs_1.FilterInputs.Picker, - }, - { - key: "sortcountchapt", - label: "Количество глав:", - values: [ - { label: "Любое кол-во глав", value: "1" }, - { label: "До 500", value: "500" }, - { label: "От 1000 до 2000", value: "1020" }, - { label: "От 2000 до 3000", value: "2030" }, - { label: "От 3000 до 4000", value: "3040" }, - { label: "От 4000", value: "400" }, - { label: "От 500 до 1000", value: "510" }, - ], - inputType: filterInputs_1.FilterInputs.Picker, - }, - { - key: "genre", - label: "Жанры:", - values: [ - { label: "Боевые Искусства", value: "Боевые Искусства" }, - { label: "Виртуальный Мир", value: "Виртуальный Мир" }, - { label: "Гарем", value: "Гарем" }, - { label: "Детектив", value: "Детектив" }, - { label: "Драма", value: "Драма" }, - { label: "Игра", value: "Игра" }, - { label: "Истории из жизни", value: "Истории из жизни" }, - { label: "Исторический", value: "Исторический" }, - { label: "История", value: "История" }, - { label: "Исэкай", value: "Исэкай" }, - { label: "Комедия", value: "Комедия" }, - { label: "Меха", value: "Меха" }, - { label: "Мистика", value: "Мистика" }, - { label: "Научная Фантастика", value: "Научная Фантастика" }, - { label: "Повседневность", value: "Повседневность" }, - { label: "Постапокалипсис", value: "Постапокалипсис" }, - { label: "Приключения", value: "Приключения" }, - { label: "Психология", value: "Психология" }, - { label: "Романтика", value: "Романтика" }, - { label: "Сверхъестественное", value: "Сверхъестественное" }, - { label: "Сёнэн", value: "Сёнэн" }, - { label: "Сёнэн-ай", value: "Сёнэн-ай" }, - { label: "Спорт", value: "Спорт" }, - { label: "Сэйнэн", value: "Сэйнэн" }, - { label: "Сюаньхуа", value: "Сюаньхуа" }, - { label: "Трагедия", value: "Трагедия" }, - { label: "Триллер", value: "Триллер" }, - { label: "Фантастика", value: "Фантастика" }, - { label: "Фэнтези", value: "Фэнтези" }, - { label: "Хоррор", value: "Хоррор" }, - { label: "Школьная жизнь", value: "Школьная жизнь" }, - { label: "Шоунен", value: "Шоунен" }, - { label: "Экшн", value: "Экшн" }, - { label: "Этти", value: "Этти" }, - { label: "Юри", value: "Юри" }, - { label: "Adult", value: "Adult" }, - { label: "Ecchi", value: "Ecchi" }, - { label: "Josei", value: "Josei" }, - { label: "Lolicon", value: "Lolicon" }, - { label: "Mature", value: "Mature" }, - { label: "Shoujo", value: "Shoujo" }, - { label: "Wuxia", value: "Wuxia" }, - { label: "Xianxia", value: "Xianxia" }, - { label: "Xuanhuan", value: "Xuanhuan" }, - { label: "Yaoi", value: "Yaoi" }, - ], - inputType: filterInputs_1.FilterInputs.Checkbox, - }, - { - key: "delgenre", - label: "Исключить жанры:", - values: [ - { label: "Боевые Искусства", value: "Боевые Искусства" }, - { label: "Виртуальный Мир", value: "Виртуальный Мир" }, - { label: "Гарем", value: "Гарем" }, - { label: "Детектив", value: "Детектив" }, - { label: "Драма", value: "Драма" }, - { label: "Игра", value: "Игра" }, - { label: "Истории из жизни", value: "Истории из жизни" }, - { label: "Исторический", value: "Исторический" }, - { label: "История", value: "История" }, - { label: "Исэкай", value: "Исэкай" }, - { label: "Комедия", value: "Комедия" }, - { label: "Меха", value: "Меха" }, - { label: "Мистика", value: "Мистика" }, - { label: "Научная Фантастика", value: "Научная Фантастика" }, - { label: "Повседневность", value: "Повседневность" }, - { label: "Постапокалипсис", value: "Постапокалипсис" }, - { label: "Приключения", value: "Приключения" }, - { label: "Психология", value: "Психология" }, - { label: "Романтика", value: "Романтика" }, - { label: "Сверхъестественное", value: "Сверхъестественное" }, - { label: "Сёнэн", value: "Сёнэн" }, - { label: "Сёнэн-ай", value: "Сёнэн-ай" }, - { label: "Спорт", value: "Спорт" }, - { label: "Сэйнэн", value: "Сэйнэн" }, - { label: "Сюаньхуа", value: "Сюаньхуа" }, - { label: "Трагедия", value: "Трагедия" }, - { label: "Триллер", value: "Триллер" }, - { label: "Фантастика", value: "Фантастика" }, - { label: "Фэнтези", value: "Фэнтези" }, - { label: "Хоррор", value: "Хоррор" }, - { label: "Школьная жизнь", value: "Школьная жизнь" }, - { label: "Шоунен", value: "Шоунен" }, - { label: "Экшн", value: "Экшн" }, - { label: "Этти", value: "Этти" }, - { label: "Юри", value: "Юри" }, - { label: "Adult", value: "Adult" }, - { label: "Ecchi", value: "Ecchi" }, - { label: "Josei", value: "Josei" }, - { label: "Lolicon", value: "Lolicon" }, - { label: "Mature", value: "Mature" }, - { label: "Shoujo", value: "Shoujo" }, - { label: "Wuxia", value: "Wuxia" }, - { label: "Xianxia", value: "Xianxia" }, - { label: "Xuanhuan", value: "Xuanhuan" }, - { label: "Yaoi", value: "Yaoi" }, - ], - inputType: filterInputs_1.FilterInputs.Checkbox, - }, - { - key: "lang", - label: "Выбрать языки:", - values: [ - { label: "Английский", value: "Английский" }, - { label: "Китайский", value: "Китайский" }, - { label: "Корейский", value: "Корейский" }, - { label: "Японский", value: "Японский" }, - ], - inputType: filterInputs_1.FilterInputs.Checkbox, - }, -]; -exports.fetchImage = fetch_1.fetchFile; diff --git a/js/plugins/russian/novelTL.js b/js/plugins/russian/novelTL.js deleted file mode 100644 index 86e4d28..0000000 --- a/js/plugins/russian/novelTL.js +++ /dev/null @@ -1,855 +0,0 @@ -"use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.filters = exports.fetchImage = exports.searchNovels = exports.parseChapter = exports.parseNovelAndChapters = exports.popularNovels = exports.icon = exports.version = exports.site = exports.name = exports.id = void 0; -const filterInputs_1 = require("@libs/filterInputs"); -const defaultCover_1 = require("@libs/defaultCover"); -const fetch_1 = require("@libs/fetch"); -const novelStatus_1 = require("@libs/novelStatus"); -const cheerio_1 = require("cheerio"); -const dayjs_1 = __importDefault(require("dayjs")); -exports.id = "TL"; -exports.name = "NovelTL"; -exports.site = "https://novel.tl"; -exports.version = "1.0.0"; -exports.icon = "src/ru/noveltl/icon.png"; -const popularNovels = (page, { filters }) => __awaiter(void 0, void 0, void 0, function* () { - var _a, _b, _c; - const result = yield (0, fetch_1.fetchApi)(exports.site + "/api/site/v2/graphql", { - method: "post", - headers: { - Accept: "application/json, text/plain, */*", - "Accept-Language": "ru-RU,ru;q=0.8,en-US;q=0.5,en;q=0.3", - "Content-Type": "application/json", - }, - referrer: exports.site, - body: JSON.stringify({ - operationName: "Projects", - query: "query Projects($hostname:String! $filter:SearchFilter $page:Int $limit:Int){projects(section:{fullUrl:$hostname}filter:$filter page:{pageSize:$limit,pageNumber:$page}){content{title fullUrl covers{url}}}}", - variables: { - filter: { - tags: (filters === null || filters === void 0 ? void 0 : filters.tags) || [], - genres: (filters === null || filters === void 0 ? void 0 : filters.genres) || [], - }, - hostname: "novel.tl", - limit: 40, - page, - }, - }), - }); - const json = (yield result.json()); - let novels = []; - (_c = (_b = (_a = json.data) === null || _a === void 0 ? void 0 : _a.projects) === null || _b === void 0 ? void 0 : _b.content) === null || _c === void 0 ? void 0 : _c.forEach((novel) => { - var _a, _b; - return novels.push({ - name: novel.title, - url: "https://" + novel.fullUrl, - cover: ((_b = (_a = novel === null || novel === void 0 ? void 0 : novel.covers) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.url) - ? exports.site + novel.covers[0].url - : defaultCover_1.defaultCover, - }); - }); - return novels; -}); -exports.popularNovels = popularNovels; -const parseNovelAndChapters = (novelUrl) => __awaiter(void 0, void 0, void 0, function* () { - var _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s; - const result = yield (0, fetch_1.fetchApi)(exports.site + "/api/site/v2/graphql", { - method: "post", - headers: { - Accept: "application/json, text/plain, */*", - "Accept-Language": "ru-RU,ru;q=0.8,en-US;q=0.5,en;q=0.3", - "Content-Type": "application/json", - }, - referrer: exports.site, - body: JSON.stringify({ - operationName: "Book", - query: 'query Book($url:String){project(project:{fullUrl:$url}){title translationStatus fullUrl covers{url}persons(langs:["ru","en","*"],roles:["author","illustrator"]){role name{firstName lastName}}genres{nameRu nameEng}tags{nameRu nameEng}annotation{text}subprojects{content{title volumes{content{shortName chapters{title publishDate fullUrl published}}}}}}}', - variables: { - url: novelUrl, - }, - }), - }); - const json = (yield result.json()); - let novel = { - url: novelUrl, - name: (_d = json.data.project) === null || _d === void 0 ? void 0 : _d.title, - cover: ((_g = (_f = (_e = json.data.project) === null || _e === void 0 ? void 0 : _e.covers) === null || _f === void 0 ? void 0 : _f[0]) === null || _g === void 0 ? void 0 : _g.url) - ? exports.site + json.data.project.covers[0].url - : defaultCover_1.defaultCover, - summary: (_j = (_h = json.data.project) === null || _h === void 0 ? void 0 : _h.annotation) === null || _j === void 0 ? void 0 : _j.text, - status: ((_k = json.data.project) === null || _k === void 0 ? void 0 : _k.translationStatus) === "active" - ? novelStatus_1.NovelStatus.Ongoing - : novelStatus_1.NovelStatus.Completed, - }; - let genres = [(_l = json.data.project) === null || _l === void 0 ? void 0 : _l.tags, (_m = json.data.project) === null || _m === void 0 ? void 0 : _m.genres] - .flat() - .map((item) => (item === null || item === void 0 ? void 0 : item.nameRu) || (item === null || item === void 0 ? void 0 : item.nameEng)) - .filter((item) => item); - if (genres === null || genres === void 0 ? void 0 : genres.length) { - novel.genres = genres.join(", "); - } - (_p = (_o = json.data.project) === null || _o === void 0 ? void 0 : _o.persons) === null || _p === void 0 ? void 0 : _p.forEach((person) => { - var _a; - if (person.role == "author" && person.name.firstName) { - novel.author = - person.name.firstName + " " + (((_a = person.name) === null || _a === void 0 ? void 0 : _a.lastName) || ""); - } - }); - let novelChapters = []; - (_s = (_r = (_q = json.data.project) === null || _q === void 0 ? void 0 : _q.subprojects) === null || _r === void 0 ? void 0 : _r.content) === null || _s === void 0 ? void 0 : _s.forEach((work) => work.volumes.content.forEach((volume) => volume.chapters.forEach((chapter) => (chapter === null || chapter === void 0 ? void 0 : chapter.published) && - novelChapters.push({ - name: volume.shortName + " " + chapter.title, - url: "https://" + chapter.fullUrl, - releaseTime: (0, dayjs_1.default)(chapter.publishDate).format("LLL"), - })))); - novel.chapters = novelChapters; - return novel; -}); -exports.parseNovelAndChapters = parseNovelAndChapters; -const parseChapter = (chapterUrl) => __awaiter(void 0, void 0, void 0, function* () { - var _t, _u; - const result = yield (0, fetch_1.fetchApi)(exports.site + "/api/site/v2/graphql", { - method: "post", - headers: { - Accept: "application/json, text/plain, */*", - "Accept-Language": "ru-RU,ru;q=0.8,en-US;q=0.5,en;q=0.3", - "Content-Type": "application/json", - }, - referrer: exports.site, - body: JSON.stringify({ - query: "query($url:String){chapter(chapter:{fullUrl:$url}){text{text}}}", - variables: { - url: chapterUrl, - }, - }), - }); - const json = (yield result.json()); - const loadedCheerio = (0, cheerio_1.load)(((_u = (_t = json.data.chapter) === null || _t === void 0 ? void 0 : _t.text) === null || _u === void 0 ? void 0 : _u.text) || ""); - loadedCheerio("p > a[href]").each(function () { - let url = exports.site + loadedCheerio(this).attr("href"); - if (!url.startsWith("http")) { - url = exports.site + url; - } - loadedCheerio(this).find("picture").remove(); - loadedCheerio(this).removeAttr("href"); - loadedCheerio(``).appendTo(this); - }); - const chapterText = loadedCheerio.html(); - return chapterText; -}); -exports.parseChapter = parseChapter; -const searchNovels = (searchTerm) => __awaiter(void 0, void 0, void 0, function* () { - var _v, _w, _x; - const result = yield (0, fetch_1.fetchApi)(exports.site + "/api/site/v2/graphql", { - method: "post", - headers: { - Accept: "application/json, text/plain, */*", - "Accept-Language": "ru-RU,ru;q=0.8,en-US;q=0.5,en;q=0.3", - "Content-Type": "application/json", - }, - referrer: exports.site, - body: JSON.stringify({ - operationName: "Projects", - query: "query Projects($hostname:String! $filter:SearchFilter $page:Int $limit:Int){projects(section:{fullUrl:$hostname}filter:$filter page:{pageSize:$limit,pageNumber:$page}){content{title fullUrl covers{url}}}}", - variables: { - filter: { - query: searchTerm, - }, - hostname: "novel.tl", - limit: 40, - page: 1, - }, - }), - }); - const json = (yield result.json()); - let novels = []; - (_x = (_w = (_v = json === null || json === void 0 ? void 0 : json.data) === null || _v === void 0 ? void 0 : _v.projects) === null || _w === void 0 ? void 0 : _w.content) === null || _x === void 0 ? void 0 : _x.forEach((novel) => { - var _a, _b; - return novels.push({ - name: novel.title, - url: "https://" + novel.fullUrl, - cover: ((_b = (_a = novel === null || novel === void 0 ? void 0 : novel.covers) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.url) - ? exports.site + novel.covers[0].url - : defaultCover_1.defaultCover, - }); - }); - return novels; -}); -exports.searchNovels = searchNovels; -exports.fetchImage = fetch_1.fetchFile; -exports.filters = [ - { - key: "tags", - label: "Тэги", - values: [ - { label: "Автоматы", value: 64 }, - { label: "Агрессивные персонажи", value: 26 }, - { label: "Ад", value: 338 }, - { label: "Адаптация манги", value: 8 }, - { label: "Академия", value: 5 }, - { label: "Актёрское искусство", value: 7 }, - { label: "Актеры озвучки", value: 746 }, - { label: "Алхимия", value: 27 }, - { label: "Альтернативная реальность", value: 30 }, - { label: "Амнезия", value: 31 }, - { label: "Анабиоз", value: 170 }, - { label: "Анал", value: 33 }, - { label: "Ангелы", value: 38 }, - { label: "Андроиды", value: 37 }, - { label: "Анти-рост персонажа", value: 25 }, - { label: "Антигерой", value: 43 }, - { label: "Антикварный магазин", value: 44 }, - { label: "Антимагия", value: 41 }, - { label: "Антиутопия", value: 225 }, - { label: "Апатичный главный герой", value: 46 }, - { label: "Апокалипсис", value: 47 }, - { label: "Аристократия", value: 51 }, - { label: "Армия", value: 53 }, - { label: "Артефакты", value: 58 }, - { label: "Асоциальный главный герой", value: 42 }, - { label: "Ассасины", value: 61 }, - { label: "Атмосфера Европы", value: 245 }, - { label: "Банды", value: 302 }, - { label: "БДСМ", value: 77 }, - { label: "Бедный главный герой", value: 541 }, - { label: "Бездушный главный герой", value: 143 }, - { label: "Беззаботный герой", value: 115 }, - { label: "Безответная любовь", value: 213 }, - { label: "Безответная любовь", value: 740 }, - { label: "Безработные", value: 377 }, - { label: "Беременность", value: 551 }, - { label: "Бескорыстная любовь", value: 733 }, - { label: "Бессмертные", value: 359 }, - { label: "Бесстрашный главный герой", value: 274 }, - { label: "Библиотека", value: 393 }, - { label: "Биография", value: 86 }, - { label: "Близнецы", value: 729 }, - { label: "Богачи", value: 753 }, - { label: "Боги", value: 318 }, - { label: "Богини", value: 316 }, - { label: "Богоподобный протагонист", value: 314 }, - { label: "Боевая академия", value: 75 }, - { label: "Боевая парочка", value: 547 }, - { label: "Божественная защита", value: 208 }, - { label: "Божественная сила", value: 317 }, - { label: "Болеющие персонажи", value: 648 }, - { label: "Борьба за власть", value: 548 }, - { label: "Брак по расчету", value: 55 }, - { label: "Братство", value: 106 }, - { label: "Братья или сёстры", value: 646 }, - { label: "Брошенные дети", value: 1 }, - { label: "Бывший герой", value: 290 }, - { label: "Вампиры", value: 742 }, - { label: "Ваншот", value: 496 }, - { label: "Вдали от родителей", value: 3 }, - { label: "Ведьмы", value: 756 }, - { label: "Везучий главный герой", value: 411 }, - { label: "Верные подданные", value: 410 }, - { label: "Вероломные герои/плетение интриг", value: 424 }, - { label: "Взросление персонажа", value: 24 }, - { label: "Видит то, чего остальной люд не в силах", value: 617 }, - { label: "Виртуальная реальность", value: 744 }, - { label: "Владелец магазина", value: 677 }, - { label: "Владелец уникального оружия", value: 736 }, - { label: "Властные персонажи", value: 545 }, - { label: "Влияние прошлого", value: 517 }, - { label: "Внезапное обогащение", value: 691 }, - { label: "Внезапное обретение силы", value: 690 }, - { label: "Военные хроники", value: 749 }, - { label: "Возвращение в родной мир", value: 587 }, - { label: "Война", value: 750 }, - { label: "Вокалоид", value: 745 }, - { label: "Волшебные твари", value: 413 }, - { label: "Воскрешение", value: 586 }, - { label: "Воспитанный главный герой", value: 537 }, - { label: "Воспоминания прошлого", value: 283 }, - { label: "Враги становятся союзниками", value: 238 }, - { label: "Врата в иной мир", value: 303 }, - { label: "Временной парадокс", value: 711 }, - { label: "Вторжение на Землю", value: 228 }, - { label: "Второй шанс", value: 608 }, - { label: "Выживание", value: 695 }, - { label: "Вынужденные условия проживания", value: 287 }, - { label: "Высокомерный герой", value: 56 }, - { label: "Гадание", value: 207 }, - { label: "Галлюцинации", value: 189 }, - { label: "Гарем рабов", value: 656 }, - { label: "Геймеры", value: 301 }, - { label: "Генетические модификации", value: 306 }, - { label: "Герои", value: 341 }, - { label: "Герои непонятного пола", value: 36 }, - { label: "Героиня девушка-сорванец", value: 715 }, - { label: "Героиня красавица", value: 81 }, - { label: "Герой влюбляется первым", value: 561 }, - { label: "Герой использует щит", value: 636 }, - { label: "Герой красавец", value: 329 }, - { label: "Герой со множеством тел", value: 564 }, - { label: "Герой-бесстыдник", value: 632 }, - { label: "Герой-извращенец", value: 521 }, - { label: "Герой-трудяга", value: 330 }, - { label: "Герой-яндере", value: 421 }, - { label: "Гетерохромия", value: 342 }, - { label: "Гильдии", value: 324 }, - { label: "Гиперопека", value: 509 }, - { label: "Главная героиня — женщина", value: 277 }, - { label: "Главный герой - гений", value: 308 }, - { label: "Главный герой - Моб", value: 446 }, - { label: "Главный герой — знаменитость", value: 263 }, - { label: "Главный герой — мужчина", value: 419 }, - { label: "Главный герой в поисках гарема", value: 331 }, - { label: "Главный герой заранее готовится", value: 557 }, - { label: "Главный герой не человек", value: 488 }, - { label: "Главный герой приёмный", value: 20 }, - { label: "Главный герой сразу силён", value: 563 }, - { label: "Гладиаторы", value: 310 }, - { label: "Глухой к любви герой", value: 194 }, - { label: "Гоблины", value: 313 }, - { label: "Големы", value: 319 }, - { label: "Гомункул", value: 347 }, - { label: "Горничные", value: 418 }, - { label: "Государственные интриги", value: 212 }, - { label: "Гринд", value: 322 }, - { label: "Давняя травма", value: 518 }, - { label: "Двойник", value: 97 }, - { label: "Дворецкие", value: 111 }, - { label: "Дворфы", value: 224 }, - { label: "Дворяне", value: 487 }, - { label: "Двоюродные братья или сёстры", value: 162 }, - { label: "Девочки-волшебницы", value: 415 }, - { label: "Демоны", value: 193 }, - { label: "Депрессия", value: 196 }, - { label: "Детектив", value: 198 }, - { label: "Детективное расследование", value: 473 }, - { label: "Детское насилие", value: 125 }, - { label: "Детское обещание", value: 130 }, - { label: "Дискриминация", value: 203 }, - { label: "Длительный разрыв отношений", value: 400 }, - { label: "Домашняя жизнь", value: 45 }, - { label: "Драконы", value: 218 }, - { label: "Древний Китай", value: 34 }, - { label: "Дружба", value: 293 }, - { label: "Друзья детства", value: 128 }, - { label: "Друзья становятся врагами", value: 292 }, - { label: "Духи", value: 673 }, - { label: "Духовная сила", value: 665 }, - { label: "Духовный наставник", value: 671 }, - { label: "Душещипательная история", value: 335 }, - { label: "Души", value: 666 }, - { label: "Дьявольский путь культивации", value: 192 }, - { label: "Ёкай", value: 763 }, - { label: "Есть аниме-адаптация", value: 10 }, - { label: "Есть видеоигра", value: 13 }, - { label: "Есть дорама-адаптация", value: 11 }, - { label: "Есть манга-адаптация", value: 14 }, - { label: "Есть манхва-адаптация", value: 16 }, - { label: "Есть маньхуа-адаптация", value: 15 }, - { label: "Есть фильм", value: 17 }, - { label: "Есть CD дорама-адаптация", value: 12 }, - { label: "Жёсткий главный герой", value: 597 }, - { label: "Жестокие персонажи", value: 4 }, - { label: "Жёстокие персонажи", value: 169 }, - { label: "Животное-спутник", value: 78 }, - { label: "Жизнь в одиночку", value: 396 }, - { label: "Жрецы", value: 555 }, - { label: "Жрицы", value: 554 }, - { label: "Забота о детях", value: 127 }, - { label: "Заботливый главный герой", value: 116 }, - { label: "Загадочное заболевание", value: 471 }, - { label: "Загадочное прошлое родителей", value: 470 }, - { label: "Заговоры", value: 154 }, - { label: "Закалка тела", value: 96 }, - { label: "Закон джунглей", value: 682 }, - { label: "Закулисная борба", value: 603 }, - { label: "Замкнутый главный герой", value: 371 }, - { label: "Запечатанная сила", value: 607 }, - { label: "Затворник", value: 346 }, - { label: "Звери", value: 80 }, - { label: "Зверолюди", value: 39 }, - { label: "Звероподобные", value: 79 }, - { label: "Земледелие", value: 268 }, - { label: "Злобные благородные девы", value: 743 }, - { label: "Зловещие организации", value: 247 }, - { label: "Злой главный герой", value: 248 }, - { label: "Злые боги", value: 246 }, - { label: "Злые религии", value: 249 }, - { label: "Знаменитости", value: 118 }, - { label: "Знания из прошлой жизни", value: 553 }, - { label: "Зомби", value: 767 }, - { label: "Игра на выживание", value: 696 }, - { label: "Игровая рейтинговая система", value: 300 }, - { label: "Из грязи в князи", value: 542 }, - { label: "Известные родители", value: 262 }, - { label: "Изменение внешнего вида", value: 48 }, - { label: "Изнасилование", value: 574 }, - { label: "Инвалидность", value: 202 }, - { label: "Индустриализация", value: 364 }, - { label: "Инженер", value: 241 }, - { label: "Инцест", value: 361 }, - { label: "Искажённая личность", value: 730 }, - { label: "Искусственный интеллект", value: 59 }, - { label: "Исполнение желаний", value: 755 }, - { label: "Каннибализм", value: 113 }, - { label: "Карточные игры", value: 114 }, - { label: "Кладбищенский смотритель", value: 321 }, - { label: "Классика", value: 134 }, - { label: "Книги", value: 99 }, - { label: "Книги навыков", value: 654 }, - { label: "Книжный червь", value: 100 }, - { label: "Коллеги", value: 140 }, - { label: "Колледж/Университет", value: 145 }, - { label: "Командная работа", value: 701 }, - { label: "Комедийный подтекст", value: 147 }, - { label: "Комплекс брата", value: 105 }, - { label: "Комплекс неполноценности", value: 365 }, - { label: "Контракты", value: 155 }, - { label: "Контроль разума", value: 441 }, - { label: "Конфликт в семье", value: 261 }, - { label: "Конфликт верности", value: 153 }, - { label: "Копейщик", value: 668 }, - { label: "Королевская особа", value: 596 }, - { label: "Королевства", value: 382 }, - { label: "Короткий рассказ", value: 638 }, - { label: "Коррупция", value: 157 }, - { label: "Космические Войны", value: 158 }, - { label: "Космос", value: 507 }, - { label: "Косплей", value: 159 }, - { label: "Кража способностей", value: 2 }, - { label: "Крафтинг", value: 164 }, - { label: "Кризис личности", value: 357 }, - { label: "Кровь", value: 320 }, - { label: "Кружки, клубы", value: 138 }, - { label: "Кудэрэ", value: 384 }, - { label: "Кузнец", value: 90 }, - { label: "Кукловоды", value: 567 }, - { label: "Куклы/Марионетки", value: 211 }, - { label: "Кулинария", value: 156 }, - { label: "Культивация", value: 171 }, - { label: "Куннилингус", value: 172 }, - { label: "Легенды", value: 391 }, - { label: "Легкая жизнь", value: 229 }, - { label: "Лекари", value: 334 }, - { label: "Ленивый главный герой", value: 389 }, - { label: "Лидерство", value: 390 }, - { label: "Любит персонажа младше себя", value: 765 }, - { label: "Любит персонажа старше себя", value: 494 }, - { label: "Любовное соперничество", value: 406 }, - { label: "Любовные треугольники", value: 407 }, - { label: "Любовь детства", value: 129 }, - { label: "Любовь с первого взгляда", value: 404 }, - { label: "Любящие родители", value: 215 }, - { label: "Маги", value: 757 }, - { label: "Магические технологии", value: 417 }, - { label: "Магия", value: 412 }, - { label: "Магия призыва", value: 694 }, - { label: "Маленькие девочки", value: 397 }, - { label: "Мангака", value: 423 }, - { label: "Маниакальная любовь", value: 492 }, - { label: "Марти Сью", value: 508 }, - { label: "Мастер подземелий", value: 222 }, - { label: "Мастурбация", value: 432 }, - { label: "Матриархат", value: 433 }, - { label: "Межпространственные путешествия", value: 370 }, - { label: "Менеджмент", value: 422 }, - { label: "Месть", value: 588 }, - { label: "Мечи и магия", value: 697 }, - { label: "Мечники", value: 698 }, - { label: "Миленькие дети", value: 176 }, - { label: "Милитаризм", value: 439 }, - { label: "Миловидная история", value: 178 }, - { label: "Милый главный герой", value: 177 }, - { label: "Минет", value: 275 }, - { label: "Мировое древо", value: 760 }, - { label: "Миролюбивый главный герой", value: 510 }, - { label: "Мифология", value: 475 }, - { label: "Младшие сёстры", value: 766 }, - { label: "ММОРПГ", value: 445 }, - { label: "Множество временных линий", value: 463 }, - { label: "Модели", value: 447 }, - { label: "Молод не по годам", value: 49 }, - { label: "Монстры", value: 454 }, - { label: "Мрачность", value: 183 }, - { label: "Музыка", value: 466 }, - { label: "Музыкальные группы", value: 68 }, - { label: "Мутации", value: 468 }, - { label: "На волосок от смерти", value: 479 }, - { label: "На все руки мастер", value: 374 }, - { label: "Навыки имеют стоимость", value: 150 }, - { label: "Нагота", value: 490 }, - { label: "Наездники на драконах", value: 216 }, - { label: "Наёмники", value: 437 }, - { label: "Наивный главный герой", value: 476 }, - { label: "Наследие", value: 366 }, - { label: "Настоящая любовь", value: 200 }, - { label: "Настоящий гарем", value: 540 }, - { label: "Небесное испытание", value: 337 }, - { label: "Невезучий главный герой", value: 738 }, - { label: "Недоверчивый протагонист", value: 206 }, - { label: "Недооцененный главный герой", value: 734 }, - { label: "Недопонимание", value: 444 }, - { label: "Некромант", value: 480 }, - { label: "Нелинейное повествование", value: 489 }, - { label: "Неловкий главный герой", value: 67 }, - { label: "Нелюбимый протагонист", value: 333 }, - { label: "Немой персонаж", value: 469 }, - { label: "Ненадежный рассказчик", value: 739 }, - { label: "Непримечательный герой", value: 65 }, - { label: "Нерешительный протагонист", value: 363 }, - { label: "Несгибаемый главный герой", value: 676 }, - { label: "Несколько главных героев", value: 460 }, - { label: "Несколько миров", value: 461 }, - { label: "Несколько перерожденцев", value: 462 }, - { label: "Несколько попаданцев", value: 464 }, - { label: "Несравненная скорость культивации", value: 269 }, - { label: "Нехватка/отсутствие здравого смысла", value: 385 }, - { label: "Нечестный протагонист", value: 205 }, - { label: "НИИТ", value: 481 }, - { label: "Ниндзя", value: 486 }, - { label: "Обмен телами", value: 95 }, - { label: "Оборотни", value: 754 }, - { label: "Объект любви влюбился первым", value: 405 }, - { label: "Объект любви популярен", value: 543 }, - { label: "Огнестрельное оружие", value: 280 }, - { label: "Ограничение на время жизни", value: 394 }, - { label: "Одержимость", value: 544 }, - { label: "Один родитель", value: 651 }, - { label: "Одинокий главный герой", value: 399 }, - { label: "Одиночество", value: 398 }, - { label: "Одно тело на двоих", value: 634 }, - { label: "Око силы", value: 253 }, - { label: "Оммёдзи", value: 498 }, - { label: "Организованная преступность", value: 500 }, - { label: "Оргия", value: 501 }, - { label: "Орки", value: 499 }, - { label: "Основано на аниме", value: 74 }, - { label: "Основано на видеоигре", value: 72 }, - { label: "Основано на визуальной новелле", value: 73 }, - { label: "Основано на песне", value: 70 }, - { label: "Основано на фильме", value: 69 }, - { label: "Осторожный главный герой", value: 117 }, - { label: "От ненависти до любви один шаг", value: 239 }, - { label: "От сильного с сильнейшему", value: 684 }, - { label: "От слабого к сильному", value: 752 }, - { label: "Отаку", value: 503 }, - { label: "Отзывчивая любовь", value: 380 }, - { label: "Отзывчивый главный герой", value: 339 }, - { label: "Отношение учитель-ученик", value: 430 }, - { label: "Отношения бог-человек", value: 315 }, - { label: "Отношения между учителем и учеником", value: 687 }, - { label: "Отношения начальник-подчинённый", value: 101 }, - { label: "Отношения против воли", value: 286 }, - { label: "Отношения с нечеловеком", value: 353 }, - { label: "Отношения сэмпай-кохай", value: 621 }, - { label: "Отношения хозяин-слуга", value: 431 }, - { label: "Отомэ-игры", value: 504 }, - { label: "ОТП", value: 562 }, - { label: "Отшельники", value: 505 }, - { label: "Офисный работник", value: 600 }, - { label: "Официанты", value: 748 }, - { label: "Охотники", value: 355 }, - { label: "Падшие ангелы", value: 255 }, - { label: "Падшие дворяне", value: 256 }, - { label: "Пайзури", value: 511 }, - { label: "Паразиты", value: 513 }, - { label: "Параллельные миры", value: 512 }, - { label: "Парк развлечений", value: 32 }, - { label: "Пародия", value: 515 }, - { label: "Перемещение между мирами", value: 758 }, - { label: "Переодевание", value: 167 }, - { label: "Переплавка пилюль", value: 529 }, - { label: "Перерождение в девушку", value: 420 }, - { label: "Перерождение в другом мире", value: 580 }, - { label: "Перерождение в другом мире", value: 720 }, - { label: "Перерождение в игровом мире", value: 579 }, - { label: "Перерождение в монстра", value: 577 }, - { label: "Персонажи с мазохистскими наклонностями", value: 429 }, - { label: "Персонажи с садистскими наклонностями", value: 598 }, - { label: "Петля времени", value: 709 }, - { label: "Петтинг", value: 328 }, - { label: "Писатели", value: 761 }, - { label: "Питомцы", value: 522 }, - { label: "Племенное общество", value: 726 }, - { label: "Повелитель демонов", value: 191 }, - { label: "Повествование от нескольких лиц", value: 459 }, - { label: "Поглощение навыков", value: 653 }, - { label: "Подземелья", value: 223 }, - { label: "Поздно начинающаяся романтическая линия", value: 387 }, - { label: "Политика", value: 538 }, - { label: "Полулюди", value: 190 }, - { label: "Помолвка", value: 240 }, - { label: "Попаданец в другой мир", value: 723 }, - { label: "Попаданец в игровой мир", value: 722 }, - { label: "Постапокалипсис", value: 546 }, - { label: "Постижение Дао", value: 181 }, - { label: "Потеря девственности", value: 282 }, - { label: "Потустороннее пространство", value: 416 }, - { label: "Похищения", value: 379 }, - { label: "Прагматичный главный герой", value: 549 }, - { label: "Предательство", value: 83 }, - { label: "Предвидение", value: 550 }, - { label: "Преследователи", value: 674 }, - { label: "Преступление", value: 165 }, - { label: "Преступность", value: 166 }, - { label: "Приёмные дети", value: 19 }, - { label: "Призванный герой", value: 693 }, - { label: "Призраки", value: 309 }, - { label: "Приключения", value: 22 }, - { label: "Принуждение", value: 108 }, - { label: "Приручатель", value: 453 }, - { label: "Прислуга", value: 625 }, - { label: "Приставучий любовник", value: 136 }, - { label: "Притворная любовь", value: 552 }, - { label: "Пришельцы", value: 28 }, - { label: "Программист", value: 558 }, - { label: "Произведение - обладатель наград", value: 66 }, - { label: "Проклятия", value: 175 }, - { label: "Промывка мозгов", value: 102 }, - { label: "Пропуск времени", value: 712 }, - { label: "Пророчества", value: 559 }, - { label: "Протагонист в очках", value: 312 }, - { label: "Протагонист раб", value: 657 }, - { label: "Психокинез", value: 565 }, - { label: "Психопаты", value: 566 }, - { label: "Путешествия", value: 759 }, - { label: "Путешествия во времени", value: 713 }, - { label: "Пытки", value: 716 }, - { label: "Рабы", value: 658 }, - { label: "Развитие отношений", value: 160 }, - { label: "Развитие персонажа", value: 119 }, - { label: "Раздвоение личности", value: 458 }, - { label: "Размеренная романтика", value: 661 }, - { label: "Разница в статусе", value: 201 }, - { label: "Разорванная помолвка", value: 104 }, - { label: "Разумные предметы", value: 622 }, - { label: "Рай", value: 336 }, - { label: "Раняя романтика", value: 227 }, - { label: "Расизм", value: 573 }, - { label: "Расследования", value: 372 }, - { label: "Ребенок — главный герой", value: 126 }, - { label: "Реверс-гарем", value: 589 }, - { label: "Реверс-изнасилование", value: 590 }, - { label: "Резкая смена характера", value: 520 }, - { label: "Реинкарнация", value: 581 }, - { label: "Религии", value: 582 }, - { label: "Ресторан", value: 585 }, - { label: "Решительный главный герой", value: 199 }, - { label: "Робкий протагонист", value: 714 }, - { label: "Родительсткий комплекс", value: 514 }, - { label: "Родные не связанные кровью", value: 647 }, - { label: "Родословные", value: 94 }, - { label: "РПГ-система", value: 392 }, - { label: "Рыцари", value: 383 }, - { label: "Самовлюбленный главный герой", value: 477 }, - { label: "Самоубийства", value: 692 }, - { label: "Самураи", value: 601 }, - { label: "Сборник коротких историй", value: 144 }, - { label: "Свадьба", value: 426 }, - { label: "Связанные сюжетные линии", value: 369 }, - { label: "Святые", value: 599 }, - { label: "Секреты", value: 614 }, - { label: "Секс втроём", value: 707 }, - { label: "Секс-рабыня", value: 629 }, - { label: "Семейная любовь", value: 257 }, - { label: "Семь добродетелей", value: 627 }, - { label: "Семь смертных грехов", value: 626 }, - { label: "Серийные убийцы", value: 624 }, - { label: "Сикигами", value: 637 }, - { label: "Сильная любовь от старших", value: 214 }, - { label: "Синдром восьмиклассника", value: 132 }, - { label: "Синдром сестры", value: 652 }, - { label: "Сироты", value: 502 }, - { label: "Системный администратор", value: 699 }, - { label: "Скромный главный герой", value: 409 }, - { label: "Скрытые романтические отношения", value: 23 }, - { label: "Скрытые способности", value: 343 }, - { label: "Скряга", value: 450 }, - { label: "Скульпторы", value: 606 }, - { label: "Слабая романтика", value: 688 }, - { label: "Слабый главный герой", value: 751 }, - { label: "Сложные семейные отношения", value: 149 }, - { label: "Смена расы", value: 572 }, - { label: "Смертельное заболевание", value: 704 }, - { label: "Смерть", value: 185 }, - { label: "Смерть любимых", value: 186 }, - { label: "Современность", value: 448 }, - { label: "Современные знания в слаборазвитых мирах", value: 449 }, - { label: "Сожительство", value: 141 }, - { label: "Создание артефактов", value: 57 }, - { label: "Создание клана", value: 133 }, - { label: "Создание королевства", value: 381 }, - { label: "Создание навыков", value: 655 }, - { label: "Сокрытие истинных способностей", value: 344 }, - { label: "Сокрытие личности", value: 345 }, - { label: "Солдаты", value: 664 }, - { label: "Сон", value: 659 }, - { label: "Соседи по комнате", value: 595 }, - { label: "Социальные изгои", value: 663 }, - { label: "Спасение мира", value: 602 }, - { label: "Спорящая пара", value: 84 }, - { label: "Способность перевоплощения", value: 719 }, - { label: "Средневековье", value: 436 }, - { label: "Стеснительные персонажи", value: 643 }, - { label: "Стокгольмский синдром", value: 575 }, - { label: "Стокгольмский синдром", value: 675 }, - { label: "Стратег", value: 681 }, - { label: "Стратегические битвы", value: 680 }, - { label: "Стрелки", value: 325 }, - { label: "Стрельба из лука", value: 50 }, - { label: "Студенческий совет", value: 686 }, - { label: "Судьба", value: 197 }, - { label: "Суккубы", value: 689 }, - { label: "Суперспособности", value: 669 }, - { label: "Суровая тренировка", value: 332 }, - { label: "Сцены насилия", value: 195 }, - { label: "Таинственное прошлое", value: 472 }, - { label: "Тайная личность", value: 610 }, - { label: "Тайные организации", value: 611 }, - { label: "Телохранители", value: 98 }, - { label: "Тентакли", value: 703 }, - { label: "Террористы", value: 705 }, - { label: "Технологический разрыв", value: 702 }, - { label: "Тихие герои", value: 568 }, - { label: "Толстый протагонист", value: 271 }, - { label: "Торговцы", value: 438 }, - { label: "Травник", value: 340 }, - { label: "Трагичное прошлое", value: 718 }, - { label: "Трап", value: 725 }, - { label: "Триллер", value: 708 }, - { label: "Турнир", value: 76 }, - { label: "Тюрьма", value: 556 }, - { label: "Убийства", value: 465 }, - { label: "Уверенный в себе главный герой", value: 151 }, - { label: "Умная пара", value: 662 }, - { label: "Умный главный герой", value: 135 }, - { label: "Уникальная техника культивации", value: 735 }, - { label: "Уникальные оружия", value: 737 }, - { label: "Управление бизнесом", value: 109 }, - { label: "Управление временем", value: 710 }, - { label: "Управление пространством", value: 667 }, - { label: "Ускоренный рост", value: 6 }, - { label: "Учёные", value: 605 }, - { label: "Учителя", value: 700 }, - { label: "Фамильяры", value: 258 }, - { label: "Фанатизм", value: 264 }, - { label: "Фармацевт", value: 523 }, - { label: "Феи", value: 254 }, - { label: "Фениксы", value: 526 }, - { label: "Фетиш на грудь", value: 103 }, - { label: "Фетиш на очки", value: 311 }, - { label: "Философия", value: 524 }, - { label: "Фобии/Страхи", value: 525 }, - { label: "Фольклор", value: 285 }, - { label: "Формирование армии", value: 54 }, - { label: "Футанари", value: 295 }, - { label: "Футуристический мир", value: 296 }, - { label: "Фэнтези", value: 267 }, - { label: "Фэнтезийные существа", value: 266 }, - { label: "Хакеры", value: 326 }, - { label: "Харизматичный протагонист", value: 120 }, - { label: "Хитрый главный герой", value: 173 }, - { label: "Хладнокровный главный герой", value: 112 }, - { label: "Художники", value: 60 }, - { label: "Хулиганы", value: 188 }, - { label: "Цундере", value: 728 }, - { label: "Чат", value: 122 }, - { label: "Человек-оружие", value: 352 }, - { label: "Человекоподобный главный герой", value: 354 }, - { label: "Честный главный герой", value: 348 }, - { label: "Четкие любовные убеждения", value: 683 }, - { label: "Читы", value: 123 }, - { label: "Чудаковатые герои", value: 569 }, - { label: "Чужие воспоминания", value: 721 }, - { label: "Шантаж", value: 89 }, - { label: "Шеф-повар", value: 124 }, - { label: "Школа для девочек", value: 29 }, - { label: "Шоу-бизнес", value: 642 }, - { label: "Шпионы", value: 670 }, - { label: "Эволюция", value: 250 }, - { label: "Эгоистичный главный герой", value: 618 }, - { label: "Экзорцизм", value: 252 }, - { label: "Экономика", value: 230 }, - { label: "Эксгибиционизм", value: 251 }, - { label: "Эксперименты на людях", value: 351 }, - { label: "Элементальная магия", value: 234 }, - { label: "Элементы игрового мира", value: 299 }, - { label: "Элементы романтики", value: 594 }, - { label: "Элементы юри", value: 640 }, - { label: "Элементы яоя", value: 641 }, - { label: "Эльфы", value: 235 }, - { label: "Эпизодичность", value: 243 }, - { label: "Язвительные персонажи", value: 635 }, - { label: "Языковой барьер", value: 386 }, - { label: "Яндере", value: 762 }, - { label: "Яойщица", value: 294 }, - { label: "Японские силы самообороны", value: 378 }, - { label: "R-15", value: 570 }, - { label: "R-18", value: 571 }, - ], - inputType: filterInputs_1.FilterInputs.Checkbox, - }, - { - key: "genres", - label: "Жанры", - values: [ - { label: "16+", value: 1 }, - { label: "18+", value: 2 }, - { label: "Боевик", value: 3 }, - { label: "Боевые искусства", value: 4 }, - { label: "Вампиры", value: 47 }, - { label: "Военное", value: 44 }, - { label: "Гарем", value: 5 }, - { label: "Демоны", value: 48 }, - { label: "Детектив", value: 6 }, - { label: "Дзёсей", value: 50 }, - { label: "Драма", value: 7 }, - { label: "Игры", value: 45 }, - { label: "Историческое", value: 8 }, - { label: "Киберпанк", value: 9 }, - { label: "Комедия", value: 10 }, - { label: "Космос", value: 46 }, - { label: "Магия", value: 42 }, - { label: "Махо-сёдзё", value: 12 }, - { label: "Меха", value: 13 }, - { label: "Мистика", value: 14 }, - { label: "Музыка", value: 49 }, - { label: "Научная фантастика", value: 15 }, - { label: "Пародия", value: 16 }, - { label: "Повседневность", value: 17 }, - { label: "Приключения", value: 18 }, - { label: "Психологическое", value: 19 }, - { label: "Романтика", value: 20 }, - { label: "Сверхъестественное", value: 21 }, - { label: "Сёдзё", value: 22 }, - { label: "Сёдзё-ай", value: 23 }, - { label: "Сёнэн", value: 24 }, - { label: "Сёнэн-ай", value: 25 }, - { label: "Смена пола", value: 26 }, - { label: "Современность", value: 27 }, - { label: "Спорт", value: 28 }, - { label: "Супер сила", value: 43 }, - { label: "Сэйнэн", value: 29 }, - { label: "Трагедия", value: 32 }, - { label: "Триллер", value: 33 }, - { label: "Ужасы", value: 34 }, - { label: "Уся", value: 35 }, - { label: "Фэнтези", value: 36 }, - { label: "Школьная жизнь", value: 37 }, - { label: "Этти", value: 38 }, - { label: "Юри", value: 39 }, - { label: "Яой", value: 40 }, - { label: "LitRPG", value: 41 }, - ], - inputType: filterInputs_1.FilterInputs.Checkbox, - }, -]; diff --git a/js/plugins/russian/ranobehub.js b/js/plugins/russian/ranobehub.js deleted file mode 100644 index 1443676..0000000 --- a/js/plugins/russian/ranobehub.js +++ /dev/null @@ -1,1126 +0,0 @@ -"use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.filters = exports.fetchImage = exports.searchNovels = exports.parseChapter = exports.parseNovelAndChapters = exports.popularNovels = exports.icon = exports.site = exports.version = exports.name = exports.id = void 0; -const filterInputs_1 = require("@libs/filterInputs"); -const fetch_1 = require("@libs/fetch"); -const novelStatus_1 = require("@libs/novelStatus"); -const cheerio_1 = require("cheerio"); -const dayjs_1 = __importDefault(require("dayjs")); -exports.id = "RNBH.org"; -exports.name = "RanobeHub"; -exports.version = "1.0.0"; -exports.site = "https://ranobehub.org/"; -exports.icon = "src/ru/ranobehub/icon.png"; -const popularNovels = function (page, { showLatestNovels, filters }) { - return __awaiter(this, void 0, void 0, function* () { - let url = exports.site + `api/search?page=${page}&sort=`; - url += showLatestNovels - ? "last_chapter_at" - : (filters === null || filters === void 0 ? void 0 : filters.sort) || "computed_rating"; - url += "&status=" + ((filters === null || filters === void 0 ? void 0 : filters.status) ? filters === null || filters === void 0 ? void 0 : filters.status : "0"); - if (filters) { - if (Array.isArray(filters.country) && filters.country.length) { - url += "&country=" + filters.country.join(","); - } - let tags = [filters === null || filters === void 0 ? void 0 : filters.tags, filters === null || filters === void 0 ? void 0 : filters.events].flat().filter((t) => t); - if (tags.length) { - url += "&tags:positive=" + tags.join(","); - } - } - url += "&take=40"; - const result = yield (0, fetch_1.fetchApi)(url); - const body = (yield result.json()); - let novels = []; - body.resource.forEach((novel) => { - var _a; - return novels.push({ - name: ((_a = novel.names) === null || _a === void 0 ? void 0 : _a.rus) || novel.names.eng, - cover: novel.poster.medium, - url: novel.url, - }); - }); - return novels; - }); -}; -exports.popularNovels = popularNovels; -const parseNovelAndChapters = function (novelUrl) { - var _a, _b, _c, _d; - return __awaiter(this, void 0, void 0, function* () { - const novelId = novelUrl - .substring("https://ranobehub.org/ranobe/".length) - .split("-")[0]; - const result = yield (0, fetch_1.fetchApi)(`${exports.site}api/ranobe/${novelId}`); - const json = (yield result.json()); - let novel = { - url: json.data.url, - name: ((_a = json.data.names) === null || _a === void 0 ? void 0 : _a.rus) || json.data.names.eng, - cover: json.data.posters.medium, - summary: json.data.description, - author: ((_d = (_c = (_b = json.data) === null || _b === void 0 ? void 0 : _b.authors) === null || _c === void 0 ? void 0 : _c[0]) === null || _d === void 0 ? void 0 : _d.name_eng) || "", - status: json.data.status.title.includes("процессе") - ? novelStatus_1.NovelStatus.Ongoing - : novelStatus_1.NovelStatus.Completed, - }; - let tags = [json.data.tags.events, json.data.tags.genres] - .flat() - .map((tags) => { var _a, _b; return ((_a = tags === null || tags === void 0 ? void 0 : tags.names) === null || _a === void 0 ? void 0 : _a.rus) || ((_b = tags === null || tags === void 0 ? void 0 : tags.names) === null || _b === void 0 ? void 0 : _b.eng) || (tags === null || tags === void 0 ? void 0 : tags.title); }) - .filter((tags) => tags); - if (tags.length > 0) { - novel.genres = tags.join(", "); - } - let novelChapters = []; - const fetchChaptersUrl = `${exports.site}api/ranobe/${novelId}/contents`; - const chaptersRaw = yield (0, fetch_1.fetchApi)(fetchChaptersUrl); - const chaptersJSON = (yield chaptersRaw.json()); - chaptersJSON.volumes.forEach((volume) => { - var _a; - return (_a = volume.chapters) === null || _a === void 0 ? void 0 : _a.forEach((chapter) => novelChapters.push({ - name: chapter.name, - url: chapter.url, - releaseTime: (0, dayjs_1.default)(parseInt(chapter.changed_at, 10) * 1000).format("LLL"), - })); - }); - novel.chapters = novelChapters; - return novel; - }); -}; -exports.parseNovelAndChapters = parseNovelAndChapters; -const parseChapter = function (chapterUrl) { - return __awaiter(this, void 0, void 0, function* () { - const result = yield (0, fetch_1.fetchApi)(chapterUrl); - const body = yield result.text(); - let loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio(".chapter-hoticons").remove(); - loadedCheerio("div.text:nth-child(1) img").each(function () { - var _a; - if (!((_a = loadedCheerio(this).attr("src")) === null || _a === void 0 ? void 0 : _a.startsWith("http"))) { - const dataMediaId = loadedCheerio(this).attr("data-media-id"); - loadedCheerio(this).attr("src", exports.site + "api/media/" + dataMediaId); - } - }); - let chapterText = loadedCheerio("div.text:nth-child(1)").html() || ""; - // Remove script tags - chapterText = chapterText === null || chapterText === void 0 ? void 0 : chapterText.replace(/<\s*script[^>]*>[\s\S]*?<\/script>/gim, ""); - return chapterText; - }); -}; -exports.parseChapter = parseChapter; -const searchNovels = function (searchTerm) { - var _a, _b; - return __awaiter(this, void 0, void 0, function* () { - const url = `${exports.site}api/fulltext/global?query=${searchTerm}&take=10`; - const result = yield (0, fetch_1.fetchApi)(url); - const data = (yield result.json()); - let novels = []; - (_b = (_a = data === null || data === void 0 ? void 0 : data.find((item) => { var _a; return ((_a = item === null || item === void 0 ? void 0 : item.meta) === null || _a === void 0 ? void 0 : _a.key) === "ranobe"; })) === null || _a === void 0 ? void 0 : _a.data) === null || _b === void 0 ? void 0 : _b.forEach((novel) => { - var _a, _b, _c, _d, _e; - return novels.push({ - name: ((_a = novel === null || novel === void 0 ? void 0 : novel.names) === null || _a === void 0 ? void 0 : _a.rus) || ((_b = novel === null || novel === void 0 ? void 0 : novel.names) === null || _b === void 0 ? void 0 : _b.eng) || (novel === null || novel === void 0 ? void 0 : novel.name) || "", - url: "https://ranobehub.org/ranobe/" + - ((_d = (_c = novel === null || novel === void 0 ? void 0 : novel.url) === null || _c === void 0 ? void 0 : _c.match(/https:\/\/ranobehub\.org\/ranobe\/(.*?)\?utm_source=search_name&utm_medium=search&utm_campaign=search_using/)) === null || _d === void 0 ? void 0 : _d[1]), - cover: (_e = novel === null || novel === void 0 ? void 0 : novel.image) === null || _e === void 0 ? void 0 : _e.replace("/small", "/medium"), - }); - }); - return novels; - }); -}; -exports.searchNovels = searchNovels; -exports.fetchImage = fetch_1.fetchFile; -exports.filters = [ - { - key: "sort", - label: "Сортировка", - values: [ - { label: "по рейтингу", value: "computed_rating" }, - { label: "по дате обновления", value: "last_chapter_at" }, - { label: "по дате добавления", value: "created_at" }, - { label: "по названию", value: "name_rus" }, - { label: "по просмотрам", value: "views" }, - { label: "по количеству глав", value: "count_chapters" }, - { label: "по объему перевода", value: "count_of_symbols" }, - ], - inputType: filterInputs_1.FilterInputs.Picker, - }, - { - key: "status", - label: "Статус перевода", - values: [ - { label: "Любой", value: "" }, - { label: "В процессе", value: "1" }, - { label: "Завершено", value: "2" }, - { label: "Заморожено", value: "3" }, - { label: "Неизвестно", value: "4" }, - ], - inputType: filterInputs_1.FilterInputs.Picker, - }, - { - key: "country", - label: "Тип", - values: [ - { label: "Китай", value: "2" }, - { label: "Корея", value: "3" }, - { label: "США", value: "4" }, - { label: "Япония", value: "1" }, - ], - inputType: filterInputs_1.FilterInputs.Checkbox, - }, - { - key: "events", - label: "События", - values: [ - { label: "[Награжденная работа]", value: "611" }, - { label: "18+", value: "338" }, - { label: "Авантюристы", value: "353" }, - { label: "Автоматоны", value: "538" }, - { label: "Агрессивные персонажи", value: "434" }, - { label: "Ад", value: "509" }, - { label: "Адаптация в радиопостановку", value: "522" }, - { label: "Академия", value: "25" }, - { label: "Актеры озвучки", value: "578" }, - { label: "Активный главный герой", value: "132" }, - { label: "Алхимия", value: "116" }, - { label: "Альтернативный мир", value: "28" }, - { label: "Амнезия/Потеря памяти", value: "247" }, - { label: "Анабиоз", value: "657" }, - { label: "Ангелы", value: "218" }, - { label: "Андрогинные персонажи", value: "217" }, - { label: "Андроиды", value: "82" }, - { label: "Анти-магия", value: "471" }, - { label: "Антигерой", value: "346" }, - { label: "Антикварный магазин", value: "572" }, - { label: "Антисоциальный главный герой", value: "562" }, - { label: "Антиутопия", value: "663" }, - { label: "Апатичный протагонист", value: "29" }, - { label: "Апокалипсис", value: "314" }, - { label: "Аранжированный брак", value: "285" }, - { label: "Армия", value: "598" }, - { label: "Артефакты", value: "117" }, - { label: "Артисты", value: "460" }, - { label: "Банды", value: "581" }, - { label: "БДСМ", value: "676" }, - { label: "Бедный главный герой", value: "309" }, - { label: "Безжалостный главный герой", value: "144" }, - { label: "Беззаботный главный герой", value: "355" }, - { label: "Безусловная любовь", value: "650" }, - { label: "Беременность", value: "131" }, - { label: "Бесполый главный герой", value: "222" }, - { label: "Бессмертные", value: "275" }, - { label: "Бесстрашный протагонист", value: "619" }, - { label: "Бесстыдный главный герой", value: "256" }, - { label: "Бесчестный главный герой", value: "699" }, - { label: "Библиотека", value: "342" }, - { label: "Бизнесмен ", value: "813" }, - { label: "Биочип", value: "120" }, - { label: "Бисексуальный главный герой", value: "822" }, - { label: "Близнецы", value: "148" }, - { label: "Боги", value: "211" }, - { label: "Богини", value: "356" }, - { label: "Боевая академия", value: "369" }, - { label: "Боевые духи", value: "347" }, - { label: "Боевые соревнования", value: "422" }, - { label: "Божественная защита", value: "336" }, - { label: "Божественные силы", value: "224" }, - { - label: "Большая разница в возрасте между героем и его любовным интересом", - value: "348", - }, - { label: "Борьба за власть", value: "544" }, - { label: "Брак", value: "363" }, - { label: "Брак по расчету", value: "65" }, - { label: "Братский комплекс", value: "31" }, - { label: "Братство", value: "413" }, - { label: "Братья и сестры", value: "518" }, - { label: "Буддизм", value: "742" }, - { label: "Быстрая культивация", value: "273" }, - { label: "Быстрообучаемый", value: "221" }, - { label: "Валькирии", value: "667" }, - { label: "Вампиры", value: "266" }, - { label: "Ваншот", value: "679" }, - { label: "Ведьмы", value: "169" }, - { label: "Вежливый главный герой", value: "289" }, - { label: "Верные подчиненные", value: "225" }, - { label: "Взрослый главный герой", value: "183" }, - { label: "Видит то, чего не видят другие", value: "636" }, - { label: "Виртуальная реальность", value: "313" }, - { label: "Владелец магазина", value: "653" }, - { label: "Внезапная сила", value: "376" }, - { label: "Внезапное богатство", value: "802" }, - { - label: "Внешний вид отличается от фактического возраста", - value: "334", - }, - { label: "Военные Летописи", value: "740" }, - { label: "Возвращение из другого мира", value: "673" }, - { label: "Войны", value: "58" }, - { label: "Вокалоид", value: "678" }, - { label: "Волшебники/Волшебницы", value: "477" }, - { label: "Волшебные звери", value: "201" }, - { label: "Воображаемый друг", value: "614" }, - { label: "Воры", value: "326" }, - { label: "Воскрешение", value: "78" }, - { label: "Враги становятся возлюбленными", value: "428" }, - { label: "Враги становятся союзниками", value: "502" }, - { label: "Врата в другой мир", value: "558" }, - { label: "Врачи", value: "286" }, - { label: "Временной парадокс", value: "163" }, - { label: "Всемогущий главный герой", value: "42" }, - { label: "Вторжение на землю", value: "77" }, - { label: "Второй шанс", value: "112" }, - { label: "Вуайеризм", value: "851" }, - { label: "Выживание", value: "290" }, - { label: "Высокомерные персонажи", value: "268" }, - { label: "Гадание", value: "540" }, - { label: "Гарем рабов", value: "828" }, - { label: "Геймеры", value: "302" }, - { label: "Генералы", value: "223" }, - { label: "Генетические модификации", value: "620" }, - { label: "Гениальный главный герой", value: "566" }, - { label: "Герои", value: "173" }, - { label: "Героиня — сорванец", value: "525" }, - { label: "Герой влюбляется первым", value: "64" }, - { label: "Гетерохромия", value: "510" }, - { label: "Гильдии", value: "323" }, - { label: "Гипнотизм", value: "768" }, - { label: "Главный герой — бог", value: "486" }, - { label: "Главный герой — гуманоид", value: "595" }, - { label: "Главный герой — женщина", value: "63" }, - { label: "Главный герой — мужчина", value: "39" }, - { label: "Главный герой — наполовину человек", value: "362" }, - { label: "Главный герой — отец", value: "859" }, - { label: "Главный герой — раб", value: "832" }, - { label: "Главный герой — ребенок", value: "415" }, - { label: "Главный герой — рубака", value: "400" }, - { label: "Главный герой — собиратель гарема", value: "439" }, - { label: "Главный герой влюбляется первым", value: "655" }, - { label: "Главный герой играет роль", value: "396" }, - { label: "Главный герой носит очки", value: "637" }, - { label: "Главный герой пацифист", value: "675" }, - { label: "Главный герой с несколькими телами", value: "628" }, - { label: "Главный герой силен с самого начала", value: "45" }, - { label: "Гладиаторы", value: "549" }, - { label: "Глуповатый главный герой", value: "295" }, - { label: "Гоблины", value: "529" }, - { label: "Големы", value: "569" }, - { label: "Гомункул", value: "850" }, - { label: "Горничные", value: "380" }, - { label: "Госпиталь", value: "1043" }, - { label: "Готовка", value: "193" }, - { label: "Гриндинг", value: "303" }, - { label: "Дао Компаньон", value: "384" }, - { label: "Даосизм", value: "792" }, - { label: "Дарк", value: "151" }, - { label: "Дварфы", value: "220" }, - { label: "Двойная личность", value: "601" }, - { label: "Двойник", value: "547" }, - { label: "Дворецкий", value: "623" }, - { label: "Дворяне", value: "41" }, - { label: "Дворянство/Аристократия", value: "354" }, - { label: "Девушки-монстры", value: "634" }, - { label: "Демоническая техника культивации", value: "706" }, - { label: "Демоны", value: "6" }, - { label: "Денежный долг", value: "841" }, - { label: "Депрессия", value: "494" }, - { label: "Детективы", value: "561" }, - { label: "Дискриминация", value: "34" }, - { - label: "Добыча денег одно из основных стремлений главного героя", - value: "307", - }, - { label: "Долгая разлука", value: "200" }, - { label: "Домашние дела", value: "178" }, - { label: "Домогательство", value: "394" }, - { label: "Драконы", value: "195" }, - { label: "Драконьи всадники", value: "555" }, - { label: "Древние времена", value: "102" }, - { label: "Древний Китай", value: "284" }, - { label: "Дружба", value: "97" }, - { label: "Друзья детства", value: "170" }, - { label: "Друзья становятся врагами", value: "507" }, - { label: "Друиды", value: "427" }, - { label: "Дух лисы", value: "842" }, - { label: "Духи/Призраки", value: "46" }, - { label: "Духовный советник", value: "351" }, - { label: "Душевность", value: "587" }, - { label: "Души", value: "136" }, - { label: "Европейская атмосфера", value: "457" }, - { label: "Ёкаи", value: "516" }, - { label: "Есть аниме-адаптация", value: "26" }, - { label: "Есть видеоигра по мотивам", value: "491" }, - { label: "Есть манга-адаптация", value: "27" }, - { label: "Есть манхва-адаптация", value: "453" }, - { label: "Есть маньхуа-адаптация", value: "298" }, - { label: "Есть сериал-адаптация", value: "421" }, - { label: "Есть фильм по мотивам", value: "47" }, - { label: "Женища-наставник", value: "438" }, - { - label: "Жертва изнасилования влюбляется в насильника", - value: "414", - }, - { label: "Жесткая, двуличная личность", value: "249" }, - { label: "Жестокие персонажи", value: "436" }, - { label: "Жестокое обращение с ребенком", value: "617" }, - { label: "Жестокость", value: "127" }, - { label: "Животноводство", value: "765" }, - { label: "Животные черты", value: "466" }, - { label: "Жизнь в квартире", value: "554" }, - { label: "Жрицы", value: "564" }, - { label: "Заботливый главный герой", value: "176" }, - { label: "Забывчивый главный герой", value: "579" }, - { label: "Заговоры", value: "177" }, - { label: "Закалка тела", value: "269" }, - { label: "Законники", value: "769" }, - { label: "Замкнутый главный герой", value: "533" }, - { label: "Запечатанная сила", value: "344" }, - { label: "Застенчивые персонажи", value: "443" }, - { label: "Звери", value: "119" }, - { label: "Звери-компаньоны", value: "192" }, - { label: "Злой протагонист", value: "125" }, - { label: "Злые боги", value: "437" }, - { label: "Злые организации", value: "503" }, - { label: "Злые религии", value: "725" }, - { label: "Знаменитости", value: "397" }, - { label: "Знаменитый главный герой", value: "469" }, - { label: "Знания современного мира", value: "185" }, - { label: "Зомби", value: "321" }, - { label: "Игра на выживание", value: "162" }, - { label: "Игривый протагонист", value: "700" }, - { label: "Игровая система рейтинга", value: "301" }, - { label: "Игровые элементы", value: "152" }, - { label: "Игрушки (18+)", value: "644" }, - { label: "Из грязи в князи", value: "330" }, - { label: "Из женщины в мужчину ", value: "688" }, - { label: "Из мужчины в женщину", value: "698" }, - { label: "Из полного в худого", value: "809" }, - { label: "Из слабого в сильного", value: "81" }, - { label: "Из страшно(го/й) в красиво(го/ю)", value: "810" }, - { label: "Извращенный главный герой", value: "349" }, - { label: "Изгои", value: "472" }, - { label: "Изменение расы", value: "627" }, - { label: "Изменения внешнего вида", value: "191" }, - { label: "Изменения личности", value: "99" }, - { label: "Изнасилование", value: "110" }, - { label: "Изображения жестокости", value: "260" }, - { label: "Империи", value: "749" }, - { label: "Инвалидность", value: "656" }, - { label: "Индустриализация", value: "180" }, - { label: "Инженер", value: "35" }, - { label: "Инцест", value: "463" }, - { label: "Искусственный интеллект", value: "118" }, - { label: "Исследования", value: "635" }, - { label: "Каннибализм", value: "377" }, - { label: "Карточные игры", value: "654" }, - { label: "Киберспорт", value: "658" }, - { label: "Кланы", value: "950" }, - { - label: "Класс безработного [Игровой класс в игре]", - value: "727", - }, - { label: "Клоны", value: "365" }, - { label: "Клубы", value: "96" }, - { label: "Книги", value: "341" }, - { label: "Книги навыков", value: "312" }, - { label: "Книжный червь", value: "455" }, - { label: "Коварство", value: "111" }, - { label: "Коллеги", value: "683" }, - { label: "Колледж/Университет", value: "712" }, - { label: "Кома", value: "826" }, - { label: "Командная работа", value: "426" }, - { label: "Комедийный оттенок", value: "523" }, - { label: "Комплекс неполноценности", value: "489" }, - { label: "Комплекс семейных отношений", value: "104" }, - { label: "Конкуренция", value: "746" }, - { label: "Контракты", value: "483" }, - { label: "Контроль разума/сознания", value: "262" }, - { label: "Копейщик", value: "339" }, - { label: "Королевская битва", value: "1025" }, - { label: "Королевская власть", value: "53" }, - { label: "Королевства", value: "141" }, - { label: "Коррупция", value: "378" }, - { label: "Космические войны", value: "674" }, - { label: "Красивый герой", value: "107" }, - { label: "Крафт", value: "287" }, - { label: "Кризис личности", value: "599" }, - { label: "Кругосветное путешествие", value: "257" }, - { label: "Кудере", value: "440" }, - { label: "Кузены", value: "701" }, - { label: "Кузнец", value: "454" }, - { label: "Кукловоды", value: "431" }, - { label: "Куклы/марионетки", value: "573" }, - { label: "Культивация", value: "123" }, - { label: "Куннилингус", value: "632" }, - { label: "Легенды", value: "430" }, - { label: "Легкая жизнь", value: "604" }, - { label: "Ленивый главный герой", value: "570" }, - { label: "Лидерство", value: "424" }, - { label: "Лоли", value: "92" }, - { label: "Лотерея", value: "401" }, - { label: "Любовный интерес влюбляется первым", value: "647" }, - { - label: "Любовный интерес главного героя носит очки", - value: "576", - }, - { label: "Любовный треугольник", value: "98" }, - { label: "Любовь детства", value: "500" }, - { label: "Любовь с первого взгляда", value: "730" }, - { label: "Магические надписи", value: "373" }, - { label: "Магические печати", value: "277" }, - { label: "Магические технологии", value: "357" }, - { - label: "Магическое пространство/измерение, доступное не всем персонажам", - value: "244", - }, - { label: "Магия", value: "38" }, - { label: "Магия призыва", value: "333" }, - { label: "Мазохистские персонажи", value: "660" }, - { label: "Манипулятивные персонажи", value: "130" }, - { label: "Мания", value: "91" }, - { label: "Мастер на все руки", value: "390" }, - { label: "Мастурбация", value: "846" }, - { label: "Махо-сёдзё", value: "496" }, - { label: "Медицинские знания", value: "441" }, - { label: "Медленная романтическая линия", value: "113" }, - { label: "Медленное развитие на старте ", value: "670" }, - { label: "Межпространственные путешествия", value: "316" }, - { label: "Менеджмент", value: "182" }, - { label: "Мертвый главный герой", value: "794" }, - { label: "Месть", value: "88" }, - { label: "Метаморфы", value: "234" }, - { label: "Меч и магия", value: "55" }, - { label: "Мечник", value: "607" }, - { label: "Мечты", value: "733" }, - { label: "Милая история", value: "709" }, - { label: "Милое дитя", value: "596" }, - { label: "Милый главный герой", value: "697" }, - { label: "Мировое дерево", value: "385" }, - { label: "Мистический ореол вокруг семьи", value: "409" }, - { label: "Мифические звери", value: "418" }, - { label: "Мифология", value: "468" }, - { label: "Младшие братья", value: "843" }, - { label: "Младшие сестры", value: "465" }, - { label: "ММОРПГ (ЛитРПГ)", value: "306" }, - { label: "Множество перемещенных людей", value: "488" }, - { label: "Множество реальностей", value: "278" }, - { label: "Множество реинкарнированных людей", value: "227" }, - { label: "Модели", value: "649" }, - { label: "Молчаливый персонаж", value: "705" }, - { label: "Монстры", value: "69" }, - { label: "Мужская гей-пара", value: "685" }, - { label: "Мужчина-яндере", value: "155" }, - { label: "Музыка", value: "589" }, - { label: "Музыкальные группы", value: "588" }, - { label: "Мутации", value: "668" }, - { label: "Мутированные существа", value: "317" }, - { label: "Навык кражи", value: "626" }, - { label: "Навязчивая любовь", value: "85" }, - { label: "Наемники", value: "324" }, - { label: "Назойливый возлюбленный", value: "501" }, - { label: "Наивный главный герой", value: "66" }, - { label: "Наркотики", value: "661" }, - { label: "Нарциссический главный герой", value: "470" }, - { label: "Насилие сексуального характера", value: "824" }, - { label: "Наследование", value: "372" }, - { label: "Национализм", value: "318" }, - { label: "Не блещущий внешне главный герой", value: "328" }, - { label: "Не родные братья и сестры", value: "464" }, - { label: "Небеса", value: "508" }, - { label: "Небесное испытание", value: "274" }, - { label: "Негуманоидный главный герой", value: "622" }, - { label: "Недоверчивый главный герой", value: "485" }, - { label: "Недооцененный главный герой", value: "140" }, - { label: "Недоразумения", value: "202" }, - { label: "Неизлечимая болезнь", value: "75" }, - { label: "Некромант", value: "308" }, - { label: "Нелинейная история", value: "157" }, - { label: "Ненавистный главный герой", value: "487" }, - { label: "Ненадежный рассказчик", value: "165" }, - { label: "Нерезиденты", value: "821" }, - { label: "Нерешительный главный герой", value: "741" }, - { label: "Несерьезный главный герой", value: "294" }, - { label: "Несколько временных линий", value: "517" }, - { label: "Несколько главных героев", value: "475" }, - { label: "Несколько идентичностей", value: "615" }, - { label: "Несколько личностей", value: "474" }, - { label: "Нетораре", value: "721" }, - { label: "Нетори", value: "450" }, - { label: "Неудачливый главный герой", value: "567" }, - { label: "Ниндзя", value: "358" }, - { label: "Обещание из детства", value: "738" }, - { label: "Обманщик", value: "411" }, - { label: "Обмен телами", value: "94" }, - { label: "Обнаженка", value: "417" }, - { label: "Обольщение", value: "718" }, - { label: "Оборотни", value: "624" }, - { label: "Обратный гарем", value: "255" }, - { label: "Общество монстров", value: "226" }, - { label: "Обязательство", value: "548" }, - { label: "Огнестрельное оружие", value: "179" }, - { label: "Ограниченная продолжительность жизни", value: "73" }, - { label: "Одержимость", value: "447" }, - { label: "Одинокий главный герой", value: "304" }, - { label: "Одиночество", value: "199" }, - { label: "Одиночное проживание", value: "207" }, - { label: "Околосмертные переживания", value: "773" }, - { label: "Оммёдзи", value: "542" }, - { label: "Омоложение", value: "237" }, - { label: "Организованная преступность", value: "478" }, - { label: "Оргия", value: "825" }, - { label: "Орки", value: "228" }, - { label: "Освоение навыков", value: "235" }, - { label: "Основано на аниме", value: "553" }, - { label: "Основано на видео игре", value: "704" }, - { label: "Основано на визуальной новелле ", value: "861" }, - { label: "Основано на песне", value: "677" }, - { label: "Основано на фильме", value: "552" }, - { label: "Осторожный главный герой", value: "122" }, - { label: "Отаку", value: "512" }, - { label: "Открытый космос", value: "150" }, - { label: "Отношения в сети", value: "713" }, - { label: "Отношения между богом и человеком", value: "603" }, - { label: "Отношения между людьми и нелюдьми", value: "205" }, - { label: "Отношения на расстоянии", value: "852" }, - { label: "Отношения начальник-подчиненный", value: "590" }, - { label: "Отношения Сенпай-Коухай", value: "513" }, - { label: "Отношения ученика и учителя", value: "451" }, - { label: "Отношения учитель-ученик", value: "343" }, - { label: "Отношения хозяин-слуга", value: "206" }, - { label: "Отомэ игра", value: "723" }, - { label: "Отсутствие здравого смысла", value: "605" }, - { label: "Отсутствие родителей", value: "575" }, - { label: "Офисный роман", value: "686" }, - { label: "Официанты", value: "681" }, - { label: "Охотники", value: "288" }, - { label: "Очаровательный главный герой", value: "659" }, - { label: "Падшее дворянство", value: "618" }, - { label: "Падшие ангелы", value: "505" }, - { label: "Пайзури", value: "630" }, - { label: "Паразиты", value: "535" }, - { label: "Параллельные миры", value: "86" }, - { label: "Парк развлечений", value: "586" }, - { label: "Пародия", value: "319" }, - { label: "Певцы/Певицы", value: "734" }, - { label: "Первая любовь", value: "716" }, - { label: "Первоисточник новеллы — манга", value: "560" }, - { label: "Первый раз", value: "845" }, - { - label: "Перемещение в другой мир, имея при себе современные достижения", - value: "732", - }, - { label: "Перемещение в игровой мир", value: "532" }, - { label: "Перемещение в иной мир", value: "754" }, - { label: "Перерождение в ином мире", value: "755" }, - { label: "Переселение души/Трансмиграция", value: "139" }, - { label: "Персонаж использует щит", value: "631" }, - { label: "Петля времени", value: "79" }, - { label: "Пираты", value: "817" }, - { label: "Писатели", value: "408" }, - { label: "Питомцы", value: "253" }, - { label: "Племенное общество", value: "291" }, - { label: "Повелитель демонов", value: "171" }, - { - label: "Повествование от нескольких лиц/Несколько точек зрения", - value: "156", - }, - { label: "Подземелья", value: "219" }, - { label: "Пожелания", value: "166" }, - { label: "Познание Дао", value: "360" }, - { label: "Покинутое дитя", value: "534" }, - { label: "Полигамия", value: "296" }, - { label: "Политика", value: "43" }, - { label: "Полиция", value: "801" }, - { label: "Полулюди", value: "335" }, - { label: "Пользователь уникального оружия", value: "432" }, - { label: "Популярный любовный интерес", value: "241" }, - { label: "Постапокалиптика", value: "60" }, - { label: "Потерянные цивилизации", value: "751" }, - { label: "Похищения людей", value: "707" }, - { label: "Поэзия", value: "404" }, - { label: "Правонарушители", value: "694" }, - { label: "Прагматичный главный герой", value: "536" }, - { label: "Преданный любовный интерес", value: "106" }, - { label: "Предательство", value: "103" }, - { label: "Предвидение", value: "52" }, - { label: "Прекрасная героиня", value: "30" }, - { label: "Преступники", value: "728" }, - { label: "Преступность", value: "83" }, - { label: "Призванный герой", value: "147" }, - { label: "Призраки", value: "51" }, - { label: "Принуждение к отношениям", value: "602" }, - { label: "Принцессы", value: "933" }, - { label: "Притворная пара", value: "600" }, - { label: "Причудливые персонажи", value: "297" }, - { label: "Пришельцы/Инопланетяне", value: "76" }, - { label: "Программист", value: "666" }, - { label: "Проклятия", value: "48" }, - { label: "Промывание мозгов", value: "519" }, - { label: "Пропуск времени", value: "138" }, - { label: "Пророчества", value: "429" }, - { label: "Проститутки", value: "844" }, - { label: "Пространственное манипулирование", value: "375" }, - { label: "Прошлое играет большую роль", value: "215" }, - { label: "Прыжки между мирами", value: "737" }, - { label: "Психические силы", value: "265" }, - { label: "Психопаты", value: "158" }, - { label: "Путешествие во времени", value: "80" }, - { label: "Пытка", value: "168" }, - { label: "Рабы", value: "829" }, - { label: "Развод", value: "771" }, - { label: "Разумные предметы", value: "174" }, - { label: "Расизм", value: "320" }, - { label: "Рассказ", value: "61" }, - { label: "Расторжения помолвки", value: "243" }, - { label: "Расы зооморфов", value: "209" }, - { label: "Ревность", value: "717" }, - { label: "Редакторы", value: "684" }, - { label: "Реинкарнация", value: "281" }, - { label: "Реинкарнация в монстра", value: "204" }, - { label: "Реинкарнация в объект", value: "692" }, - { label: "Религии", value: "565" }, - { label: "Репортеры", value: "837" }, - { label: "Ресторан", value: "652" }, - { label: "Решительный главный герой", value: "124" }, - { label: "Робкий главный герой", value: "800" }, - { label: "Родитель одиночка", value: "687" }, - { label: "Родительский комплекс", value: "531" }, - { label: "Родословная", value: "121" }, - { label: "Романтический подсюжет ", value: "159" }, - { label: "Рост персонажа", value: "95" }, - { label: "Рыцари", value: "142" }, - { label: "Садистские персонажи", value: "642" }, - { label: "Самоотверженный главный герой", value: "748" }, - { label: "Самоубийства", value: "616" }, - { label: "Самурай", value: "646" }, - { label: "Сборник коротких историй", value: "456" }, - { label: "Связанные сюжетные линии", value: "473" }, - { label: "Святые", value: "761" }, - { label: "Священники", value: "325" }, - { label: "Сдержанный главный герой", value: "799" }, - { label: "Секретные организации", value: "331" }, - { label: "Секреты", value: "577" }, - { label: "Секс рабы", value: "830" }, - { label: "Семейный конфликт", value: "770" }, - { label: "Семь добродетелей", value: "233" }, - { label: "Семь смертных грехов", value: "134" }, - { label: "Семья", value: "251" }, - { label: "Сёнэн-ай подсюжет ", value: "664" }, - { label: "Серийные убийцы", value: "497" }, - { label: "Сестринский комплекс", value: "498" }, - { label: "Сила духа", value: "282" }, - { label: "Сила, требующая платы за пользование", value: "520" }, - { label: "Сильная пара", value: "109" }, - { label: "Сильный в сильнейшего", value: "359" }, - { label: "Сильный любовный интерес", value: "161" }, - { label: "Синдром восьмиклассника", value: "90" }, - { label: "Сироты", value: "214" }, - { label: "Система уровней", value: "198" }, - { label: "Системный администратор", value: "476" }, - { label: "Скрытие истинной личности", value: "371" }, - { label: "Скрытие истинных способностей", value: "252" }, - { label: "Скрытный главный герой", value: "133" }, - { label: "Скрытые способности", value: "128" }, - { label: "Скульпторы", value: "366" }, - { label: "Слабо выраженная романтическая линия", value: "213" }, - { label: "Слабый главный герой", value: "188" }, - { label: "Слепой главный герой", value: "864" }, - { label: "Слуги", value: "232" }, - { label: "Смерть", value: "49" }, - { label: "Смерть близких", value: "361" }, - { label: "Собственнические персонажи", value: "108" }, - { label: "Современность", value: "40" }, - { label: "Сожительство", value: "482" }, - { label: "Создание армии", value: "175" }, - { label: "Создание артефактов", value: "292" }, - { label: "Создание клана", value: "448" }, - { label: "Создание королевства", value: "181" }, - { label: "Создание навыков", value: "236" }, - { label: "Создание секты", value: "393" }, - { label: "Солдаты/Военные", value: "71" }, - { label: "Сон", value: "571" }, - { label: "Состоятельные персонажи", value: "67" }, - { label: "Социальная иерархия на основе силы", value: "137" }, - { label: "Социальные изгои", value: "480" }, - { label: "Спасение мира", value: "597" }, - { label: "Специальные способности", value: "54" }, - { label: "Спокойный главный герой", value: "32" }, - { label: "Справедливый главный герой", value: "702" }, - { label: "Средневековье", value: "184" }, - { label: "Ссорящаяся пара", value: "293" }, - { label: "Сталкеры", value: "689" }, - { label: "Старение", value: "190" }, - { label: "Стоические персонажи", value: "444" }, - { label: "Стокгольмский синдром", value: "643" }, - { label: "Стратег", value: "425" }, - { label: "Стратегические битвы", value: "160" }, - { label: "Стратегия", value: "1038" }, - { label: "Стрелки", value: "458" }, - { label: "Стрельба из лука", value: "383" }, - { label: "Студенческий совет", value: "490" }, - { label: "Судьба", value: "271" }, - { label: "Суккубы", value: "484" }, - { label: "Супер герои", value: "1039" }, - { label: "Суровая подготовка", value: "261" }, - { label: "Таинственная болезнь", value: "74" }, - { label: "Таинственное прошлое", value: "263" }, - { label: "Тайная личность", value: "310" }, - { label: "Тайные отношения", value: "812" }, - { label: "Танцоры", value: "840" }, - { label: "Телохранители", value: "452" }, - { label: "Тентакли", value: "693" }, - { label: "Террористы", value: "515" }, - { label: "Технологический разрыв", value: "621" }, - { label: "Тихие персонажи", value: "546" }, - { label: "Толстый главный герой", value: "299" }, - { label: "Торговцы", value: "416" }, - { label: "Травля/Буллинг", value: "89" }, - { label: "Травник", value: "708" }, - { label: "Трагическое прошлое", value: "164" }, - { label: "Трансплантация воспоминаний", value: "367" }, - { label: "Трап (Путаница с гендером персонажа)", value: "582" }, - { label: "Трудолюбивый главный герой", value: "37" }, - { label: "Тюрьма", value: "479" }, - { label: "Убийства", value: "84" }, - { label: "Убийцы", value: "248" }, - { label: "Убийцы драконов", value: "606" }, - { label: "Уверенный главный герой", value: "270" }, - { label: "Удачливый главный герой", value: "402" }, - { label: "Укротитель монстров", value: "337" }, - { label: "Умения из прошлой жизни", value: "280" }, - { label: "Умная пара", value: "493" }, - { label: "Умный главный герой", value: "33" }, - { label: "Уникальная техника Культивации", value: "254" }, - { label: "Уникальное оружие", value: "340" }, - { label: "Управление бизнесом", value: "315" }, - { label: "Управление временем", value: "167" }, - { label: "Управление кровью", value: "764" }, - { label: "Упрямый главный герой", value: "672" }, - { label: "Уродливый главный герой", value: "803" }, - { label: "Ускоренный рост", value: "300" }, - { label: "Усыновленные дети", value: "481" }, - { label: "Усыновленный главный герой", value: "412" }, - { label: "Уход за детьми", value: "398" }, - { label: "Учителя", value: "345" }, - { label: "Фамильяры", value: "541" }, - { label: "Фанатизм", value: "613" }, - { label: "Фантастические существа", value: "322" }, - { label: "Фанфикшн", value: "388" }, - { label: "Фармацевт", value: "715" }, - { label: "Фарминг", value: "379" }, - { label: "Феи", value: "210" }, - { label: "Фелляция", value: "584" }, - { label: "Фениксы", value: "374" }, - { label: "Фетиш груди", value: "499" }, - { label: "Философия", value: "87" }, - { label: "Фильмы", value: "403" }, - { label: "Флэшбэки", value: "528" }, - { label: "Фобии", value: "100" }, - { label: "Фольклор", value: "467" }, - { label: "Футанари", value: "568" }, - { label: "Футуристический сеттинг", value: "382" }, - { label: "Фэнтези мир", value: "126" }, - { label: "Хакеры", value: "399" }, - { label: "Харизматический герой", value: "391" }, - { label: "Хикикомори/Затворники", value: "462" }, - { label: "Хитроумный главный герой", value: "105" }, - { label: "Хозяин подземелий", value: "557" }, - { label: "Холодный главный герой", value: "259" }, - { label: "Хорошие отношения с семьей", value: "506" }, - { label: "Хранители могил", value: "68" }, - { label: "Целители", value: "389" }, - { label: "Цзянши", value: "735" }, - { label: "Цундэрэ", value: "445" }, - { label: "Чаты", value: "580" }, - { label: "Человеческое оружие", value: "521" }, - { label: "Честный главный герой", value: "240" }, - { label: "Читы", value: "238" }, - { label: "Шантаж", value: "526" }, - { label: "Шеф-повар", value: "239" }, - { label: "Шикигами", value: "543" }, - { label: "Школа только для девочек", value: "633" }, - { label: "Шота", value: "514" }, - { label: "Шоу-бизнес", value: "407" }, - { label: "Шпионы", value: "563" }, - { label: "Эволюция", value: "196" }, - { label: "Эгоистичный главный герой", value: "539" }, - { label: "Эйдетическая память", value: "392" }, - { label: "Экзорсизм", value: "504" }, - { label: "Экономика", value: "492" }, - { label: "Эксгибиционизм", value: "639" }, - { label: "Эксперименты с людьми", value: "129" }, - { label: "Элементальная магия", value: "395" }, - { label: "Эльфы", value: "172" }, - { label: "Эмоционально слабый главный герой", value: "816" }, - { label: "Эпизодический", value: "612" }, - { label: "Юный любовный интерес", value: "446" }, - { label: "Яды", value: "410" }, - { label: "Языкастые персонажи", value: "406" }, - { label: "Языковой барьер", value: "59" }, - { label: "Яндере", value: "208" }, - { label: "Японские силы самообороны", value: "559" }, - { label: "Ярко выраженная романтическая линия", value: "272" }, - { label: "Abusive Characters", value: "625" }, - { label: "Adapted to Visual Novel", value: "1046" }, - { label: "Adopted-lead", value: "886" }, - { label: "Adultery", value: "866" }, - { label: "Affair", value: "645" }, - { label: "Age-gap", value: "923" }, - { label: "Almost-human-lead", value: "975" }, - { label: "An*l", value: "780" }, - { label: "Androgynous-male-lead", value: "1002" }, - { label: "Anti-hero-lead", value: "976" }, - { label: "Apathetic-lead", value: "967" }, - { label: "Arms Dealers", value: "839" }, - { label: "Army-commander", value: "1003" }, - { label: "Artifact-refining", value: "924" }, - { label: "Autism", value: "855" }, - { label: "Awkward Protagonist", value: "669" }, - { label: "Awkward-lead", value: "892" }, - { label: "Bestiality", value: "796" }, - { label: "Big-breasts", value: "908" }, - { label: "Birth-of-a-nation", value: "1004" }, - { label: "Bisexual-lead", value: "1027" }, - { label: "Body-refining", value: "947" }, - { label: "Body-swap/s", value: "1036" }, - { label: "Boss-subordinate-relationship", value: "876" }, - { label: "Bride-kidnapping", value: "948" }, - { label: "Caring-lead", value: "879" }, - { label: "Cautious-lead", value: "1032" }, - { label: "Changed-man", value: "925" }, - { label: "Charismatic-lead", value: "1005" }, - { label: "Child-lead", value: "936" }, - { label: "Clever-lead", value: "880" }, - { label: "Clumsy Love Interests", value: "815" }, - { label: "Cold Love Interests", value: "651" }, - { label: "Coming of Age", value: "860" }, - { label: "Confident-lead", value: "894" }, - { label: "Confident-male-lead", value: "951" }, - { label: "Confinement", value: "767" }, - { label: "Conflicting Loyalties", value: "793" }, - { label: "Couple Growth", value: "690" }, - { label: "Court Official", value: "863" }, - { label: "Cowardly Protagonist", value: "703" }, - { label: "Cowardly-lead", value: "1000" }, - { label: "Cross-dressing", value: "250" }, - { label: "Cunnilingus", value: "867" }, - { label: "Cunning-lead", value: "952" }, - { label: "Cunning-male-lead", value: "953" }, - { label: "Curious Protagonist", value: "849" }, - { label: "Cute-lead", value: "887" }, - { label: "Dense-lead", value: "868" }, - { label: "Determined-lead", value: "972" }, - { label: "Developing-technology", value: "1006" }, - { label: "Devil/s", value: "1007" }, - { label: "Different Social Status", value: "758" }, - { label: "Disfigurement", value: "838" }, - { label: "Doting Love Interests", value: "665" }, - { label: "Doting Older Siblings", value: "609" }, - { label: "Doting Parents", value: "530" }, - { label: "Dungeon/s-exploring", value: "990" }, - { label: "Elderly Protagonist", value: "774" }, - { label: "Enlightenment", value: "729" }, - { label: "Eunuch", value: "1047" }, - { label: "Eye Powers", value: "386" }, - { label: "Family Business", value: "785" }, - { label: "Famous Parents", value: "790" }, - { label: "Famous-lead", value: "897" }, - { label: "Fanfic", value: "942" }, - { label: "Fated Lovers", value: "797" }, - { label: "Fellatio", value: "870" }, - { label: "Female-lead", value: "888" }, - { label: "First-time-intercourse", value: "871" }, - { label: "Fleet Battles", value: "836" }, - { label: "Forced Living Arrangements", value: "808" }, - { label: "Forced Marriage", value: "835" }, - { label: "Former Hero", value: "752" }, - { label: "Fujoshi", value: "1045" }, - { label: "Galge", value: "848" }, - { label: "Gambling", value: "1031" }, - { label: "Gamelit", value: "994" }, - { label: "Genderless-lead", value: "1008" }, - { label: "Glasses-wearing-lead", value: "995" }, - { label: "Guardian Relationship", value: "197" }, - { label: "H*ndjob", value: "629" }, - { label: "Half-human-lead", value: "956" }, - { label: "Hard-working-lead", value: "957" }, - { label: "Hard-working-male-lead", value: "958" }, - { label: "Hard-working-protagonist/s", value: "1030" }, - { label: "Harem-seeking-lead", value: "929" }, - { label: "Harem-subtext", value: "909" }, - { label: "Helpful Protagonist", value: "760" }, - { label: "Helpful-lead", value: "882" }, - { label: "Hidden-gem", value: "998" }, - { label: "High-fantasy", value: "991" }, - { label: "Human-becomes-demon/monster", value: "1009" }, - { label: "Human-nonhuman-relationship", value: "914" }, - { label: "Humanoid-lead", value: "915" }, - { label: "Imperial Harem", value: "805" }, - { label: "Incubus", value: "1049" }, - { label: "Insects", value: "831" }, - { label: "Interspatial-storage", value: "959" }, - { label: "Kind Love Interests", value: "757" }, - { label: "Large-number-of-skills", value: "1010" }, - { label: "Legendary-hero", value: "1011" }, - { label: "Litrpg", value: "977" }, - { label: "Love Rivals", value: "788" }, - { label: "Lovers Reunited", value: "853" }, - { label: "Low-fantasy", value: "1037" }, - { label: "Master-disciple-relationship", value: "899" }, - { label: "Matriarchy", value: "807" }, - { label: "Mature-lead", value: "900" }, - { label: "Mind Break", value: "862" }, - { label: "Mismatched Couple", value: "695" }, - { label: "Mob Protagonist", value: "648" }, - { label: "Mob-lead", value: "902" }, - { label: "Modern", value: "988" }, - { label: "Monster-pov", value: "1012" }, - { label: "Mpreg", value: "856" }, - { label: "Multiple-povs", value: "1013" }, - { label: "Mystery Solving", value: "710" }, - { label: "Naive-lead", value: "1014" }, - { label: "Near-death-experience", value: "996" }, - { label: "Neet", value: "495" }, - { label: "Nightmares", value: "833" }, - { label: "Nobility", value: "1015" }, - { label: "Non-human-lead", value: "978" }, - { label: "Non-humanoid-lead", value: "1016" }, - { label: "Not-so-secret-identity", value: "979" }, - { label: "Omegaverse", value: "857" }, - { label: "Online-game", value: "910" }, - { label: "Online-gaming", value: "911" }, - { label: "Outdoor Interc**rse", value: "847" }, - { label: "Outdoor-intercourse", value: "903" }, - { label: "Overprotective Siblings", value: "610" }, - { label: "Part-Time Job", value: "865" }, - { label: "Past Trauma", value: "726" }, - { label: "Past-memories", value: "1017" }, - { label: "Persistent Love Interests", value: "714" }, - { label: "Perverted-lead", value: "932" }, - { label: "Photography", value: "798" }, - { label: "Pill Based Cultivation", value: "279" }, - { label: "Pill Concocting", value: "245" }, - { label: "Pilots", value: "820" }, - { label: "Playboys", value: "795" }, - { label: "Playful-lead", value: "989" }, - { label: "Polyandry", value: "811" }, - { label: "Portal-fantasy-/-isekai", value: "992" }, - { label: "Pragmatic-lead", value: "884" }, - { label: "Profanity", value: "980" }, - { label: "Protagonist-loyal-to-love-interest", value: "905" }, - { label: "R-15 (Японское возрастное ограничение)", value: "230" }, - { label: "Rebellion", value: "834" }, - { label: "Reincarnated in a Game World", value: "804" }, - { label: "Reluctant Protagonist", value: "696" }, - { label: "Reverse R*pe", value: "776" }, - { label: "Reversible Couple", value: "854" }, - { label: "Ruling-class", value: "943" }, - { label: "S*x Friends", value: "750" }, - { label: "S*xual Cultivation Technique", value: "823" }, - { label: "Salaryman", value: "1035" }, - { label: "Satire", value: "981" }, - { label: "Schemes And Conspiracies", value: "745" }, - { label: "Scientist/s", value: "997" }, - { label: "Scientists", value: "1029" }, - { label: "Secret Crush", value: "827" }, - { label: "Seme Protagonist", value: "1034" }, - { label: "Seme-lead", value: "1028" }, - { label: "Sentimental Protagonist", value: "1048" }, - { label: "Seven-heavenly-virtues", value: "1018" }, - { label: "Sexual Cultivation Technique", value: "350" }, - { label: "Sexual-content", value: "982" }, - { label: "Sexuality", value: "983" }, - { label: "Sharing A Body", value: "814" }, - { label: "Shotacon", value: "858" }, - { label: "Shoujo-Ai Subplot", value: "777" }, - { label: "Sibling Rivalry", value: "766" }, - { label: "Sibling's Care", value: "1042" }, - { label: "Sickly Characters", value: "787" }, - { label: "Skills", value: "1019" }, - { label: "Slave-harem", value: "1001" }, - { label: "Slime", value: "1020" }, - { label: "Smart-male-lead", value: "963" }, - { label: "Spirit Users", value: "739" }, - { label: "Straight Seme", value: "819" }, - { label: "Straight Uke", value: "818" }, - { label: "Strength-based-social-hierarchy", value: "974" }, - { label: "Strong-lead", value: "944" }, - { label: "Strong-male-lead", value: "964" }, - { label: "Student-teacher-relationship", value: "1026" }, - { label: "Suspense", value: "987" }, - { label: "Sword-and-sorcery", value: "875" }, - { label: "Threesome", value: "574" }, - { label: "Transformation Ability", value: "736" }, - { label: "Traumatising-content", value: "1040" }, - { label: "Underestimated-lead", value: "919" }, - { label: "Underestimated-male-lead", value: "966" }, - { label: "Unique-abilities", value: "1021" }, - { label: "Unique-skill", value: "1022" }, - { label: "Unique-skills", value: "1023" }, - { label: "Unlimited Flow", value: "1044" }, - { label: "Unrequited Love", value: "806" }, - { label: "Urban-fantasy", value: "1041" }, - { label: "Villainess Noble Girls", value: "719" }, - { label: "Weak-lead", value: "885" }, - { label: "Web-novel", value: "1024" }, - ], - inputType: filterInputs_1.FilterInputs.Checkbox, - }, - { - key: "tags", - label: "Жанры", - values: [ - { label: "Боевые искусства", value: "22" }, - { label: "Гарем", value: "114" }, - { label: "Гендер бендер", value: "246" }, - { label: "Дзёсэй", value: "216" }, - { label: "Для взрослых", value: "115" }, - { label: "Для взрослых", value: "258" }, - { label: "Драма", value: "7" }, - { label: "Исторический", value: "101" }, - { label: "Комедия", value: "17" }, - { label: "Лоликон", value: "638" }, - { label: "Магический реализм", value: "922" }, - { label: "Меха", value: "24" }, - { label: "Милитари", value: "12" }, - { label: "Мистика", value: "2" }, - { label: "Научная фантастика", value: "13" }, - { label: "Непристойность", value: "747" }, - { label: "Повседневность", value: "93" }, - { label: "Приключение", value: "11" }, - { label: "Психология", value: "18" }, - { label: "Романтика", value: "9" }, - { label: "Сверхъестественное", value: "20" }, - { label: "Сёдзё", value: "15" }, - { label: "Сёдзё-ай", value: "23" }, - { label: "Сёнэн", value: "189" }, - { label: "Сёнэн-ай", value: "680" }, - { label: "Спорт", value: "420" }, - { label: "Сэйнэн", value: "5" }, - { label: "Сюаньхуа", value: "242" }, - { label: "Сянься", value: "364" }, - { label: "Трагедия", value: "19" }, - { label: "Триллер", value: "3" }, - { label: "Ужасы", value: "1" }, - { label: "Уся", value: "720" }, - { label: "Фэнтези", value: "8" }, - { label: "Школьная жизнь", value: "21" }, - { label: "Экшн", value: "14" }, - { label: "Эччи", value: "327" }, - { label: "Юри", value: "691" }, - { label: "Яой", value: "682" }, - { label: "Eastern fantasy", value: "907" }, - { label: "Isekai", value: "999" }, - { label: "Video games", value: "993" }, - ], - inputType: filterInputs_1.FilterInputs.Checkbox, - }, -]; diff --git a/js/plugins/russian/ranobelib.js b/js/plugins/russian/ranobelib.js deleted file mode 100644 index 805aead..0000000 --- a/js/plugins/russian/ranobelib.js +++ /dev/null @@ -1,374 +0,0 @@ -"use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.filters = exports.fetchImage = exports.searchNovels = exports.parseChapter = exports.parseNovelAndChapters = exports.popularNovels = exports.icon = exports.version = exports.site = exports.name = exports.id = void 0; -const filterInputs_1 = require("@libs/filterInputs"); -const fetch_1 = require("@libs/fetch"); -const novelStatus_1 = require("@libs/novelStatus"); -const cheerio_1 = require("cheerio"); -const dayjs_1 = __importDefault(require("dayjs")); -exports.id = "RLIB"; -exports.name = "RanobeLib"; -exports.site = "https://ranobelib.me"; -exports.version = "1.0.0"; -exports.icon = "src/ru/ranobelib/icon.png"; -var ui; -const popularNovels = function (page, { showLatestNovels, filters }) { - var _a, _b, _c; - return __awaiter(this, void 0, void 0, function* () { - let url = `${exports.site}/manga-list?sort=`; - url += showLatestNovels ? "last_chapter_at" : (filters === null || filters === void 0 ? void 0 : filters.sort) || "rate"; - url += "&dir=" + ((filters === null || filters === void 0 ? void 0 : filters.order) || "desc"); - if (filters) { - if (Array.isArray(filters.type) && filters.type.length) { - url += filters.type.map((i) => `&types[]=${i}`).join(""); - } - if (Array.isArray(filters.format) && ((_a = filters.format) === null || _a === void 0 ? void 0 : _a.length)) { - url += filters.format.map((i) => `&format[include][]=${i}`).join(""); - } - if (Array.isArray(filters.status) && filters.status.length) { - url += filters.status.map((i) => `&status[]=${i}`).join(""); - } - if (Array.isArray(filters.statuss) && filters.statuss.length) { - url += filters.statuss.map((i) => `&manga_status[]=${i}`).join(""); - } - if (Array.isArray(filters.genres) && filters.genres.length) { - url += filters.genres.map((i) => `&genres[include][]=${i}`).join(""); - } - if (Array.isArray(filters.tags) && filters.tags.length) { - url += filters.tags.map((i) => `&tags[include][]=${i}`).join(""); - } - } - url += "&page=" + page; - const result = yield (0, fetch_1.fetchApi)(url); - const body = yield result.text(); - const loadedCheerio = (0, cheerio_1.load)(body); - ui = (_c = (_b = loadedCheerio("a.header-right-menu__item") - .attr("href")) === null || _b === void 0 ? void 0 : _b.replace) === null || _c === void 0 ? void 0 : _c.call(_b, /[^0-9]/g, ""); - let novels = []; - loadedCheerio(".media-card-wrap").each(function () { - const name = loadedCheerio(this).find(".media-card__title").text(); - const cover = loadedCheerio(this).find("a.media-card").attr("data-src"); - const url = loadedCheerio(this).find("a.media-card").attr("href"); - if (!url) - return; - novels.push({ name, cover, url }); - }); - return novels; - }); -}; -exports.popularNovels = popularNovels; -const parseNovelAndChapters = function (novelUrl) { - var _a, _b, _c, _d, _e, _f, _g; - return __awaiter(this, void 0, void 0, function* () { - const result = yield (0, fetch_1.fetchApi)(novelUrl); - const body = yield result.text(); - const loadedCheerio = (0, cheerio_1.load)(body); - let novel = { - url: novelUrl, - }; - novel.name = loadedCheerio(".media-name__main").text().trim(); - novel.cover = loadedCheerio(".media-sidebar__cover img").attr("src"); - novel.summary = loadedCheerio(".media-description__text").text().trim(); - novel.genres = loadedCheerio('div[class="media-tags"]') - .text() - .trim() - .replace(/[\n\r]+/g, ", ") - .replace(/ /g, ""); - loadedCheerio('div[class="media-info-list paper"] > [class="media-info-list__item"]').each(function () { - let name = loadedCheerio(this) - .find('div[class="media-info-list__title"]') - .text(); - if (name === "Статус перевода") { - novel.status = - loadedCheerio(this).find("div:nth-child(2)").text().trim() === - "Продолжается" - ? novelStatus_1.NovelStatus.Ongoing - : novelStatus_1.NovelStatus.Completed; - } - else if (name === "Автор") { - novel.author = loadedCheerio(this) - .find("div:nth-child(2)") - .text() - .trim(); - } - }); - let chapters = []; - let chaptersRaw = body.match(/window.__DATA__ = [\s\S]*?window._SITE_COLOR_/gm); - chaptersRaw = (_d = (_c = (_b = (_a = chaptersRaw === null || chaptersRaw === void 0 ? void 0 : chaptersRaw[0]) === null || _a === void 0 ? void 0 : _a.replace("window.__DATA__ = ", "")) === null || _b === void 0 ? void 0 : _b.replace("window._SITE_COLOR_", "")) === null || _c === void 0 ? void 0 : _c.trim()) === null || _d === void 0 ? void 0 : _d.slice(0, -1); - let chaptersJson = JSON.parse(chaptersRaw); - ui = (_e = chaptersJson === null || chaptersJson === void 0 ? void 0 : chaptersJson.user) === null || _e === void 0 ? void 0 : _e.id; - (_g = (_f = chaptersJson.chapters) === null || _f === void 0 ? void 0 : _f.list) === null || _g === void 0 ? void 0 : _g.forEach((chapter) => { - var _a; - return chapters.push({ - name: (_a = `Том ${chapter.chapter_volume} Глава ${chapter.chapter_number} ${chapter.chapter_name}`) === null || _a === void 0 ? void 0 : _a.trim(), - releaseTime: (0, dayjs_1.default)(chapter.chapter_created_at).format("LLL"), - url: `${exports.site}/${chaptersJson.manga.slug}/v${chapter.chapter_volume}/c${chapter.chapter_number}?bid=` + - ((chapter === null || chapter === void 0 ? void 0 : chapter.branch_id) || ""), - }); - }); - novel.chapters = chapters.reverse(); - return novel; - }); -}; -exports.parseNovelAndChapters = parseNovelAndChapters; -const parseChapter = function (chapterUrl) { - return __awaiter(this, void 0, void 0, function* () { - const result = yield (0, fetch_1.fetchApi)(chapterUrl + (ui ? `&ui=${ui}` : "")); - const body = yield result.text(); - const loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio(".reader-container img").each(function () { - const url = loadedCheerio(this).attr("data-src") || loadedCheerio(this).attr("src"); - if (!(url === null || url === void 0 ? void 0 : url.startsWith("http"))) { - loadedCheerio(this).attr("src", exports.site + url); - } - else { - loadedCheerio(this).attr("src", url); - } - loadedCheerio(this).removeAttr("data-src"); - }); - const chapterText = loadedCheerio(".reader-container").html(); - return chapterText; - }); -}; -exports.parseChapter = parseChapter; -const searchNovels = function (searchTerm) { - return __awaiter(this, void 0, void 0, function* () { - const result = yield (0, fetch_1.fetchApi)(`${exports.site}/search?q=${searchTerm}&type=manga`); - const body = (yield result.json()); - let novels = []; - body.forEach((novel) => novels.push({ - name: (novel === null || novel === void 0 ? void 0 : novel.rus_name) || novel.name, - cover: novel === null || novel === void 0 ? void 0 : novel.coverImage, - url: (novel === null || novel === void 0 ? void 0 : novel.href) || exports.site + "/" + novel.slug, - })); - return novels; - }); -}; -exports.searchNovels = searchNovels; -exports.fetchImage = fetch_1.fetchFile; -exports.filters = [ - { - key: "sort", - label: "Сортировка", - values: [ - { label: "Рейтинг", value: "rate" }, - { label: "Имя", value: "name" }, - { label: "Просмотры", value: "views" }, - { label: "Дате добавления", value: "created_at" }, - { label: "Дате обновления", value: "last_chapter_at" }, - { label: "Количество глав", value: "chap_count" }, - ], - inputType: filterInputs_1.FilterInputs.Picker, - }, - { - key: "order", - label: "Порядок", - values: [ - { label: "По убыванию", value: "desc" }, - { label: "По возрастанию", value: "asc" }, - ], - inputType: filterInputs_1.FilterInputs.Picker, - }, - { - key: "type", - label: "Тип", - values: [ - { label: "Авторский", value: "14" }, - { label: "Английский", value: "13" }, - { label: "Китай", value: "12" }, - { label: "Корея", value: "11" }, - { label: "Фанфик", value: "15" }, - { label: "Япония", value: "10" }, - ], - inputType: filterInputs_1.FilterInputs.Checkbox, - }, - { - key: "format", - label: "Формат выпуска", - values: [ - { label: "4-кома (Ёнкома)", value: "1" }, - { label: "В цвете", value: "4" }, - { label: "Веб", value: "6" }, - { label: "Вебтун", value: "7" }, - { label: "Додзинси", value: "3" }, - { label: "Сборник", value: "2" }, - { label: "Сингл", value: "5" }, - ], - inputType: filterInputs_1.FilterInputs.Checkbox, - }, - { - key: "status", - label: "Статус перевода", - values: [ - { label: "Продолжается", value: "1" }, - { label: "Завершен", value: "2" }, - { label: "Заморожен", value: "3" }, - { label: "Заброшен", value: "4" }, - ], - inputType: filterInputs_1.FilterInputs.Checkbox, - }, - { - key: "statuss", - label: "Статус тайтла", - values: [ - { label: "Онгоинг", value: "1" }, - { label: "Завершён", value: "2" }, - { label: "Анонс", value: "3" }, - { label: "Приостановлен", value: "4" }, - { label: "Выпуск прекращён", value: "5" }, - ], - inputType: filterInputs_1.FilterInputs.Checkbox, - }, - { - key: "genres", - label: "Жанры", - values: [ - { label: "Арт", value: "32" }, - { label: "Безумие", value: "91" }, - { label: "Боевик", value: "34" }, - { label: "Боевые искусства", value: "35" }, - { label: "Вампиры", value: "36" }, - { label: "Военное", value: "89" }, - { label: "Гарем", value: "37" }, - { label: "Гендерная интрига", value: "38" }, - { label: "Героическое фэнтези", value: "39" }, - { label: "Демоны", value: "81" }, - { label: "Детектив", value: "40" }, - { label: "Детское", value: "88" }, - { label: "Дзёсэй", value: "41" }, - { label: "Драма", value: "43" }, - { label: "Игра", value: "44" }, - { label: "Исекай", value: "79" }, - { label: "История", value: "45" }, - { label: "Киберпанк", value: "46" }, - { label: "Кодомо", value: "76" }, - { label: "Комедия", value: "47" }, - { label: "Космос", value: "83" }, - { label: "Магия", value: "85" }, - { label: "Махо-сёдзё", value: "48" }, - { label: "Машины", value: "90" }, - { label: "Меха", value: "49" }, - { label: "Мистика", value: "50" }, - { label: "Музыка", value: "80" }, - { label: "Научная фантастика", value: "51" }, - { label: "Омегаверс", value: "77" }, - { label: "Пародия", value: "86" }, - { label: "Повседневность", value: "52" }, - { label: "Полиция", value: "82" }, - { label: "Постапокалиптика", value: "53" }, - { label: "Приключения", value: "54" }, - { label: "Психология", value: "55" }, - { label: "Романтика", value: "56" }, - { label: "Самурайский боевик", value: "57" }, - { label: "Сверхъестественное", value: "58" }, - { label: "Сёдзё", value: "59" }, - { label: "Сёдзё-ай", value: "60" }, - { label: "Сёнэн", value: "61" }, - { label: "Сёнэн-ай", value: "62" }, - { label: "Спорт", value: "63" }, - { label: "Супер сила", value: "87" }, - { label: "Сэйнэн", value: "64" }, - { label: "Трагедия", value: "65" }, - { label: "Триллер", value: "66" }, - { label: "Ужасы", value: "67" }, - { label: "Фантастика", value: "68" }, - { label: "Фэнтези", value: "69" }, - { label: "Школа", value: "70" }, - { label: "Эротика", value: "71" }, - { label: "Этти", value: "72" }, - { label: "Юри", value: "73" }, - { label: "Яой", value: "74" }, - ], - inputType: filterInputs_1.FilterInputs.Checkbox, - }, - { - key: "tags", - label: "Теги", - values: [ - { label: "Авантюристы", value: "328" }, - { label: "Антигерой", value: "176" }, - { label: "Бессмертные", value: "333" }, - { label: "Боги", value: "218" }, - { label: "Борьба за власть", value: "309" }, - { label: "Брат и сестра", value: "360" }, - { label: "Ведьма", value: "339" }, - { label: "Видеоигры", value: "204" }, - { label: "Виртуальная реальность", value: "214" }, - { label: "Владыка демонов", value: "349" }, - { label: "Военные", value: "198" }, - { label: "Воспоминания из другого мира", value: "310" }, - { label: "Выживание", value: "212" }, - { label: "ГГ женщина", value: "294" }, - { label: "ГГ имба", value: "292" }, - { label: "ГГ мужчина", value: "295" }, - { label: "ГГ не ояш", value: "325" }, - { label: "ГГ не человек", value: "331" }, - { label: "ГГ ояш", value: "326" }, - { label: "Главный герой бог", value: "324" }, - { label: "Глупый ГГ", value: "298" }, - { label: "Горничные", value: "171" }, - { label: "Гуро", value: "306" }, - { label: "Гяру", value: "197" }, - { label: "Демоны", value: "157" }, - { label: "Драконы", value: "313" }, - { label: "Древний мир", value: "317" }, - { label: "Зверолюди", value: "163" }, - { label: "Зомби", value: "155" }, - { label: "Исторические фигуры", value: "323" }, - { label: "Кулинария", value: "158" }, - { label: "Культивация", value: "161" }, - { label: "ЛГБТ", value: "344" }, - { label: "ЛитРПГ", value: "319" }, - { label: "Лоли", value: "206" }, - { label: "Магия", value: "170" }, - { label: "Машинный перевод", value: "345" }, - { label: "Медицина", value: "159" }, - { label: "Межгалактическая война", value: "330" }, - { label: "Монстр Девушки", value: "207" }, - { label: "Монстры", value: "208" }, - { label: "Мрачный мир", value: "316" }, - { label: "Музыка", value: "358" }, - { label: "Музыка", value: "209" }, - { label: "Ниндзя", value: "199" }, - { label: "Обратный Гарем", value: "210" }, - { label: "Офисные Работники", value: "200" }, - { label: "Пираты", value: "341" }, - { label: "Подземелья", value: "314" }, - { label: "Политика", value: "311" }, - { label: "Полиция", value: "201" }, - { label: "Преступники / Криминал", value: "205" }, - { label: "Призраки / Духи", value: "196" }, - { label: "Призыватели", value: "329" }, - { label: "Прыжки между мирами", value: "321" }, - { label: "Путешествие в другой мир", value: "318" }, - { label: "Путешествие во времени", value: "213" }, - { label: "Рабы", value: "355" }, - { label: "Ранги силы", value: "312" }, - { label: "Реинкарнация", value: "154" }, - { label: "Самураи", value: "202" }, - { label: "Скрытие личности", value: "315" }, - { label: "Средневековье", value: "174" }, - { label: "Традиционные игры", value: "203" }, - { label: "Умный ГГ", value: "303" }, - { label: "Характерный рост", value: "332" }, - { label: "Хикикомори", value: "167" }, - { label: "Эволюция", value: "322" }, - { label: "Элементы РПГ", value: "327" }, - { label: "Эльфы", value: "217" }, - { label: "Якудза", value: "165" }, - ], - inputType: filterInputs_1.FilterInputs.Checkbox, - }, -]; diff --git a/js/plugins/russian/ranoberf.js b/js/plugins/russian/ranoberf.js deleted file mode 100644 index 1a0fc6a..0000000 --- a/js/plugins/russian/ranoberf.js +++ /dev/null @@ -1,143 +0,0 @@ -"use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.filters = exports.fetchImage = exports.searchNovels = exports.parseChapter = exports.parseNovelAndChapters = exports.popularNovels = exports.icon = exports.version = exports.site = exports.name = exports.id = void 0; -const filterInputs_1 = require("@libs/filterInputs"); -const defaultCover_1 = require("@libs/defaultCover"); -const fetch_1 = require("@libs/fetch"); -const novelStatus_1 = require("@libs/novelStatus"); -const cheerio_1 = require("cheerio"); -const dayjs_1 = __importDefault(require("dayjs")); -exports.id = "RNRF"; -exports.name = "РанобэРФ"; -exports.site = "https://ранобэ.рф"; -exports.version = "1.0.0"; -exports.icon = "src/ru/ranoberf/icon.png"; -const popularNovels = function (page, { showLatestNovels, filters }) { - var _a, _b, _c; - return __awaiter(this, void 0, void 0, function* () { - let url = exports.site + "/books?order="; - url += showLatestNovels ? "lastPublishedChapter" : (filters === null || filters === void 0 ? void 0 : filters.sort) || "popular"; - url += "&page=" + page; - const result = yield (0, fetch_1.fetchApi)(url); - const body = yield result.text(); - const loadedCheerio = (0, cheerio_1.load)(body); - const jsonRaw = loadedCheerio("#__NEXT_DATA__").html(); - let json = JSON.parse(jsonRaw || '{}'); - let novels = []; - (_c = (_b = (_a = json.props.pageProps) === null || _a === void 0 ? void 0 : _a.totalData) === null || _b === void 0 ? void 0 : _b.items) === null || _c === void 0 ? void 0 : _c.forEach((novel) => { - var _a; - return novels.push({ - name: novel.title, - cover: ((_a = novel === null || novel === void 0 ? void 0 : novel.verticalImage) === null || _a === void 0 ? void 0 : _a.url) - ? exports.site + novel.verticalImage.url - : defaultCover_1.defaultCover, - url: exports.site + "/" + novel.slug, - }); - }); - return novels; - }); -}; -exports.popularNovels = popularNovels; -const parseNovelAndChapters = function (novelUrl) { - var _a, _b; - return __awaiter(this, void 0, void 0, function* () { - const result = yield (0, fetch_1.fetchApi)(novelUrl); - const body = yield result.text(); - const loadedCheerio = (0, cheerio_1.load)(body); - const jsonRaw = loadedCheerio("#__NEXT_DATA__").html(); - const book = JSON.parse(jsonRaw || '{}').props.pageProps.book; - let novel = { - url: novelUrl, - name: book === null || book === void 0 ? void 0 : book.title, - cover: ((_a = book === null || book === void 0 ? void 0 : book.verticalImage) === null || _a === void 0 ? void 0 : _a.url) - ? exports.site + book.verticalImage.url - : defaultCover_1.defaultCover, - summary: book === null || book === void 0 ? void 0 : book.description, - author: (book === null || book === void 0 ? void 0 : book.author) || "", - genres: book === null || book === void 0 ? void 0 : book.genres.map((item) => item.title).join(", "), - status: (book === null || book === void 0 ? void 0 : book.additionalInfo.includes("Активен")) - ? novelStatus_1.NovelStatus.Ongoing - : novelStatus_1.NovelStatus.Completed, - }; - let chapters = []; - (_b = book === null || book === void 0 ? void 0 : book.chapters) === null || _b === void 0 ? void 0 : _b.forEach((chapter) => { - if (!(chapter === null || chapter === void 0 ? void 0 : chapter.isDonate) || (chapter === null || chapter === void 0 ? void 0 : chapter.isUserPaid)) { - chapters.push({ - name: chapter.title, - releaseTime: (0, dayjs_1.default)(chapter.publishedAt).format("LLL"), - url: exports.site + chapter.url, - }); - } - }); - novel.chapters = chapters.reverse(); - return novel; - }); -}; -exports.parseNovelAndChapters = parseNovelAndChapters; -const parseChapter = function (chapterUrl) { - var _a, _b, _c; - return __awaiter(this, void 0, void 0, function* () { - const result = yield (0, fetch_1.fetchApi)(chapterUrl); - const body = yield result.text(); - let loadedCheerio = (0, cheerio_1.load)(body); - let jsonRaw = loadedCheerio("#__NEXT_DATA__").html(); - let json = JSON.parse(jsonRaw || '{}'); - loadedCheerio = (0, cheerio_1.load)(((_c = (_b = (_a = json.props.pageProps) === null || _a === void 0 ? void 0 : _a.chapter) === null || _b === void 0 ? void 0 : _b.content) === null || _c === void 0 ? void 0 : _c.text) || ""); - loadedCheerio("img").each(function () { - var _a; - if (!((_a = loadedCheerio(this).attr("src")) === null || _a === void 0 ? void 0 : _a.startsWith("http"))) { - const src = loadedCheerio(this).attr("src"); - loadedCheerio(this).attr("src", exports.site + src); - } - }); - const chapterText = loadedCheerio.html(); - return chapterText; - }); -}; -exports.parseChapter = parseChapter; -const searchNovels = function (searchTerm) { - return __awaiter(this, void 0, void 0, function* () { - const url = `${exports.site}/v3/books?filter[or][0][title][like]=${searchTerm}&filter[or][1][titleEn][like]=${searchTerm}&filter[or][2][fullTitle][like]=${searchTerm}&filter[status][]=active&filter[status][]=abandoned&filter[status][]=completed&expand=verticalImage`; - const result = yield (0, fetch_1.fetchApi)(url); - const body = (yield result.json()); - let novels = []; - body.items.forEach((novel) => { - var _a; - return novels.push({ - name: novel.title, - cover: ((_a = novel === null || novel === void 0 ? void 0 : novel.verticalImage) === null || _a === void 0 ? void 0 : _a.url) - ? exports.site + novel.verticalImage.url - : defaultCover_1.defaultCover, - url: exports.site + "/" + novel.slug, - }); - }); - return novels; - }); -}; -exports.searchNovels = searchNovels; -exports.fetchImage = fetch_1.fetchFile; -exports.filters = [ - { - key: "sort", - label: "Сортировка", - values: [ - { label: "Рейтинг", value: "popular" }, - { label: "Дате добавления", value: "new" }, - { label: "Дате обновления", value: "lastPublishedChapter" }, - { label: "Законченные", value: "completed" }, - ], - inputType: filterInputs_1.FilterInputs.Picker, - }, -]; diff --git a/js/plugins/russian/renovels.js b/js/plugins/russian/renovels.js deleted file mode 100644 index 792d4f4..0000000 --- a/js/plugins/russian/renovels.js +++ /dev/null @@ -1,941 +0,0 @@ -"use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.filters = exports.fetchImage = exports.searchNovels = exports.parseChapter = exports.parseNovelAndChapters = exports.popularNovels = exports.icon = exports.version = exports.site = exports.name = exports.id = void 0; -const filterInputs_1 = require("@libs/filterInputs"); -const fetch_1 = require("@libs/fetch"); -const novelStatus_1 = require("@libs/novelStatus"); -const dayjs_1 = __importDefault(require("dayjs")); -exports.id = "ReN"; -exports.name = "Renovels"; -exports.site = "https://renovels.org"; -exports.version = "1.0.0"; -exports.icon = "src/ru/renovels/icon.png"; -const popularNovels = function (page, { showLatestNovels, filters }) { - return __awaiter(this, void 0, void 0, function* () { - let url = exports.site + "/api/search/catalog/?count=30&ordering="; - url += (filters === null || filters === void 0 ? void 0 : filters.order) ? filters.order.replace("+", "") : "-"; - url += showLatestNovels ? "chapter_date" : (filters === null || filters === void 0 ? void 0 : filters.sort) || "rating"; - if ((filters === null || filters === void 0 ? void 0 : filters.genres) instanceof Array) { - url += filters.genres.map((i) => `&genres=${i}`).join(""); - } - if ((filters === null || filters === void 0 ? void 0 : filters.status) instanceof Array) { - url += filters === null || filters === void 0 ? void 0 : filters.status.map((i) => `&status=${i}`).join(""); - } - if ((filters === null || filters === void 0 ? void 0 : filters.types) instanceof Array) { - url += filters.types.map((i) => `&types=${i}`).join(""); - } - if ((filters === null || filters === void 0 ? void 0 : filters.categories) instanceof Array) { - url += filters.categories.map((i) => `&categories=${i}`).join(""); - } - if ((filters === null || filters === void 0 ? void 0 : filters.age_limit) instanceof Array) { - url += filters.age_limit.map((i) => `&age_limit=${i}`).join(""); - } - url += "&page=" + page; - const result = yield (0, fetch_1.fetchApi)(url); - let body = (yield result.json()); - let novels = []; - body.content.forEach((novel) => { - var _a, _b; - return novels.push({ - name: novel.main_name || novel.secondary_name, - cover: exports.site + (((_a = novel.img) === null || _a === void 0 ? void 0 : _a.high) || ((_b = novel.img) === null || _b === void 0 ? void 0 : _b.mid) || novel.img.low), - url: exports.site + "/novel/" + novel.dir, - }); - }); - return novels; - }); -}; -exports.popularNovels = popularNovels; -const parseNovelAndChapters = function (novelUrl) { - var _a, _b, _c, _d, _e, _f; - return __awaiter(this, void 0, void 0, function* () { - let novelID = novelUrl.split("/")[4]; - const result = yield (0, fetch_1.fetchApi)(exports.site + "/api/titles/" + novelID); - let body = (yield result.json()); - let novel = { - url: novelUrl, - name: body.content.main_name || body.content.secondary_name, - summary: body.content.description, - cover: exports.site + - (((_a = body.content.img) === null || _a === void 0 ? void 0 : _a.high) || - ((_b = body.content.img) === null || _b === void 0 ? void 0 : _b.mid) || - body.content.img.low), - status: body.content.status.name === "Продолжается" - ? novelStatus_1.NovelStatus.Ongoing - : novelStatus_1.NovelStatus.Completed, - }; - let tags = [(_c = body.content) === null || _c === void 0 ? void 0 : _c.genres, (_d = body.content) === null || _d === void 0 ? void 0 : _d.categories] - .flat() - .map((tags) => tags === null || tags === void 0 ? void 0 : tags.name) - .filter((tags) => tags); - if (tags.length > 0) { - novel.genres = tags.join(","); - } - let all = Math.floor(body.content.count_chapters / 100 + 1); - let branch_id = ((_f = (_e = body.content.branches) === null || _e === void 0 ? void 0 : _e[0]) === null || _f === void 0 ? void 0 : _f.id) || body.content.id; - let chapters = []; - for (let i = 0; i < all; i++) { - let chapterResult = yield (0, fetch_1.fetchApi)(exports.site + - "/api/titles/chapters/?branch_id=" + - branch_id + - "&count=100&page=" + - (i + 1)); - let volumes = (yield chapterResult.json()); - volumes.content.forEach((chapter) => { - var _a; - if (!chapter.is_paid || chapter.is_bought) { - chapters.push({ - name: (_a = `Том ${chapter.tome} Глава ${chapter.chapter} ${chapter.name}`) === null || _a === void 0 ? void 0 : _a.trim(), - releaseTime: (0, dayjs_1.default)(chapter.upload_date).format("LLL"), - url: `${exports.site}/novel/${novelID}/${chapter.id}/`, - }); - } - }); - } - novel.chapters = chapters.reverse(); - return novel; - }); -}; -exports.parseNovelAndChapters = parseNovelAndChapters; -const parseChapter = function (chapterUrl) { - return __awaiter(this, void 0, void 0, function* () { - let url = exports.site + "/api/titles/chapters/" + chapterUrl.split("/")[5]; - const result = yield (0, fetch_1.fetchApi)(url); - const body = (yield result.json()); - return body.content.content; - }); -}; -exports.parseChapter = parseChapter; -const searchNovels = function (searchTerm) { - return __awaiter(this, void 0, void 0, function* () { - const url = `${exports.site}/api/search/?query=${searchTerm}&count=100&field=titles`; - const result = yield (0, fetch_1.fetchApi)(url); - let body = (yield result.json()); - let novels = []; - body.content.forEach((novel) => { - var _a, _b; - return novels.push({ - name: novel.main_name || novel.secondary_name, - cover: exports.site + (((_a = novel.img) === null || _a === void 0 ? void 0 : _a.high) || ((_b = novel.img) === null || _b === void 0 ? void 0 : _b.mid) || novel.img.low), - url: exports.site + "/novel/" + novel.dir, - }); - }); - return novels; - }); -}; -exports.searchNovels = searchNovels; -exports.fetchImage = fetch_1.fetchFile; -exports.filters = [ - { - key: "sort", - label: "Сортировка", - values: [ - { label: "Рейтинг", value: "rating" }, - { label: "Просмотры", value: "views" }, - { label: "Лайкам", value: "votes" }, - { label: "Дате добавления", value: "id" }, - { label: "Дате обновления", value: "chapter_date" }, - { label: "Количество глав", value: "count_chapters" }, - ], - inputType: filterInputs_1.FilterInputs.Picker, - }, - { - key: "order", - label: "Порядок", - values: [ - { label: "По убыванию", value: "-" }, - { label: "По возрастанию", value: "+" }, - ], - inputType: filterInputs_1.FilterInputs.Picker, - }, - { - key: "genres", - label: "Жанры:", - values: [ - { label: "Боевик", value: "112" }, - { label: "Война", value: "123" }, - { label: "Детектив", value: "114" }, - { label: "Драма", value: "125" }, - { label: "Историческая проза", value: "115" }, - { label: "ЛитРПГ", value: "109" }, - { label: "Любовные романы", value: "116" }, - { label: "Мистика", value: "103" }, - { label: "Научная фантастика", value: "121" }, - { label: "Повседневность", value: "128" }, - { label: "Подростковая проза", value: "113" }, - { label: "Политический роман", value: "119" }, - { label: "Попаданцы", value: "108" }, - { label: "Поэзия", value: "105" }, - { label: "Разное", value: "111" }, - { label: "РеалРПГ", value: "117" }, - { label: "Романтика", value: "126" }, - { label: "Современная проза", value: "102" }, - { label: "Современная фантастика", value: "127" }, - { label: "Спорт", value: "122" }, - { label: "Трагедия", value: "129" }, - { label: "Триллер", value: "110" }, - { label: "Триллер и саспенс", value: "124" }, - { label: "Ужасы", value: "106" }, - { label: "Фантастика", value: "101" }, - { label: "Фанфик", value: "107" }, - { label: "Фьюжн роман", value: "120" }, - { label: "Фэнтези", value: "100" }, - { label: "Эротика", value: "118" }, - { label: "Юмор", value: "104" }, - ], - inputType: filterInputs_1.FilterInputs.Checkbox, - }, - { - key: "categories", - label: "Тэги:", - values: [ - { label: "[Награжденная работа]", value: "648" }, - { label: "18+", value: "423" }, - { label: "Абьюзеры", value: "663" }, - { label: "Авантюристы", value: "436" }, - { label: "Автоматоны", value: "593" }, - { label: "Агрессивные персонажи", value: "502" }, - { label: "Ад", value: "569" }, - { label: "Адаптация в радиопостановку", value: "581" }, - { label: "Академия", value: "153" }, - { label: "Актеры озвучки", value: "627" }, - { label: "Активный главный герой", value: "251" }, - { label: "Алхимия", value: "233" }, - { label: "Альтернативная история", value: "147" }, - { label: "Альтернативный мир", value: "156" }, - { label: "Амнезия/Потеря памяти", value: "344" }, - { label: "Анабиоз", value: "685" }, - { label: "Ангелы", value: "183" }, - { label: "Андрогинные персонажи", value: "321" }, - { label: "Андроиды", value: "203" }, - { label: "Анти-магия", value: "533" }, - { label: "Антигерой", value: "432" }, - { label: "Антикварный магазин", value: "623" }, - { label: "Антисоциальный главный герой", value: "613" }, - { label: "Антиутопия", value: "142" }, - { label: "Апатичный протагонист", value: "157" }, - { label: "Апокалипсис", value: "402" }, - { label: "Аранжированный брак", value: "375" }, - { label: "Армия", value: "639" }, - { label: "Артефакты", value: "234" }, - { label: "Артисты", value: "523" }, - { label: "Банды", value: "630" }, - { label: "БДСМ", value: "699" }, - { label: "Бедный главный герой", value: "398" }, - { label: "Безжалостный главный герой", value: "261" }, - { label: "Беззаботный главный герой", value: "438" }, - { label: "Безусловная любовь", value: "679" }, - { label: "Беременность", value: "250" }, - { label: "Бесполый главный герой", value: "325" }, - { label: "Бессмертные", value: "368" }, - { label: "Бесстрашный протагонист", value: "656" }, - { label: "Бесстыдный главный герой", value: "352" }, - { label: "Бесчестный главный герой", value: "716" }, - { label: "Библиотека", value: "428" }, - { label: "Бизнес-литература", value: "121" }, - { label: "Бизнесмен", value: "769" }, - { label: "Биочип", value: "238" }, - { label: "Бисексуальный главный герой", value: "773" }, - { label: "Близнецы", value: "263" }, - { label: "Боги", value: "317" }, - { label: "Богини", value: "439" }, - { label: "Боевая академия", value: "450" }, - { label: "Боевая фантастика", value: "149" }, - { label: "Боевое фэнтези", value: "104" }, - { label: "Боевые духи", value: "433" }, - { label: "Боевые соревнования", value: "493" }, - { label: "Божественная защита", value: "421" }, - { label: "Божественные силы", value: "327" }, - { label: "Борьба за власть", value: "599" }, - { label: "Брак", value: "446" }, - { label: "Брак по расчету", value: "188" }, - { label: "Братский комплекс", value: "159" }, - { label: "Братство", value: "487" }, - { label: "Братья и сестры", value: "577" }, - { label: "Буддизм", value: "745" }, - { label: "Быстрая культивация", value: "366" }, - { label: "Быстрообучаемый", value: "324" }, - { label: "Валькирии", value: "692" }, - { label: "Вампиры", value: "360" }, - { label: "Ваншот", value: "702" }, - { label: "Ведьмы", value: "281" }, - { label: "Вежливый главный герой", value: "379" }, - { label: "Верные подчиненные", value: "328" }, - { label: "Взрослый главный герой", value: "295" }, - { label: "Видит то, чего не видят другие", value: "671" }, - { label: "Виртуальная реальность", value: "401" }, - { label: "Владелец магазина", value: "681" }, - { label: "Внезапная сила", value: "455" }, - { label: "Внезапное богатство", value: "765" }, - { label: "Внешний вид отличается от факт", value: "419" }, - { label: "Военные Летописи", value: "743" }, - { label: "Возвращение из другого мира", value: "696" }, - { label: "Войны", value: "181" }, - { label: "Вокалоид", value: "701" }, - { label: "Волшебники/Волшебницы", value: "539" }, - { label: "Волшебные звери", value: "308" }, - { label: "Воображаемый друг", value: "651" }, - { label: "Воры", value: "414" }, - { label: "Воскрешение", value: "199" }, - { label: "Враги становятся возлюбленными", value: "498" }, - { label: "Враги становятся союзниками", value: "562" }, - { label: "Врата в другой мир", value: "609" }, - { label: "Врачи", value: "376" }, - { label: "Временной парадокс", value: "275" }, - { label: "Всемогущий главный герой", value: "169" }, - { label: "Вторжение на землю", value: "198" }, - { label: "Второй шанс", value: "231" }, - { label: "Вуайеризм", value: "790" }, - { label: "Выживание", value: "380" }, - { label: "Высокомерные персонажи", value: "361" }, - { label: "Гадание", value: "595" }, - { label: "Гарем рабов", value: "777" }, - { label: "Гг - женщина", value: "186" }, - { label: "Гг - мужчина", value: "166" }, - { label: "Гг силен с самого начала", value: "171" }, - { label: "Геймеры", value: "392" }, - { label: "Генералы", value: "326" }, - { label: "Генетические модификации", value: "657" }, - { label: "Гениальный главный герой", value: "617" }, - { label: "Герои", value: "285" }, - { label: "Героиня — сорванец", value: "583" }, - { label: "Героическая фантастика", value: "140" }, - { label: "Героическое фэнтези", value: "107" }, - { label: "Герой влюбляется первым", value: "187" }, - { label: "Гетерохромия", value: "570" }, - { label: "Гильдии", value: "411" }, - { label: "Гипнотизм", value: "755" }, - { label: "Главный герой — бог", value: "547" }, - { label: "Главный герой — гуманоид", value: "636" }, - { label: "Главный герой — наполовину чел", value: "445" }, - { label: "Главный герой — отец", value: "792" }, - { label: "Главный герой — раб", value: "780" }, - { label: "Главный герой — ребенок", value: "488" }, - { label: "Главный герой — рубака", value: "476" }, - { label: "Главный герой влюбляется первы", value: "683" }, - { label: "Главный герой играет роль", value: "472" }, - { label: "Главный герой носит очки", value: "672" }, - { label: "Главный герой пацифист", value: "698" }, - { label: "Гладиаторы", value: "603" }, - { label: "Глуповатый главный герой", value: "385" }, - { label: "Гоблины", value: "586" }, - { label: "Големы", value: "620" }, - { label: "Гомункул", value: "789" }, - { label: "Горничные", value: "459" }, - { label: "Городское фэнтези", value: "105" }, - { label: "Госпиталь", value: "800" }, - { label: "Готовка", value: "302" }, - { label: "Гриндинг", value: "393" }, - { label: "Дао Компаньон", value: "462" }, - { label: "Даосизм", value: "760" }, - { label: "Дварфы", value: "323" }, - { label: "Двойная личность", value: "642" }, - { label: "Двойник", value: "601" }, - { label: "Дворецкий", value: "660" }, - { label: "Дворяне", value: "168" }, - { label: "Дворянство/Аристократия", value: "437" }, - { label: "Девушки-монстры", value: "669" }, - { label: "Демоническая техника культивац", value: "722" }, - { label: "Демоны", value: "152" }, - { label: "Денежный долг", value: "783" }, - { label: "Депрессия", value: "555" }, - { label: "Детектив", value: "116" }, - { label: "Детективы", value: "612" }, - { label: "Детская литература", value: "123" }, - { label: "Дискриминация", value: "162" }, - { label: "Добыча денег в приоритете", value: "396" }, - { label: "Документальная проза", value: "122" }, - { label: "Долгая разлука", value: "307" }, - { label: "Домашние дела", value: "290" }, - { label: "Домогательство", value: "470" }, - { label: "Драконы", value: "303" }, - { label: "Драконьи всадники", value: "607" }, - { label: "Древние времена", value: "221" }, - { label: "Древний Китай", value: "374" }, - { label: "Дружба", value: "217" }, - { label: "Друзья детства", value: "282" }, - { label: "Друзья становятся врагами", value: "567" }, - { label: "Друиды", value: "497" }, - { label: "Дух лисы", value: "784" }, - { label: "Духи/призраки", value: "172" }, - { label: "Духовный советник", value: "435" }, - { label: "Душевность", value: "633" }, - { label: "Души", value: "254" }, - { label: "Европейская атмосфера", value: "521" }, - { label: "Ёкаи", value: "575" }, - { label: "Есть аниме-адаптация", value: "154" }, - { label: "Есть видеоигра по мотивам", value: "552" }, - { label: "Есть манга", value: "155" }, - { label: "Есть манхва-адаптация", value: "517" }, - { label: "Есть маньхуа-адаптация", value: "388" }, - { label: "Есть сериал-адаптация", value: "492" }, - { label: "Есть фильм", value: "173" }, - { label: "Женища-наставник", value: "505" }, - { label: "Жесткая, двуличная личность", value: "346" }, - { label: "Жестокие персонажи", value: "503" }, - { label: "Жестокое обращение с ребенком", value: "654" }, - { label: "Жестокость", value: "245" }, - { label: "Животноводство", value: "754" }, - { label: "Животные черты", value: "528" }, - { label: "Жизнь в квартире", value: "606" }, - { label: "Жрицы", value: "615" }, - { label: "Заботливый главный герой", value: "288" }, - { label: "Забывчивый главный герой", value: "628" }, - { label: "Заговоры", value: "289" }, - { label: "Закалка тела", value: "362" }, - { label: "Законники", value: "756" }, - { label: "Замкнутый главный герой", value: "589" }, - { label: "Запечатанная сила", value: "430" }, - { label: "Застенчивые персонажи", value: "508" }, - { label: "Звери", value: "237" }, - { label: "Звери-компаньоны", value: "301" }, - { label: "Злой протагонист", value: "243" }, - { label: "Злые боги", value: "504" }, - { label: "Злые организации", value: "563" }, - { label: "Злые религии", value: "734" }, - { label: "Знаменитости", value: "473" }, - { label: "Знаменитый главный герой", value: "531" }, - { label: "Знания современного мира", value: "297" }, - { label: "Зомби", value: "409" }, - { label: "Игра на выживание", value: "274" }, - { label: "Игривый протагонист", value: "717" }, - { label: "Игровая система рейтинга", value: "391" }, - { label: "Игровые элементы", value: "266" }, - { label: "Игрушки (18+)", value: "676" }, - { label: "Из грязи в князи", value: "416" }, - { label: "Из женщины в мужчину", value: "709" }, - { label: "Из мужчины в женщину", value: "715" }, - { label: "Из полного в худого", value: "767" }, - { label: "Из слабого в сильного", value: "202" }, - { label: "Извращенный главный герой", value: "434" }, - { label: "Изгои", value: "534" }, - { label: "Изменение расы", value: "664" }, - { label: "Изменения внешнего вида", value: "300" }, - { label: "Изменения личности", value: "219" }, - { label: "Изнасилование", value: "229" }, - { label: "Изображения жестокости", value: "355" }, - { label: "ИИ", value: "235" }, - { label: "Империи", value: "748" }, - { label: "Инвалидность", value: "684" }, - { label: "Индустриализация", value: "292" }, - { label: "Инженер", value: "163" }, - { label: "Инцест", value: "525" }, - { label: "Искусственный интеллект", value: "236" }, - { label: "Исследования", value: "670" }, - { label: "Историческая проза", value: "119" }, - { label: "Исторические приключения", value: "120" }, - { label: "Исторический детектив", value: "117" }, - { label: "Исторический любовный роман", value: "138" }, - { label: "Историческое фэнтези", value: "110" }, - { label: "Каннибализм", value: "456" }, - { label: "Карточные игры", value: "682" }, - { label: "Киберпанк", value: "141" }, - { label: "Киберспорт", value: "686" }, - { label: "Кланы", value: "796" }, - { label: "Класс безработного", value: "735" }, - { label: "Клоны", value: "447" }, - { label: "Клубы", value: "216" }, - { label: "Книги", value: "427" }, - { label: "Книги навыков", value: "400" }, - { label: "Книжный червь", value: "519" }, - { label: "Коварство", value: "230" }, - { label: "Коллеги", value: "704" }, - { label: "Колледж/Университет", value: "726" }, - { label: "Кома", value: "776" }, - { label: "Командная работа", value: "496" }, - { label: "Комедийный оттенок", value: "582" }, - { label: "Комплекс неполноценности", value: "550" }, - { label: "Комплекс семейных отношений", value: "223" }, - { label: "Конкуренция", value: "746" }, - { label: "Контроль разума/сознания", value: "357" }, - { label: "Копейщик", value: "425" }, - { label: "Королевская битва", value: "797" }, - { label: "Королевская власть", value: "178" }, - { label: "Королевства", value: "259" }, - { label: "Короткий любовный роман", value: "136" }, - { label: "Коррупция", value: "457" }, - { label: "Космическая фантастика", value: "146" }, - { label: "Космические войны", value: "697" }, - { label: "Красивый герой", value: "226" }, - { label: "Крафт", value: "377" }, - { label: "Кризис личности", value: "640" }, - { label: "Кругосветное путешествие", value: "353" }, - { label: "Кудере", value: "506" }, - { label: "Кузены", value: "718" }, - { label: "Кузнец", value: "518" }, - { label: "Кукловоды", value: "501" }, - { label: "Куклы/марионетки", value: "624" }, - { label: "Культивация", value: "241" }, - { label: "Куннилингус", value: "667" }, - { label: "Легенды", value: "500" }, - { label: "Легкая жизнь", value: "644" }, - { label: "Ленивый главный герой", value: "621" }, - { label: "Лидерство", value: "494" }, - { label: "Лоли", value: "213" }, - { label: "Лотерея", value: "477" }, - { label: "Любовное фэнтези", value: "135" }, - { label: "Любовный треугольник", value: "218" }, - { label: "Любовь детства", value: "560" }, - { label: "Любовь с первого взгляда", value: "737" }, - { label: "Магические надписи", value: "453" }, - { label: "Магические печати", value: "369" }, - { label: "Магические технологии", value: "440" }, - { label: "Магия", value: "165" }, - { label: "Магия призыва", value: "418" }, - { label: "Мазохистские персонажи", value: "688" }, - { label: "Манипулятивные персонажи", value: "249" }, - { label: "Мания", value: "212" }, - { label: "Мастер на все руки", value: "466" }, - { label: "Мастурбация", value: "788" }, - { label: "Махо-сёдзё", value: "556" }, - { label: "Медицинские знания", value: "507" }, - { label: "Медленная романтическая линия", value: "232" }, - { label: "Медленное развитие на старте", value: "694" }, - { label: "Межпространственные путешестви", value: "404" }, - { label: "Менеджмент", value: "294" }, - { label: "Мертвый главный герой", value: "761" }, - { label: "Месть", value: "209" }, - { label: "Метаморфы", value: "335" }, - { label: "Меч и магия", value: "180" }, - { label: "Мечник", value: "647" }, - { label: "Мечты", value: "738" }, - { label: "Милая история", value: "725" }, - { label: "Милое дитя", value: "637" }, - { label: "Милый главный герой", value: "714" }, - { label: "Мировое дерево", value: "463" }, - { label: "Мистика", value: "151" }, - { label: "Мистический ореол вокруг семьи", value: "483" }, - { label: "Мифические звери", value: "491" }, - { label: "Мифология", value: "530" }, - { label: "Младшие братья", value: "785" }, - { label: "Младшие сестры", value: "527" }, - { label: "ММОРПГ (ЛитРПГ)", value: "395" }, - { label: "Множество перемещенных людей", value: "549" }, - { label: "Множество реальностей", value: "370" }, - { label: "Множество реинкарнированных лю", value: "330" }, - { label: "Модели", value: "678" }, - { label: "Молчаливый персонаж", value: "721" }, - { label: "Монстры", value: "192" }, - { label: "Мужская гей-пара", value: "706" }, - { label: "Мужчина-яндере", value: "267" }, - { label: "Музыка", value: "635" }, - { label: "Музыкальные группы", value: "634" }, - { label: "Мутации", value: "693" }, - { label: "Мутированные существа", value: "405" }, - { label: "Навык кражи", value: "662" }, - { label: "Навязчивая любовь", value: "206" }, - { label: "Наемники", value: "412" }, - { label: "Назойливый возлюбленный", value: "561" }, - { label: "Наивный главный герой", value: "189" }, - { label: "Наркотики", value: "689" }, - { label: "Нарциссический главный герой", value: "532" }, - { label: "Насилие сексуального характера", value: "774" }, - { label: "Наследование", value: "452" }, - { label: "Научная фантастика", value: "144" }, - { label: "Национализм", value: "406" }, - { label: "Не блещущий внешне главный гер", value: "415" }, - { label: "Не родные братья и сестры", value: "526" }, - { label: "Небеса", value: "568" }, - { label: "Небесное испытание", value: "367" }, - { label: "Негуманоидный главный герой", value: "659" }, - { label: "Недоверчивый главный герой", value: "546" }, - { label: "Недооцененный главный герой", value: "258" }, - { label: "Недоразумения", value: "309" }, - { label: "Неизлечимая болезнь", value: "196" }, - { label: "Некромант", value: "397" }, - { label: "Нелинейная история", value: "269" }, - { label: "Ненавистный главный герой", value: "548" }, - { label: "Ненадежный рассказчик", value: "277" }, - { label: "Нерезиденты", value: "772" }, - { label: "Нерешительный главный герой", value: "744" }, - { label: "Несерьезный главный герой", value: "384" }, - { label: "Несколько временных линий", value: "576" }, - { label: "Несколько гг", value: "268" }, - { label: "Несколько главных героев", value: "537" }, - { label: "Несколько идентичностей", value: "652" }, - { label: "Несколько личностей", value: "536" }, - { label: "Нетораре", value: "732" }, - { label: "Нетори", value: "514" }, - { label: "Неудачливый главный герой", value: "618" }, - { label: "Ниндзя", value: "441" }, - { label: "Новелла", value: "103" }, - { label: "Обещание из детства", value: "742" }, - { label: "Обманщик", value: "485" }, - { label: "Обмен телами", value: "214" }, - { label: "Обнаженка", value: "490" }, - { label: "Обольщение", value: "731" }, - { label: "Оборотни", value: "661" }, - { label: "Обратный гарем", value: "351" }, - { label: "Общество монстров", value: "329" }, - { label: "Обязательство", value: "602" }, - { label: "Огнестрельное оружие", value: "291" }, - { label: "Ограниченное время жизни", value: "194" }, - { label: "Одержимость", value: "512" }, - { label: "Одинокий главный герой", value: "394" }, - { label: "Одиночество", value: "306" }, - { label: "Одиночное проживание", value: "313" }, - { label: "Околосмертные переживания", value: "759" }, - { label: "Оммёдзи", value: "597" }, - { label: "Омоложение", value: "338" }, - { label: "Организованная преступность", value: "540" }, - { label: "Оргия", value: "775" }, - { label: "Орки", value: "331" }, - { label: "Освоение навыков", value: "336" }, - { label: "Основано на аниме", value: "605" }, - { label: "Основано на видео игре", value: "720" }, - { label: "Основано на визуальной новелле", value: "793" }, - { label: "Основано на песне", value: "700" }, - { label: "Основано на фильме", value: "604" }, - { label: "Осторожный главный герой", value: "240" }, - { label: "Отаку", value: "571" }, - { label: "Открытый космос", value: "264" }, - { label: "Отношения в сети", value: "727" }, - { label: "Отношения между людьми и нелюд", value: "311" }, - { label: "Отношения на расстоянии", value: "791" }, - { label: "Отношения Сенпай-Коухай", value: "572" }, - { label: "Отношения ученика и учителя", value: "515" }, - { label: "Отношения учитель-ученик", value: "429" }, - { label: "Отношения хозяин-слуга", value: "312" }, - { label: "Отомэ игра", value: "733" }, - { label: "Отсутствие здравого смысла", value: "645" }, - { label: "Отсутствие родителей", value: "625" }, - { label: "Офисный роман", value: "707" }, - { label: "Официанты", value: "703" }, - { label: "Охотники", value: "378" }, - { label: "Очаровательный главный герой", value: "687" }, - { label: "Падшее дворянство", value: "655" }, - { label: "Падшие ангелы", value: "565" }, - { label: "Пайзури", value: "665" }, - { label: "Паразиты", value: "591" }, - { label: "Параллельные миры", value: "207" }, - { label: "Парк", value: "265" }, - { label: "Парк развлечений", value: "632" }, - { label: "Пародия", value: "407" }, - { label: "Певцы/Певицы", value: "739" }, - { label: "Первая любовь", value: "729" }, - { label: "Первоисточник новеллы — манга", value: "611" }, - { label: "Первый раз", value: "787" }, - { label: "Перемещение в игровой мир", value: "588" }, - { label: "Перемещение в иной мир", value: "750" }, - { label: "Перерождение в ином мире", value: "751" }, - { label: "Переселение души/трансмиграция", value: "257" }, - { label: "Персонаж использует щит", value: "666" }, - { label: "Петля времени", value: "200" }, - { label: "Пираты", value: "771" }, - { label: "Писатели", value: "482" }, - { label: "Питомцы", value: "349" }, - { label: "Племенное общество", value: "381" }, - { label: "Повелитель демонов", value: "283" }, - { label: "Подземелья", value: "322" }, - { label: "Подростковая проза", value: "114" }, - { label: "Пожелания", value: "278" }, - { label: "Познание Дао", value: "443" }, - { label: "Покинутое дитя", value: "590" }, - { label: "Полигамия", value: "386" }, - { label: "Политика", value: "170" }, - { label: "Политический роман", value: "133" }, - { label: "Полиция", value: "764" }, - { label: "Полулюди", value: "420" }, - { label: "Популярный любовный интерес", value: "342" }, - { label: "Постапокалипсис", value: "145" }, - { label: "Постапокалиптика", value: "184" }, - { label: "Потерянные цивилизации", value: "749" }, - { label: "Похищения людей", value: "723" }, - { label: "Поэзия", value: "111" }, - { label: "Правонарушители", value: "713" }, - { label: "Прагматичный главный герой", value: "592" }, - { label: "Преданный любовный интерес", value: "225" }, - { label: "Предательство", value: "222" }, - { label: "Предвидение", value: "177" }, - { label: "Прекрасная героиня", value: "158" }, - { label: "Преступники", value: "736" }, - { label: "Преступность", value: "204" }, - { label: "Призванный герой", value: "262" }, - { label: "Призраки", value: "176" }, - { label: "Принуждение к отношениям", value: "643" }, - { label: "Принцессы", value: "795" }, - { label: "Притворная пара", value: "641" }, - { label: "Причудливые персонажи", value: "387" }, - { label: "Пришельцы/инопланетяне", value: "197" }, - { label: "Программист", value: "691" }, - { label: "Проклятия", value: "174" }, - { label: "Промывание мозгов", value: "578" }, - { label: "Пропуск времени", value: "256" }, - { label: "Пророчества", value: "499" }, - { label: "Проститутки", value: "786" }, - { label: "Прошлое играет большую роль", value: "320" }, - { label: "Прыжки между мирами", value: "741" }, - { label: "Психические силы", value: "359" }, - { label: "Психопаты", value: "270" }, - { label: "Публицистика", value: "124" }, - { label: "Путешествие во времени", value: "201" }, - { label: "Пытка", value: "280" }, - { label: "Рабы", value: "778" }, - { label: "Развитие личности", value: "125" }, - { label: "Развод", value: "758" }, - { label: "Разумные предметы", value: "286" }, - { label: "Расизм", value: "408" }, - { label: "Рассказ", value: "185" }, - { label: "Расторжения помолвки", value: "343" }, - { label: "Расы зооморфов", value: "315" }, - { label: "Реализм", value: "246" }, - { label: "Ревность", value: "730" }, - { label: "Редакторы", value: "705" }, - { label: "Реинкарнация", value: "372" }, - { label: "Реинкарнация в монстра", value: "310" }, - { label: "Реинкарнация в объект", value: "711" }, - { label: "Религии", value: "616" }, - { label: "Репортеры", value: "781" }, - { label: "Ресторан", value: "680" }, - { label: "Решительный главный герой", value: "242" }, - { label: "Робкий главный герой", value: "763" }, - { label: "Родитель одиночка", value: "708" }, - { label: "Родительский комплекс", value: "587" }, - { label: "Родословная", value: "239" }, - { label: "Романтическая эротика", value: "132" }, - { label: "Романтический подсюжет", value: "271" }, - { label: "Рост персонажа", value: "215" }, - { label: "Рыцари", value: "260" }, - { label: "Садистские персонажи", value: "674" }, - { label: "Самоотверженный главный герой", value: "747" }, - { label: "Самурай", value: "677" }, - { label: "Сборник коротких историй", value: "520" }, - { label: "Связанные сюжетные линии", value: "535" }, - { label: "Святые", value: "752" }, - { label: "Священники", value: "413" }, - { label: "Сдержанный главный герой", value: "762" }, - { label: "Секретные организации", value: "417" }, - { label: "Секреты", value: "626" }, - { label: "Секс рабы", value: "779" }, - { label: "Семейный конфликт", value: "757" }, - { label: "Семь добродетелей", value: "334" }, - { label: "Семь смертных грехов", value: "253" }, - { label: "Семья", value: "347" }, - { label: "Сёнэн-ай подсюжет", value: "690" }, - { label: "Серийные убийцы", value: "557" }, - { label: "Сестринский комплекс", value: "558" }, - { label: "Сила духа", value: "373" }, - { label: "Сила, требующая платы за польз", value: "579" }, - { label: "Сильная пара", value: "228" }, - { label: "Сильный в сильнейшего", value: "442" }, - { label: "Сильный любовный интерес", value: "273" }, - { label: "Синдром восьмиклассника", value: "211" }, - { label: "Сироты", value: "319" }, - { label: "Система уровней", value: "305" }, - { label: "Системный администратор", value: "538" }, - { label: "Сказка", value: "126" }, - { label: "Скрытие истинной личности", value: "451" }, - { label: "Скрытие истинных способностей", value: "348" }, - { label: "Скрытный главный герой", value: "252" }, - { label: "Скрытые способности", value: "247" }, - { label: "Скульпторы", value: "448" }, - { label: "Слабо выраженная романтическая", value: "318" }, - { label: "Слабый главный герой", value: "298" }, - { label: "Слепой главный герой", value: "794" }, - { label: "Слуги", value: "333" }, - { label: "Слэш", value: "131" }, - { label: "Смерть", value: "175" }, - { label: "Смерть близких", value: "444" }, - { label: "Собственнические персонажи", value: "227" }, - { label: "Современная проза", value: "150" }, - { label: "Современность", value: "167" }, - { label: "Современный любовный роман", value: "137" }, - { label: "Сожительство", value: "544" }, - { label: "Создание армии", value: "287" }, - { label: "Создание артефактов", value: "382" }, - { label: "Создание клана", value: "513" }, - { label: "Создание королевства", value: "293" }, - { label: "Создание навыков", value: "337" }, - { label: "Создание секты", value: "469" }, - { label: "Солдаты/военные", value: "193" }, - { label: "Сон", value: "622" }, - { label: "Состоятельные персонажи", value: "190" }, - { label: "Социальная иерархия по силе", value: "255" }, - { label: "Социальная фантастика", value: "148" }, - { label: "Социальные изгои", value: "542" }, - { label: "Спасение мира", value: "638" }, - { label: "Специальные способности", value: "179" }, - { label: "Спокойный главный герой", value: "160" }, - { label: "Справедливый главный герой", value: "719" }, - { label: "Средневековье", value: "296" }, - { label: "Ссорящаяся пара", value: "383" }, - { label: "Сталкеры", value: "710" }, - { label: "Старение", value: "299" }, - { label: "Стимпанк", value: "139" }, - { label: "Стоические персонажи", value: "509" }, - { label: "Стокгольмский синдром", value: "675" }, - { label: "Стратег", value: "495" }, - { label: "Стратегические битвы", value: "272" }, - { label: "Стратегия", value: "798" }, - { label: "Стрелки", value: "522" }, - { label: "Стрельба из лука", value: "461" }, - { label: "Студенческий совет", value: "551" }, - { label: "Судьба", value: "364" }, - { label: "Суккубы", value: "545" }, - { label: "Супер герои", value: "799" }, - { label: "Суровая подготовка", value: "356" }, - { label: "Таинственная болезнь", value: "195" }, - { label: "Таинственное прошлое", value: "358" }, - { label: "Тайная личность", value: "399" }, - { label: "Тайные отношения", value: "768" }, - { label: "Танцоры", value: "782" }, - { label: "Телохранители", value: "516" }, - { label: "Темное фэнтези", value: "106" }, - { label: "Тентакли", value: "712" }, - { label: "Террористы", value: "574" }, - { label: "Технологический разрыв", value: "658" }, - { label: "Тихие персонажи", value: "600" }, - { label: "Толстый главный герой", value: "389" }, - { label: "Торговцы", value: "489" }, - { label: "Травля/буллинг", value: "210" }, - { label: "Травник", value: "724" }, - { label: "Трагическое прошлое", value: "276" }, - { label: "Трансплантация воспоминаний", value: "449" }, - { label: "Триллер", value: "134" }, - { label: "Трудолюбивый главный герой", value: "164" }, - { label: "Тюрьма", value: "541" }, - { label: "Убийства", value: "205" }, - { label: "Убийцы", value: "345" }, - { label: "Убийцы драконов", value: "646" }, - { label: "Уверенный главный герой", value: "363" }, - { label: "Удачливый главный герой", value: "478" }, - { label: "Ужасы", value: "112" }, - { label: "Укротитель монстров", value: "422" }, - { label: "Умения из прошлой жизни", value: "371" }, - { label: "Умная пара", value: "554" }, - { label: "Умный главный герой", value: "161" }, - { label: "Уникальная техника Культивации", value: "350" }, - { label: "Уникальное оружие", value: "426" }, - { label: "Управление бизнесом", value: "403" }, - { label: "Управление временем", value: "279" }, - { label: "Управление кровью", value: "753" }, - { label: "Упрямый главный герой", value: "695" }, - { label: "Уродливый главный герой", value: "766" }, - { label: "Ускоренный рост", value: "390" }, - { label: "Усыновленные дети", value: "543" }, - { label: "Усыновленный главный герой", value: "486" }, - { label: "Уход за детьми", value: "474" }, - { label: "Учителя", value: "431" }, - { label: "Фамильяры", value: "596" }, - { label: "Фанатизм", value: "650" }, - { label: "Фантастические существа", value: "410" }, - { label: "Фантастический детектив", value: "115" }, - { label: "Фанфик", value: "113" }, - { label: "Фанфикшн", value: "464" }, - { label: "Фармацевт", value: "728" }, - { label: "Фарминг", value: "458" }, - { label: "Феи", value: "316" }, - { label: "Фелляция", value: "631" }, - { label: "Фемслэш", value: "127" }, - { label: "Фениксы", value: "454" }, - { label: "Фетиш груди", value: "559" }, - { label: "Философия", value: "208" }, - { label: "Фильмы", value: "479" }, - { label: "Флэшбэки", value: "585" }, - { label: "Фобии", value: "220" }, - { label: "Фольклор", value: "529" }, - { label: "Футанари", value: "619" }, - { label: "Футуристический сеттинг", value: "460" }, - { label: "Фэнтези мир", value: "244" }, - { label: "Хакеры", value: "475" }, - { label: "Харизматический герой", value: "467" }, - { label: "Хикикомори/Затворники", value: "524" }, - { label: "Хитроумный главный герой", value: "224" }, - { label: "Хозяин подземелий", value: "608" }, - { label: "Холодный главный герой", value: "354" }, - { label: "Хорошие отношения с семьей", value: "566" }, - { label: "Хранители могил", value: "191" }, - { label: "Целители", value: "465" }, - { label: "Цзянши", value: "740" }, - { label: "Цундэрэ", value: "510" }, - { label: "Чаты", value: "629" }, - { label: "Человеческое оружие", value: "580" }, - { label: "Честный главный герой", value: "341" }, - { label: "Читы", value: "339" }, - { label: "Шантаж", value: "584" }, - { label: "Шеф-повар", value: "340" }, - { label: "Шикигами", value: "598" }, - { label: "Школа только для девочек", value: "668" }, - { label: "Шота", value: "573" }, - { label: "Шоу-бизнес", value: "481" }, - { label: "Шпионский детектив", value: "118" }, - { label: "Шпионы", value: "614" }, - { label: "Эволюция", value: "304" }, - { label: "Эгоистичный главный герой", value: "594" }, - { label: "Эйдетическая память", value: "468" }, - { label: "Экзорсизм", value: "564" }, - { label: "Экономика", value: "553" }, - { label: "Эксгибиционизм", value: "673" }, - { label: "Эксперименты с людьми", value: "248" }, - { label: "Элементальная магия", value: "471" }, - { label: "Эльфы", value: "284" }, - { label: "Эмоционально слабый гг", value: "770" }, - { label: "Эпизодический", value: "649" }, - { label: "Эпическое фэнтези", value: "109" }, - { label: "Эротическая фантастика", value: "129" }, - { label: "Эротический фанфик", value: "128" }, - { label: "Эротическое фэнтези", value: "130" }, - { label: "Юмористическая фантастика", value: "143" }, - { label: "Юмористическое фэнтези", value: "108" }, - { label: "Юный любовный интерес", value: "511" }, - { label: "Яды", value: "484" }, - { label: "Языкастые персонажи", value: "480" }, - { label: "Языковой барьер", value: "182" }, - { label: "Яндере", value: "314" }, - { label: "Японские силы самообороны", value: "610" }, - { label: "Ярко выраженная романтика", value: "365" }, - { label: "R-15 Японское возрастное огр.", value: "332" }, - { label: "R-18", value: "424" }, - ], - inputType: filterInputs_1.FilterInputs.Checkbox, - }, - { - key: "types", - label: "Типы:", - values: [ - { label: "Авторское", value: "1" }, - { label: "Другое", value: "7" }, - { label: "Запад", value: "5" }, - { label: "Китай", value: "4" }, - { label: "Корея", value: "3" }, - { label: "Фанфики", value: "6" }, - { label: "Япония", value: "2" }, - ], - inputType: filterInputs_1.FilterInputs.Checkbox, - }, - { - key: "status", - label: "Статус проекта:", - values: [ - { label: "Анонс", value: "4" }, - { label: "Закончен", value: "0" }, - { label: "Заморожен", value: "2" }, - { label: "Лицензировано", value: "5" }, - { label: "Нет переводчика", value: "3" }, - { label: "Продолжается", value: "1" }, - ], - inputType: filterInputs_1.FilterInputs.Checkbox, - }, - { - key: "age_limit", - label: "Возрастной рейтинг:", - values: [ - { label: "16+", value: "1" }, - { label: "18+", value: "2" }, - { label: "Для всех", value: "0" }, - ], - inputType: filterInputs_1.FilterInputs.Checkbox, - }, -]; diff --git a/js/plugins/spanish/hasutl.js b/js/plugins/spanish/hasutl.js deleted file mode 100644 index 8a31f92..0000000 --- a/js/plugins/spanish/hasutl.js +++ /dev/null @@ -1,121 +0,0 @@ -"use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.fetchImage = exports.searchNovels = exports.parseChapter = exports.parseNovelAndChapters = exports.popularNovels = exports.icon = exports.version = exports.site = exports.name = exports.id = void 0; -const cheerio_1 = require("cheerio"); -const fetch_1 = require("@libs/fetch"); -exports.id = "HasuTL"; -exports.name = "Hasu Translations"; -exports.site = "https://hasutl.wordpress.com/"; -exports.version = "1.0.0"; -exports.icon = "src/es/hasutl/icon.png"; -const baseUrl = exports.site; -const popularNovels = function (page) { - return __awaiter(this, void 0, void 0, function* () { - let url = baseUrl + "light-novels-activas/"; - const result = yield (0, fetch_1.fetchApi)(url); - const body = yield result.text(); - let loadedCheerio = (0, cheerio_1.load)(body); - let novels = []; - loadedCheerio("div.wp-block-columns").each(function () { - const novelName = loadedCheerio(this).find(".wp-block-button").text(); - const novelCover = loadedCheerio(this).find("img").attr("src"); - let novelUrl = loadedCheerio(this) - .find(".wp-block-button > a") - .attr("href"); - if (!novelUrl) - return; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - }); - return novels; - }); -}; -exports.popularNovels = popularNovels; -const parseNovelAndChapters = function (novelUrl) { - return __awaiter(this, void 0, void 0, function* () { - const url = novelUrl; - const result = yield (0, fetch_1.fetchApi)(url); - const body = yield result.text(); - let loadedCheerio = (0, cheerio_1.load)(body); - let novel = { - url, - }; - novel.url = novelUrl; - novel.name = loadedCheerio(".post-header").text(); - novel.cover = loadedCheerio(".featured-media > img").attr("src"); - let novelSummary = loadedCheerio(".post-content").find("p").html(); - novel.summary = novelSummary; - let novelChapters = []; - loadedCheerio(".wp-block-media-text__content") - .find("a") - .each(function () { - const chapterName = loadedCheerio(this).text().trim(); - const releaseDate = null; - let chapterUrl = loadedCheerio(this).attr("href"); - if (!chapterUrl) - return; - const chapter = { - name: chapterName, - releaseTime: releaseDate, - url: chapterUrl, - }; - novelChapters.push(chapter); - }); - novel.chapters = novelChapters; - return novel; - }); -}; -exports.parseNovelAndChapters = parseNovelAndChapters; -const parseChapter = function (chapterUrl) { - return __awaiter(this, void 0, void 0, function* () { - const url = chapterUrl; - const result = yield (0, fetch_1.fetchApi)(url); - const body = yield result.text(); - let loadedCheerio = (0, cheerio_1.load)(body); - let chapterText = loadedCheerio(".post-content").html(); - return chapterText; - }); -}; -exports.parseChapter = parseChapter; -const searchNovels = function (searchTerm) { - return __awaiter(this, void 0, void 0, function* () { - const url = `${baseUrl}?s=${searchTerm}&post_type=wp-manga`; - const result = yield (0, fetch_1.fetchApi)(url); - const body = yield result.text(); - let loadedCheerio = (0, cheerio_1.load)(body); - let novels = []; - loadedCheerio(".post-container ").each(function () { - const novelName = loadedCheerio(this).find(".post-header").text(); - if (!novelName.includes("Cap") && - !novelName.includes("Vol") && - !novelName.includes("Light Novels")) { - const novelCover = loadedCheerio(this).find("img").attr("src"); - let novelUrl = loadedCheerio(this).find("a").attr("href"); - if (!novelUrl) - return; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - } - }); - return novels; - }); -}; -exports.searchNovels = searchNovels; -exports.fetchImage = fetch_1.fetchFile; diff --git a/js/plugins/spanish/novelasligera.js b/js/plugins/spanish/novelasligera.js deleted file mode 100644 index 40ab405..0000000 --- a/js/plugins/spanish/novelasligera.js +++ /dev/null @@ -1,157 +0,0 @@ -"use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.fetchImage = exports.searchNovels = exports.parseChapter = exports.parseNovelAndChapters = exports.popularNovels = exports.icon = exports.version = exports.site = exports.name = exports.id = void 0; -const cheerio_1 = require("cheerio"); -const fetch_1 = require("@libs/fetch"); -exports.id = "ligera.com"; -exports.name = "Novelas Ligera"; -exports.site = "https://novelasligera.com/"; -exports.version = "1.0.0"; -exports.icon = "src/es/novelasligera/icon.png"; -const baseUrl = exports.site; -const popularNovels = function (page) { - return __awaiter(this, void 0, void 0, function* () { - let url = baseUrl; - const result = yield (0, fetch_1.fetchApi)(url); - const body = yield result.text(); - let loadedCheerio = (0, cheerio_1.load)(body); - let novels = []; - loadedCheerio(".elementor-column").each(function () { - const novelName = loadedCheerio(this) - .find(".widget-image-caption.wp-caption-text") - .text(); - if (novelName) { - const novelCover = loadedCheerio(this) - .find("a > img") - .attr("data-lazy-src"); - let novelUrl = loadedCheerio(this).find("a").attr("href"); - if (!novelUrl) - return; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - } - }); - return novels; - }); -}; -exports.popularNovels = popularNovels; -const parseNovelAndChapters = function (novelUrl) { - return __awaiter(this, void 0, void 0, function* () { - const url = baseUrl + "novela/" + novelUrl; - // console.log(url); - const result = yield (0, fetch_1.fetchApi)(url); - const body = yield result.text(); - let loadedCheerio = (0, cheerio_1.load)(body); - let novel = { url }; - novel.name = loadedCheerio("h1").text(); - novel.cover = loadedCheerio(".elementor-widget-container") - .find("img") - .attr("src"); - loadedCheerio(".elementor-row") - .find("p") - .each(function () { - if (loadedCheerio(this).text().includes("Autor:")) { - novel.author = loadedCheerio(this) - .text() - .replace("Autor:", "") - .trim(); - } - if (loadedCheerio(this).text().includes("Estado:")) { - novel.status = loadedCheerio(this) - .text() - .replace("Estado: ", "") - .trim(); - } - if (loadedCheerio(this).text().includes("Género:")) { - loadedCheerio(this).find("span").remove(); - novel.genres = loadedCheerio(this) - .text() - .replace(/,\s/g, ","); - } - }); - novel.summary = loadedCheerio(".elementor-text-editor.elementor-clearfix").text(); - let novelChapters = []; - loadedCheerio(".elementor-accordion-item").remove(); - loadedCheerio(".elementor-tab-content") - .find("li") - .each(function () { - const chapterName = loadedCheerio(this).text(); - const releaseDate = null; - const chapterUrl = loadedCheerio(this).find("a").attr("href"); - if (!chapterUrl) - return; - const chapter = { - name: chapterName, - releaseTime: releaseDate, - url: chapterUrl, - }; - novelChapters.push(chapter); - }); - novel.chapters = novelChapters; - return novel; - }); -}; -exports.parseNovelAndChapters = parseNovelAndChapters; -const parseChapter = function (chapterUrl) { - return __awaiter(this, void 0, void 0, function* () { - const url = chapterUrl; - // console.log(url); - const result = yield (0, fetch_1.fetchApi)(url); - const body = yield result.text(); - let loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio(".osny-nightmode.osny-nightmode--left").remove(); - loadedCheerio(".code-block.code-block-1").remove(); - loadedCheerio(".adsb30").remove(); - loadedCheerio(".saboxplugin-wrap").remove(); - loadedCheerio(".wp-post-navigation").remove(); - let chapterText = loadedCheerio(".entry-content").html(); - return chapterText; - }); -}; -exports.parseChapter = parseChapter; -const searchNovels = function (searchTerm) { - return __awaiter(this, void 0, void 0, function* () { - const url = baseUrl + "?s=" + searchTerm + "&post_type=wp-manga"; - // console.log(url); - const result = yield (0, fetch_1.fetchApi)(url); - const body = yield result.text(); - let loadedCheerio = (0, cheerio_1.load)(body); - let novels = []; - loadedCheerio(".inside-article").each(function () { - const novelCover = loadedCheerio(this).find("img").attr("src"); - let novelUrl = loadedCheerio(this).find("a").attr("href"); - let novelName; - if (novelUrl) { - novelName = novelUrl.replace(/-/g, " ").replace(/^./, function (x) { - return x.toUpperCase(); - }); - } - novelUrl += "/"; - if (!novelName || !novelUrl) - return; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - }); - novels = [Object.assign({}, novels[1])]; - return novels; - }); -}; -exports.searchNovels = searchNovels; -exports.fetchImage = fetch_1.fetchFile; diff --git a/js/plugins/spanish/skynovels.js b/js/plugins/spanish/skynovels.js deleted file mode 100644 index e486dbf..0000000 --- a/js/plugins/spanish/skynovels.js +++ /dev/null @@ -1,116 +0,0 @@ -"use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.fetchImage = exports.searchNovels = exports.parseChapter = exports.parseNovelAndChapters = exports.popularNovels = exports.icon = exports.version = exports.site = exports.name = exports.id = void 0; -const fetch_1 = require("@libs/fetch"); -exports.id = "skynovels.net"; -exports.name = "SkyNovels"; -exports.site = "https://www.skynovels.net/"; -exports.version = "1.0.0"; -exports.icon = "src/es/skynovels/icon.png"; -const baseUrl = exports.site; -const popularNovels = function (page) { - var _a; - return __awaiter(this, void 0, void 0, function* () { - const url = "https://api.skynovels.net/api/novels?&q"; - const result = yield (0, fetch_1.fetchApi)(url); - const body = yield result.json(); - const novels = []; - (_a = body.novels) === null || _a === void 0 ? void 0 : _a.forEach((res) => { - const novelName = res.nvl_title; - const novelCover = "https://api.skynovels.net/api/get-image/" + - res.image + - "/novels/false"; - const novelUrl = baseUrl + "novelas/" + res.id + "/" + res.nvl_name + "/"; - const novel = { name: novelName, url: novelUrl, cover: novelCover }; - novels.push(novel); - }); - return novels; - }); -}; -exports.popularNovels = popularNovels; -const parseNovelAndChapters = function (novUrl) { - var _a, _b, _c; - return __awaiter(this, void 0, void 0, function* () { - const novelId = novUrl.split("/")[4]; - const url = "https://api.skynovels.net/api/novel/" + novelId + "/reading?&q"; - const result = yield (0, fetch_1.fetchApi)(url); - const body = yield result.json(); - const item = (_a = body === null || body === void 0 ? void 0 : body.novel) === null || _a === void 0 ? void 0 : _a[0]; - let novel = { url: novUrl }; - novel.name = item === null || item === void 0 ? void 0 : item.nvl_title; - novel.cover = - "https://api.skynovels.net/api/get-image/" + - (item === null || item === void 0 ? void 0 : item.image) + - "/novels/false"; - let genres = []; - (_b = item === null || item === void 0 ? void 0 : item.genres) === null || _b === void 0 ? void 0 : _b.forEach((genre) => genres.push(genre.genre_name)); - novel.genres = genres.join(","); - novel.author = item === null || item === void 0 ? void 0 : item.nvl_writer; - novel.summary = item === null || item === void 0 ? void 0 : item.nvl_content; - novel.status = item === null || item === void 0 ? void 0 : item.nvl_status; - let novelChapters = []; - (_c = item === null || item === void 0 ? void 0 : item.volumes) === null || _c === void 0 ? void 0 : _c.forEach((volume) => { - var _a; - (_a = volume === null || volume === void 0 ? void 0 : volume.chapters) === null || _a === void 0 ? void 0 : _a.forEach((chapter) => { - const chapterName = chapter.chp_index_title; - const releaseDate = new Date(chapter.createdAt).toDateString(); - const chapterUrl = novUrl + chapter.id + "/" + chapter.chp_name; - const chap = { - name: chapterName, - releaseTime: releaseDate, - url: chapterUrl, - }; - novelChapters.push(chap); - }); - }); - novel.chapters = novelChapters; - return novel; - }); -}; -exports.parseNovelAndChapters = parseNovelAndChapters; -const parseChapter = function (chapUrl) { - var _a; - return __awaiter(this, void 0, void 0, function* () { - let chapterId = chapUrl.split("/")[6]; - const url = `https://api.skynovels.net/api/novel-chapter/${chapterId}`; - const result = yield (0, fetch_1.fetchApi)(url); - const body = yield result.json(); - const item = (_a = body === null || body === void 0 ? void 0 : body.chapter) === null || _a === void 0 ? void 0 : _a[0]; - let chapterText = (item === null || item === void 0 ? void 0 : item.chp_content) || '404'; - return chapterText; - }); -}; -exports.parseChapter = parseChapter; -const searchNovels = function (searchTerm) { - var _a; - return __awaiter(this, void 0, void 0, function* () { - searchTerm = searchTerm.toLowerCase(); - const url = "https://api.skynovels.net/api/novels?&q"; - const result = yield (0, fetch_1.fetchApi)(url); - const body = yield result.json(); - ; - let results = (_a = body === null || body === void 0 ? void 0 : body.novels) === null || _a === void 0 ? void 0 : _a.filter((novel) => novel.nvl_title.toLowerCase().includes(searchTerm)); - const novels = []; - results === null || results === void 0 ? void 0 : results.forEach((res) => { - const novelName = res.nvl_title; - const novelCover = "https://api.skynovels.net/api/get-image/" + - res.image + - "/novels/false"; - const novelUrl = baseUrl + "novelas/" + res.id + "/" + res.nvl_name + "/"; - const novel = { name: novelName, url: novelUrl, cover: novelCover }; - novels.push(novel); - }); - return novels; - }); -}; -exports.searchNovels = searchNovels; -exports.fetchImage = fetch_1.fetchFile; diff --git a/js/plugins/spanish/tunovelaligera.js b/js/plugins/spanish/tunovelaligera.js deleted file mode 100644 index d279fe8..0000000 --- a/js/plugins/spanish/tunovelaligera.js +++ /dev/null @@ -1,146 +0,0 @@ -"use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.fetchImage = exports.searchNovels = exports.parseChapter = exports.parseNovelAndChapters = exports.popularNovels = exports.icon = exports.version = exports.site = exports.name = exports.id = void 0; -const fetch_1 = require("@libs/fetch"); -const cheerio_1 = require("cheerio"); -const novelStatus_1 = require("@libs/novelStatus"); -const defaultCover_1 = require("@libs/defaultCover"); -exports.id = "TNL.com"; -exports.name = "TuNovelaLigera"; -exports.site = "https://tunovelaligera.com/"; -exports.version = "1.0.0"; -exports.icon = "src/es/tunovelaligera/icon.png"; -const baseUrl = exports.site; -const popularNovels = function (page) { - return __awaiter(this, void 0, void 0, function* () { - let url = baseUrl + "novelas/page/" + page + "/?m_orderby=rating"; - const result = yield (0, fetch_1.fetchApi)(url); - const body = yield result.text(); - let loadedCheerio = (0, cheerio_1.load)(body); - let novels = []; - loadedCheerio(".page-item-detail").each(function () { - const novelName = loadedCheerio(this).find(".h5 > a").text(); - const novelCover = loadedCheerio(this).find("img").attr("src"); - let novelUrl = loadedCheerio(this).find(".h5 > a").attr("href"); - if (!novelUrl) - return; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - }); - return novels; - }); -}; -exports.popularNovels = popularNovels; -const parseNovelAndChapters = function (novelUrl) { - return __awaiter(this, void 0, void 0, function* () { - const url = novelUrl; - const result = yield (0, fetch_1.fetchApi)(url); - const body = yield result.text(); - let loadedCheerio = (0, cheerio_1.load)(body); - let novel = { - url, - }; - loadedCheerio(".manga-title-badges").remove(); - novel.name = loadedCheerio(".post-title > h1").text().trim(); - let novelCover = loadedCheerio(".summary_image > a > img"); - novel.cover = - novelCover.attr("data-src") || - novelCover.attr("src") || - defaultCover_1.defaultCover; - loadedCheerio(".post-content_item").each(function () { - const detailName = loadedCheerio(this) - .find(".summary-heading > h5") - .text() - .trim(); - const detail = loadedCheerio(this) - .find(".summary-content") - .text() - .trim(); - switch (detailName) { - case "Generos": - novel.genres = detail.replace(/, /g, ","); - break; - case "Autores": - novel.author = detail; - break; - case "Estado": - novel.status = - detail.includes("OnGoing") || - detail.includes("Updating") - ? novelStatus_1.NovelStatus.Ongoing - : novelStatus_1.NovelStatus.Completed; - break; - } - }); - novel.summary = loadedCheerio("div.summary__content > p").text().trim(); - let novelChapters = []; - loadedCheerio(".lcp_catlist li").each(function () { - const chapterName = loadedCheerio(this) - .find("a") - .text() - .replace(/[\t\n]/g, "") - .trim(); - const releaseDate = loadedCheerio(this).find("span").text().trim(); - let chapterUrl = loadedCheerio(this).find("a").attr("href"); - if (!chapterUrl) - return; - novelChapters.push({ - name: chapterName, - releaseTime: releaseDate, - url: chapterUrl, - }); - }); - novel.chapters = novelChapters.reverse(); - return novel; - }); -}; -exports.parseNovelAndChapters = parseNovelAndChapters; -const parseChapter = function (chapterUrl) { - return __awaiter(this, void 0, void 0, function* () { - const url = chapterUrl; - const result = yield (0, fetch_1.fetchApi)(url); - const body = yield result.text(); - let loadedCheerio = (0, cheerio_1.load)(body); - let chapterText = loadedCheerio("#hola_siguiente").next().text(); - return chapterText; - }); -}; -exports.parseChapter = parseChapter; -const searchNovels = function (searchTerm) { - return __awaiter(this, void 0, void 0, function* () { - const url = `${baseUrl}?s=${searchTerm}&post_type=wp-manga`; - const result = yield (0, fetch_1.fetchApi)(url); - const body = yield result.text(); - let loadedCheerio = (0, cheerio_1.load)(body); - let novels = []; - loadedCheerio(".c-tabs-item__content").each(function () { - const novelName = loadedCheerio(this).find(".h4 > a").text(); - const novelCover = loadedCheerio(this).find("img").attr("src"); - let novelUrl = loadedCheerio(this).find(".h4 > a").attr("href"); - if (!novelUrl) - return; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - }); - return novels; - }); -}; -exports.searchNovels = searchNovels; -exports.fetchImage = fetch_1.fetchFile; diff --git a/js/plugins/spanish/yukitls.js b/js/plugins/spanish/yukitls.js deleted file mode 100644 index 6b7547e..0000000 --- a/js/plugins/spanish/yukitls.js +++ /dev/null @@ -1,160 +0,0 @@ -"use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.fetchImage = exports.searchNovels = exports.parseChapter = exports.parseNovelAndChapters = exports.popularNovels = exports.icon = exports.version = exports.site = exports.name = exports.id = void 0; -const fetch_1 = require("@libs/fetch"); -const cheerio_1 = require("cheerio"); -exports.id = "yuukitls.com"; -exports.name = "Yuuki Tls"; -exports.site = "https://yuukitls.com/"; -exports.version = "1.0.0"; -exports.icon = "src/es/yuukitls/icon.png"; -const baseUrl = exports.site; -const popularNovels = function (page) { - return __awaiter(this, void 0, void 0, function* () { - let url = baseUrl; - const result = yield (0, fetch_1.fetchApi)(url); - const body = yield result.text(); - let loadedCheerio = (0, cheerio_1.load)(body); - let novels = []; - loadedCheerio(".quadmenu-navbar-collapse ul li:nth-child(2)") - .find("li") - .each(function () { - const novelName = loadedCheerio(this) - .text() - .replace(/[\s\n]+/g, " "); - const novelCover = loadedCheerio(this).find("img").attr("src"); - let novelUrl = loadedCheerio(this).find("a").attr("href"); - if (!novelUrl) - return; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - }); - return novels; - }); -}; -exports.popularNovels = popularNovels; -const parseNovelAndChapters = function (novelUrl) { - return __awaiter(this, void 0, void 0, function* () { - const url = novelUrl; - const result = yield (0, fetch_1.fetchApi)(url); - const body = yield result.text(); - let loadedCheerio = (0, cheerio_1.load)(body); - let novel = { - url, - }; - novel.name = loadedCheerio("h1.entry-title") - .text() - .replace(/[\t\n]/g, "") - .trim(); - novel.cover = loadedCheerio('img[loading="lazy"]').attr("src"); - loadedCheerio(".entry-content") - .find("div") - .each(function () { - if (loadedCheerio(this).text().includes("Escritor:")) { - novel.author = loadedCheerio(this) - .text() - .replace("Escritor: ", "") - .trim(); - } - if (loadedCheerio(this).text().includes("Género:")) { - novel.genres = loadedCheerio(this) - .text() - .replace(/Género: |\s/g, ""); - } - if (loadedCheerio(this).text().includes("Sinopsis:")) { - novel.summary = loadedCheerio(this).next().text(); - } - }); - let novelChapters = []; - if (loadedCheerio(".entry-content").find("li").length) { - loadedCheerio(".entry-content") - .find("li") - .each(function () { - let chapterUrl = loadedCheerio(this).find("a").attr("href"); - if (chapterUrl && chapterUrl.includes(baseUrl)) { - const chapterName = loadedCheerio(this).text(); - const releaseDate = null; - const chapter = { - name: chapterName, - releaseTime: releaseDate, - url: chapterUrl, - }; - novelChapters.push(chapter); - } - }); - } - else { - loadedCheerio(".entry-content") - .find("p") - .each(function () { - let chapterUrl = loadedCheerio(this).find("a").attr("href"); - if (chapterUrl && chapterUrl.includes(baseUrl)) { - const chapterName = loadedCheerio(this).text(); - const releaseDate = null; - const chapter = { - name: chapterName, - releaseTime: releaseDate, - url: chapterUrl, - }; - novelChapters.push(chapter); - } - }); - } - novel.chapters = novelChapters; - return novel; - }); -}; -exports.parseNovelAndChapters = parseNovelAndChapters; -const parseChapter = function (chapterUrl) { - return __awaiter(this, void 0, void 0, function* () { - const url = chapterUrl; - const result = yield (0, fetch_1.fetchApi)(url); - const body = yield result.text(); - let loadedCheerio = (0, cheerio_1.load)(body); - let chapterText = loadedCheerio(".entry-content").html(); - return chapterText; - }); -}; -exports.parseChapter = parseChapter; -const searchNovels = function (searchTerm) { - return __awaiter(this, void 0, void 0, function* () { - searchTerm = searchTerm.toLowerCase(); - let url = baseUrl; - const result = yield (0, fetch_1.fetchApi)(url); - const body = yield result.text(); - let loadedCheerio = (0, cheerio_1.load)(body); - let novels = []; - loadedCheerio(".menu-item-2869") - .find(".menu-item.menu-item-type-post_type.menu-item-object-post") - .each(function () { - const novelName = loadedCheerio(this).text(); - const novelCover = loadedCheerio(this).find("img").attr("src"); - let novelUrl = loadedCheerio(this).find("a").attr("href"); - if (!novelUrl) - return; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - }); - novels = novels.filter((novel) => novel.name.toLowerCase().includes(searchTerm)); - return novels; - }); -}; -exports.searchNovels = searchNovels; -exports.fetchImage = fetch_1.fetchFile; diff --git a/js/plugins/turkish/TurkceLightNovels[madara].js b/js/plugins/turkish/TurkceLightNovels[madara].js deleted file mode 100644 index 2438a6b..0000000 --- a/js/plugins/turkish/TurkceLightNovels[madara].js +++ /dev/null @@ -1,179 +0,0 @@ -"use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.filters = exports.fetchImage = exports.searchNovels = exports.parseChapter = exports.parseNovelAndChapters = exports.popularNovels = exports.site = exports.version = exports.icon = exports.name = exports.id = void 0; -const cheerio_1 = require("cheerio"); -const fetch_1 = require("@libs/fetch"); -const filterInputs_1 = require("@libs/filterInputs"); -const defaultCover_1 = require("@libs/defaultCover"); -const novelStatus_1 = require("@libs/novelStatus"); -const parseMadaraDate_1 = require("@libs/parseMadaraDate"); -const dayjs_1 = __importDefault(require("dayjs")); -exports.id = "turkcelightnovels"; -exports.name = "TurkceLightNovels [madara]"; -exports.icon = "multisrc/madara/icons/turkcelightnovels.png"; -exports.version = "1.0.0"; -exports.site = "https://turkcelightnovels.com/"; -const baseUrl = exports.site; -const popularNovels = (pageNo, { filters, showLatestNovels }) => __awaiter(void 0, void 0, void 0, function* () { - const novels = []; - let url = exports.site; - if (filters === null || filters === void 0 ? void 0 : filters.genres) { - url += "novel-genre/" + filters.genres + '/'; - } - else { - url += "light-novel/"; - } - url += '/page/' + pageNo + '/' + - '?m_orderby=' + (showLatestNovels ? 'latest' : ((filters === null || filters === void 0 ? void 0 : filters.sort) || 'rating')); - const body = yield (0, fetch_1.fetchApi)(url).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.manga-title-badges').remove(); - loadedCheerio('.page-item-detail').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - let novelUrl = loadedCheerio(this).find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - }); - return novels; -}); -exports.popularNovels = popularNovels; -const parseNovelAndChapters = (novelUrl) => __awaiter(void 0, void 0, void 0, function* () { - const novel = { - url: novelUrl, - }; - const body = yield (0, fetch_1.fetchApi)(novelUrl).then(res => res.text()); - let loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.manga-title-badges').remove(); - novel.name = loadedCheerio('.post-title h1').text().trim(); - novel.cover = - loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || - loadedCheerio('.summary_image > a > img').attr('data-src') || - loadedCheerio('.summary_image > a > img').attr('src') || - defaultCover_1.defaultCover; - loadedCheerio('.post-content_item, .post-content').each(function () { - const detailName = loadedCheerio(this).find('h5').text().trim(); - const detail = loadedCheerio(this).find('.summary-content').text().trim(); - switch (detailName) { - case 'Genre(s)': - case 'التصنيفات': - novel.genres = detail.replace(/[\t\n]/g, ','); - break; - case 'Author(s)': - case 'المؤلف': - case 'المؤلف (ين)': - novel.author = detail; - break; - case 'Status': - case 'الحالة': - novel.status = - detail.includes('OnGoing') || detail.includes('مستمرة') - ? novelStatus_1.NovelStatus.Ongoing - : novelStatus_1.NovelStatus.Completed; - break; - } - }); - loadedCheerio('div.summary__content .code-block,script').remove(); - novel.summary = loadedCheerio('div.summary__content').text().trim(); - let html; - if (false) { - const novelId = loadedCheerio('.rating-post-id').attr('value') || - loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; - const body = { - action: "manga_get_chapters", - manga: novelId, - }; - html = yield (0, fetch_1.fetchApi)(baseUrl + 'wp-admin/admin-ajax.php', { - method: 'POST', - body: JSON.stringify(body), - }) - .then(res => res.text()); - } - else { - html = yield (0, fetch_1.fetchApi)(baseUrl + 'ajax/chapters/', { method: 'POST' }) - .then(res => res.text()); - } - if (html !== '0') { - loadedCheerio = (0, cheerio_1.load)(html); - } - const chapters = []; - loadedCheerio('.wp-manga-chapter').each(function () { - const chapterName = loadedCheerio(this).find('a').text().trim(); - let releaseDate = null; - releaseDate = loadedCheerio(this) - .find('span.chapter-release-date') - .text() - .trim(); - if (releaseDate) { - releaseDate = (0, parseMadaraDate_1.parseMadaraDate)(releaseDate); - } - else { - /** - * Insert current date - */ - releaseDate = (0, dayjs_1.default)().format('LL'); - } - let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; - chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); - }); - novel.chapters = chapters.reverse(); - return novel; -}); -exports.parseNovelAndChapters = parseNovelAndChapters; -const parseChapter = (chapterUrl) => __awaiter(void 0, void 0, void 0, function* () { - const url = baseUrl + "/" + "light-novel" + "/" + chapterUrl; - const body = yield (0, fetch_1.fetchApi)(chapterUrl).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - const chapterText = loadedCheerio('.text-left').html() || - loadedCheerio('.text-right').html() || - loadedCheerio('.entry-content').html(); - return chapterText; -}); -exports.parseChapter = parseChapter; -const searchNovels = (searchTerm) => __awaiter(void 0, void 0, void 0, function* () { - const novels = []; - const url = baseUrl + "?s=" + searchTerm + "&post_type=wp-manga"; - const body = yield (0, fetch_1.fetchApi)(url).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.c-tabs-item__content').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - let novelUrl = loadedCheerio(this) - .find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - }); - return novels; -}); -exports.searchNovels = searchNovels; -const fetchImage = (url) => __awaiter(void 0, void 0, void 0, function* () { - return yield (0, fetch_1.fetchFile)(url); -}); -exports.fetchImage = fetchImage; -exports.filters = [{ "key": "sort", "label": "Order by", "values": [{ "label": "Rating", "value": "rating" }, { "label": "A-Z", "value": "alphabet" }, { "label": "Latest", "value": "latest" }, { "label": "Most Views", "value": "views" }, { "label": "New", "value": "new-manga" }, { "label": "Trending", "value": "trending" }], "inputType": filterInputs_1.FilterInputs.Picker }]; diff --git a/js/plugins/turkish/WebNovelOku[madara].js b/js/plugins/turkish/WebNovelOku[madara].js deleted file mode 100644 index b9d173d..0000000 --- a/js/plugins/turkish/WebNovelOku[madara].js +++ /dev/null @@ -1,179 +0,0 @@ -"use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.filters = exports.fetchImage = exports.searchNovels = exports.parseChapter = exports.parseNovelAndChapters = exports.popularNovels = exports.site = exports.version = exports.icon = exports.name = exports.id = void 0; -const cheerio_1 = require("cheerio"); -const fetch_1 = require("@libs/fetch"); -const filterInputs_1 = require("@libs/filterInputs"); -const defaultCover_1 = require("@libs/defaultCover"); -const novelStatus_1 = require("@libs/novelStatus"); -const parseMadaraDate_1 = require("@libs/parseMadaraDate"); -const dayjs_1 = __importDefault(require("dayjs")); -exports.id = "webnoveloku"; -exports.name = "WebNovelOku [madara]"; -exports.icon = "multisrc/madara/icons/webnoveloku.png"; -exports.version = "1.0.0"; -exports.site = "https://www.webnoveloku.com/"; -const baseUrl = exports.site; -const popularNovels = (pageNo, { filters, showLatestNovels }) => __awaiter(void 0, void 0, void 0, function* () { - const novels = []; - let url = exports.site; - if (filters === null || filters === void 0 ? void 0 : filters.genres) { - url += "novel-genre/" + filters.genres + '/'; - } - else { - url += "novel/"; - } - url += '/page/' + pageNo + '/' + - '?m_orderby=' + (showLatestNovels ? 'latest' : ((filters === null || filters === void 0 ? void 0 : filters.sort) || 'rating')); - const body = yield (0, fetch_1.fetchApi)(url).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.manga-title-badges').remove(); - loadedCheerio('.page-item-detail').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - let novelUrl = loadedCheerio(this).find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - }); - return novels; -}); -exports.popularNovels = popularNovels; -const parseNovelAndChapters = (novelUrl) => __awaiter(void 0, void 0, void 0, function* () { - const novel = { - url: novelUrl, - }; - const body = yield (0, fetch_1.fetchApi)(novelUrl).then(res => res.text()); - let loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.manga-title-badges').remove(); - novel.name = loadedCheerio('.post-title h1').text().trim(); - novel.cover = - loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || - loadedCheerio('.summary_image > a > img').attr('data-src') || - loadedCheerio('.summary_image > a > img').attr('src') || - defaultCover_1.defaultCover; - loadedCheerio('.post-content_item, .post-content').each(function () { - const detailName = loadedCheerio(this).find('h5').text().trim(); - const detail = loadedCheerio(this).find('.summary-content').text().trim(); - switch (detailName) { - case 'Genre(s)': - case 'التصنيفات': - novel.genres = detail.replace(/[\t\n]/g, ','); - break; - case 'Author(s)': - case 'المؤلف': - case 'المؤلف (ين)': - novel.author = detail; - break; - case 'Status': - case 'الحالة': - novel.status = - detail.includes('OnGoing') || detail.includes('مستمرة') - ? novelStatus_1.NovelStatus.Ongoing - : novelStatus_1.NovelStatus.Completed; - break; - } - }); - loadedCheerio('div.summary__content .code-block,script').remove(); - novel.summary = loadedCheerio('div.summary__content').text().trim(); - let html; - if (false) { - const novelId = loadedCheerio('.rating-post-id').attr('value') || - loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; - const body = { - action: "manga_get_chapters", - manga: novelId, - }; - html = yield (0, fetch_1.fetchApi)(baseUrl + 'wp-admin/admin-ajax.php', { - method: 'POST', - body: JSON.stringify(body), - }) - .then(res => res.text()); - } - else { - html = yield (0, fetch_1.fetchApi)(baseUrl + 'ajax/chapters/', { method: 'POST' }) - .then(res => res.text()); - } - if (html !== '0') { - loadedCheerio = (0, cheerio_1.load)(html); - } - const chapters = []; - loadedCheerio('.wp-manga-chapter').each(function () { - const chapterName = loadedCheerio(this).find('a').text().trim(); - let releaseDate = null; - releaseDate = loadedCheerio(this) - .find('span.chapter-release-date') - .text() - .trim(); - if (releaseDate) { - releaseDate = (0, parseMadaraDate_1.parseMadaraDate)(releaseDate); - } - else { - /** - * Insert current date - */ - releaseDate = (0, dayjs_1.default)().format('LL'); - } - let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; - chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); - }); - novel.chapters = chapters.reverse(); - return novel; -}); -exports.parseNovelAndChapters = parseNovelAndChapters; -const parseChapter = (chapterUrl) => __awaiter(void 0, void 0, void 0, function* () { - const url = baseUrl + "/" + "novel" + "/" + chapterUrl; - const body = yield (0, fetch_1.fetchApi)(chapterUrl).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - const chapterText = loadedCheerio('.text-left').html() || - loadedCheerio('.text-right').html() || - loadedCheerio('.entry-content').html(); - return chapterText; -}); -exports.parseChapter = parseChapter; -const searchNovels = (searchTerm) => __awaiter(void 0, void 0, void 0, function* () { - const novels = []; - const url = baseUrl + "?s=" + searchTerm + "&post_type=wp-manga"; - const body = yield (0, fetch_1.fetchApi)(url).then(res => res.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio('.c-tabs-item__content').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - let novelUrl = loadedCheerio(this) - .find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - }); - return novels; -}); -exports.searchNovels = searchNovels; -const fetchImage = (url) => __awaiter(void 0, void 0, void 0, function* () { - return yield (0, fetch_1.fetchFile)(url); -}); -exports.fetchImage = fetchImage; -exports.filters = [{ "key": "sort", "label": "Sırala", "values": [{ "label": "A-Z", "value": "alphabet" }, { "label": "En Son", "value": "latest" }, { "label": "Görüntülenme", "value": "views" }, { "label": "Popülarite", "value": "trending" }, { "label": "Reyting", "value": "rating" }, { "label": "Yeni", "value": "new-manga" }], "inputType": filterInputs_1.FilterInputs.Picker }]; diff --git a/js/plugins/turkish/epiknovel.js b/js/plugins/turkish/epiknovel.js deleted file mode 100644 index a80159c..0000000 --- a/js/plugins/turkish/epiknovel.js +++ /dev/null @@ -1,142 +0,0 @@ -"use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.fetchImage = exports.searchNovels = exports.parseChapter = exports.parseNovelAndChapters = exports.popularNovels = exports.icon = exports.version = exports.site = exports.name = exports.id = void 0; -const cheerio_1 = require("cheerio"); -const fetch_1 = require("@libs/fetch"); -exports.id = "epiknovel.com"; -exports.name = "EpikNovel"; -exports.site = "https://www.epiknovel.com/"; -exports.version = "1.0.0"; -exports.icon = "src/tr/epiknovel/icon.png"; -const baseUrl = exports.site; -const popularNovels = function (page) { - return __awaiter(this, void 0, void 0, function* () { - let url = baseUrl + "seri-listesi?Sayfa=" + page; - const result = yield (0, fetch_1.fetchApi)(url); - const body = yield result.text(); - let loadedCheerio = (0, cheerio_1.load)(body); - let novels = []; - loadedCheerio("div.col-lg-12.col-md-12").each(function () { - const novelName = loadedCheerio(this).find("h3").text(); - const novelCover = loadedCheerio(this).find("img").attr("data-src"); - const novelUrl = loadedCheerio(this).find("h3 > a").attr("href"); - if (!novelUrl) - return; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - }); - // console.log(novels); - return novels; - }); -}; -exports.popularNovels = popularNovels; -const parseNovelAndChapters = function (novelUrl) { - return __awaiter(this, void 0, void 0, function* () { - const url = novelUrl; - // console.log(url); - const result = yield (0, fetch_1.fetchApi)(url); - const body = yield result.text(); - let loadedCheerio = (0, cheerio_1.load)(body); - let novel = { url }; - novel.name = loadedCheerio("h1#tables").text().trim(); - novel.cover = loadedCheerio("img.manga-cover").attr("src"); - novel.summary = loadedCheerio("#wrapper > div.row > div.col-md-9 > div:nth-child(6) > p:nth-child(3)") - .text() - .trim(); - novel.status = loadedCheerio("#wrapper > div.row > div.col-md-9 > div.row > div.col-md-9 > h4:nth-child(3) > a") - .text() - .trim(); - novel.author = loadedCheerio("#NovelInfo > p:nth-child(4)") - .text() - .replace(/Publisher:|\s/g, "") - .trim(); - let novelChapters = []; - loadedCheerio("table").find("tr").first().remove(); - loadedCheerio("table") - .find("tr") - .each(function () { - const releaseDate = loadedCheerio(this) - .find("td:nth-child(3)") - .text(); - let chapterName = loadedCheerio(this) - .find("td:nth-child(1) > a") - .text(); - if (loadedCheerio(this).find("td:nth-child(1) > span").length > - 0) { - chapterName = "🔒 " + chapterName; - } - const chapterUrl = loadedCheerio(this) - .find(" td:nth-child(1) > a") - .attr("href"); - if (!chapterUrl) - return; - novelChapters.push({ - name: chapterName, - url: chapterUrl, - releaseTime: releaseDate, - }); - }); - novel.chapters = novelChapters; - // console.log(novel); - return novel; - }); -}; -exports.parseNovelAndChapters = parseNovelAndChapters; -const parseChapter = function (chapterUrl) { - return __awaiter(this, void 0, void 0, function* () { - const url = chapterUrl; - // console.log(url); - const result = yield (0, fetch_1.fetchApi)(url); - const body = yield result.text(); - let loadedCheerio = (0, cheerio_1.load)(body); - let chapterName, chapterText; - if (result.url === "https://www.epiknovel.com/login") { - chapterName = ""; - chapterText = "Premium Chapter"; - } - else { - chapterName = loadedCheerio("#icerik > center > h4 > b").text(); - chapterText = loadedCheerio("div#icerik").html(); - } - return chapterText; - }); -}; -exports.parseChapter = parseChapter; -const searchNovels = function (searchTerm) { - return __awaiter(this, void 0, void 0, function* () { - const url = baseUrl + "seri-listesi?q=" + searchTerm; - const result = yield (0, fetch_1.fetchApi)(url); - const body = yield result.text(); - let loadedCheerio = (0, cheerio_1.load)(body); - let novels = []; - loadedCheerio("div.col-lg-12.col-md-12").each(function () { - const novelName = loadedCheerio(this).find("h3").text(); - const novelCover = loadedCheerio(this).find("img").attr("data-src"); - const novelUrl = loadedCheerio(this).find("h3 > a").attr("href"); - if (!novelUrl) - return; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - }); - return novels; - }); -}; -exports.searchNovels = searchNovels; -exports.fetchImage = fetch_1.fetchFile; diff --git a/js/plugins/turkish/lshnovel.js b/js/plugins/turkish/lshnovel.js deleted file mode 100644 index 4e3eeec..0000000 --- a/js/plugins/turkish/lshnovel.js +++ /dev/null @@ -1,247 +0,0 @@ -"use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.filters = exports.fetchImage = exports.searchNovels = exports.parseChapter = exports.parseNovelAndChapters = exports.popularNovels = exports.site = exports.icon = exports.version = exports.name = exports.id = void 0; -const cheerio_1 = require("cheerio"); -const fetch_1 = require("@libs/fetch"); -const filterInputs_1 = require("@libs/filterInputs"); -exports.id = "lshnovel"; -exports.name = "Liebe Schnee Hiver Novel"; -exports.version = "1.0.0"; -exports.icon = "multisrc/wpmangastream/icons/lshnovel.png"; -exports.site = "https://lshnovel.com/"; -const pluginId = exports.id; -const baseUrl = exports.site; -const popularNovels = function (page, { filters }) { - return __awaiter(this, void 0, void 0, function* () { - let link = `${baseUrl}series/?page=${page}`; - if (filters) { - if (Array.isArray(filters.genres) && filters.genres.length) { - link += filters.genres.map((i) => `&genre[]=${i}`).join(""); - } - if (Array.isArray(filters.type) && filters.type.length) { - link += filters.type.map((i) => `&lang[]=${i}`).join(""); - } - } - link += "&status=" + ((filters === null || filters === void 0 ? void 0 : filters.status) ? filters === null || filters === void 0 ? void 0 : filters.status : ""); - link += "&order=" + ((filters === null || filters === void 0 ? void 0 : filters.order) ? filters === null || filters === void 0 ? void 0 : filters.order : "popular"); - const body = yield (0, fetch_1.fetchApi)(link, {}, pluginId).then((result) => result.text()); - const loadedCheerio = (0, cheerio_1.load)(body); - const novels = []; - loadedCheerio("article.bs").each(function () { - const novelName = loadedCheerio(this).find(".ntitle").text().trim(); - let image = loadedCheerio(this).find("img"); - const novelCover = image.attr("data-src") || image.attr("src"); - const novelUrl = loadedCheerio(this).find("a").attr("href"); - if (!novelUrl) - return; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - novels.push(novel); - }); - return novels; - }); -}; -exports.popularNovels = popularNovels; -const parseNovelAndChapters = function (novelUrl) { - return __awaiter(this, void 0, void 0, function* () { - const url = novelUrl; - const result = yield (0, fetch_1.fetchApi)(url, {}, pluginId); - const body = yield result.text(); - let loadedCheerio = (0, cheerio_1.load)(body); - const novel = { - url, - chapters: [], - }; - novel.name = loadedCheerio(".entry-title").text(); - novel.cover = - loadedCheerio("img.wp-post-image").attr("data-src") || - loadedCheerio("img.wp-post-image").attr("src"); - loadedCheerio("div.spe > span").each(function () { - const detailName = loadedCheerio(this).find("b").text().trim(); - const detail = loadedCheerio(this) - .find("b") - .remove() - .end() - .text() - .trim(); - switch (detailName) { - case "المؤلف:": - case "Yazar:": - case "Autor:": - case "Author:": - novel.author = detail; - break; - case "Status:": - case "Seviye:": - novel.status = detail; - break; - } - }); - novel.genres = loadedCheerio(".genxed") - .text() - .trim() - .replace(/\s/g, ","); - loadedCheerio('div[itemprop="description"] h3,p.a,strong').remove(); - novel.summary = loadedCheerio('div[itemprop="description"]') - .find("br") - .replaceWith("\n") - .end() - .text(); - let chapter = []; - loadedCheerio(".eplister") - .find("li") - .each(function () { - const chapterName = loadedCheerio(this).find(".epl-num").text() + - " - " + - loadedCheerio(this).find(".epl-title").text(); - const releaseDate = loadedCheerio(this) - .find(".epl-date") - .text() - .trim(); - const chapterUrl = loadedCheerio(this).find("a").attr("href"); - if (!chapterUrl) - return; - chapter.push({ - name: chapterName, - releaseTime: releaseDate, - url: chapterUrl, - }); - }); - novel.chapters = chapter.reverse(); - return novel; - }); -}; -exports.parseNovelAndChapters = parseNovelAndChapters; -const parseChapter = function (chapterUrl) { - return __awaiter(this, void 0, void 0, function* () { - const result = yield (0, fetch_1.fetchApi)(chapterUrl, {}, pluginId); - const body = yield result.text(); - const loadedCheerio = (0, cheerio_1.load)(body); - let chapterText = loadedCheerio("div.epcontent").html(); - return chapterText; - }); -}; -exports.parseChapter = parseChapter; -const searchNovels = function (searchTerm) { - return __awaiter(this, void 0, void 0, function* () { - const url = `${baseUrl}?s=${searchTerm}`; - const result = yield (0, fetch_1.fetchApi)(url, {}, pluginId); - const body = yield result.text(); - const loadedCheerio = (0, cheerio_1.load)(body); - const novels = []; - loadedCheerio("article.bs").each(function () { - const novelName = loadedCheerio(this).find(".ntitle").text().trim(); - const novelCover = loadedCheerio(this).find("img").attr("src"); - const novelUrl = loadedCheerio(this).find("a").attr("href"); - if (!novelUrl) - return; - novels.push({ - name: novelName, - url: novelUrl, - cover: novelCover, - }); - }); - return novels; - }); -}; -exports.searchNovels = searchNovels; -const fetchImage = function (url) { - return __awaiter(this, void 0, void 0, function* () { - const headers = { - Referer: baseUrl, - }; - return yield (0, fetch_1.fetchFile)(url, { headers: headers }); - }); -}; -exports.fetchImage = fetchImage; -exports.filters = [ - { - key: "order", - label: "Önerilen", - values: [ - { label: "Varsayılan", value: "" }, - { label: "A-Z", value: "title" }, - { label: "Z-A", value: "titlereverse" }, - { label: "Son Yüklemeler", value: "update" }, - { label: "Son Eklenenler", value: "latest" }, - { label: "Bestimiz", value: "popular" }, - ], - inputType: filterInputs_1.FilterInputs.Picker, - }, - { - key: "status", - label: "Statü", - values: [ - { label: "Tümü", value: "" }, - { label: "Ongoing", value: "ongoing" }, - { label: "Hiatus", value: "hiatus" }, - { label: "Completed", value: "completed" }, - ], - inputType: filterInputs_1.FilterInputs.Picker, - }, - { - key: "type", - label: "Tür", - values: [ - { label: "Çeviri Novel", value: "ceviri-novel" }, - { label: "Liz-Chan", value: "liz-chan" }, - { label: "Manhwa", value: "manhwa" }, - { label: "Orijinal Novel", value: "orijinal-novel" }, - { label: "Web Novel", value: "web-novel" }, - ], - inputType: filterInputs_1.FilterInputs.Checkbox, - }, - { - key: "genres", - label: "Kategori", - values: [ - { label: "+18", value: "18" }, - { label: "Action", value: "action" }, - { label: "Adult", value: "adult" }, - { label: "Aksiyon", value: "aksiyon" }, - { label: "BL", value: "bl" }, - { label: "Comedy", value: "comedy" }, - { label: "Doğaüstü", value: "dogaustu" }, - { label: "Dram", value: "dram" }, - { label: "Drama", value: "drama" }, - { label: "Ecchi", value: "ecchi" }, - { label: "Fantastik", value: "fantastik" }, - { label: "Fantasy", value: "fantasy" }, - { label: "Gizem", value: "gizem" }, - { label: "Harem", value: "harem" }, - { label: "Historical", value: "historical" }, - { label: "Josei", value: "josei" }, - { label: "Macera", value: "macera" }, - { label: "Manhwa", value: "manhwa" }, - { label: "Martial Arts", value: "martial-arts" }, - { label: "Mature", value: "mature" }, - { label: "Novel", value: "novel" }, - { label: "Okul", value: "okul" }, - { label: "Psikolojik", value: "psikolojik" }, - { label: "Psychological", value: "psychological" }, - { label: "Reverse Harem", value: "reverse-harem" }, - { label: "Romance", value: "romance" }, - { label: "Romantik", value: "romantik" }, - { label: "Shoujo", value: "shoujo" }, - { label: "Slice Of Life", value: "slice-of-life" }, - { label: "Smut", value: "smut" }, - { label: "Supernatural", value: "supernatural" }, - { label: "Tarihi", value: "tarihi" }, - { label: "Tragedy", value: "tragedy" }, - { label: "Yaoi", value: "yaoi" }, - ], - inputType: filterInputs_1.FilterInputs.Checkbox, - }, -]; diff --git a/js/plugins/ukraine/smakolykytl.js b/js/plugins/ukraine/smakolykytl.js deleted file mode 100644 index fc95ecf..0000000 --- a/js/plugins/ukraine/smakolykytl.js +++ /dev/null @@ -1,139 +0,0 @@ -"use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.fetchImage = exports.searchNovels = exports.parseChapter = exports.parseNovelAndChapters = exports.popularNovels = exports.icon = exports.version = exports.site = exports.name = exports.id = void 0; -const fetch_1 = require("@libs/fetch"); -const novelStatus_1 = require("@libs/novelStatus"); -const dayjs_1 = __importDefault(require("dayjs")); -exports.id = "smakolykytl"; -exports.name = "Смаколики"; -exports.site = "https://smakolykytl.site/"; -exports.version = "1.0.0"; -exports.icon = "src/ua/smakolykytl/icon.png"; -const popularNovels = function (page, { showLatestNovels }) { - var _a; - return __awaiter(this, void 0, void 0, function* () { - const url = showLatestNovels - ? "https://api.smakolykytl.site/api/user/updates" - : "https://api.smakolykytl.site/api/user/projects"; - const result = yield (0, fetch_1.fetchApi)(url); - const json = (yield result.json()); - let novels = []; - (_a = ((json === null || json === void 0 ? void 0 : json.projects) || (json === null || json === void 0 ? void 0 : json.updates))) === null || _a === void 0 ? void 0 : _a.forEach((novel) => novels.push({ - name: novel.title, - cover: novel.image.url, - url: exports.site + "titles/" + novel.id, - })); - return novels; - }); -}; -exports.popularNovels = popularNovels; -const parseNovelAndChapters = function (novelUrl) { - var _a, _b, _c, _d, _e, _f, _g, _h, _j; - return __awaiter(this, void 0, void 0, function* () { - const id = novelUrl.split("/").pop(); - const result = yield (0, fetch_1.fetchApi)("https://api.smakolykytl.site/api/user/projects/" + id); - const book = (yield result.json()); - let novel = { - url: novelUrl, - name: (_a = book === null || book === void 0 ? void 0 : book.project) === null || _a === void 0 ? void 0 : _a.title, - cover: (_c = (_b = book === null || book === void 0 ? void 0 : book.project) === null || _b === void 0 ? void 0 : _b.image) === null || _c === void 0 ? void 0 : _c.url, - summary: (_d = book === null || book === void 0 ? void 0 : book.project) === null || _d === void 0 ? void 0 : _d.description, - author: (_e = book === null || book === void 0 ? void 0 : book.project) === null || _e === void 0 ? void 0 : _e.author, - status: ((_f = book === null || book === void 0 ? void 0 : book.project) === null || _f === void 0 ? void 0 : _f.status_translate.includes("Триває")) - ? novelStatus_1.NovelStatus.Ongoing - : novelStatus_1.NovelStatus.Completed, - }; - let tags = [(_g = book === null || book === void 0 ? void 0 : book.project) === null || _g === void 0 ? void 0 : _g.genres, (_h = book === null || book === void 0 ? void 0 : book.project) === null || _h === void 0 ? void 0 : _h.tags] - .flat() - .map((tags) => tags === null || tags === void 0 ? void 0 : tags.title) - .filter((tags) => tags); - if (tags.length > 0) { - novel.genres = tags.join(", "); - } - let chapters = []; - const res = yield (0, fetch_1.fetchApi)("https://api.smakolykytl.site/api/user/projects/" + id + "/books"); - const data = (yield res.json()); - (_j = data === null || data === void 0 ? void 0 : data.books) === null || _j === void 0 ? void 0 : _j.forEach((volume) => { - var _a; - return (_a = volume === null || volume === void 0 ? void 0 : volume.chapters) === null || _a === void 0 ? void 0 : _a.map((chapter) => chapters.push({ - name: volume.title + " " + chapter.title, - releaseTime: (0, dayjs_1.default)(chapter.modifiedAt).format("LLL"), - url: exports.site + "read/" + chapter.id, - })); - }); - novel.chapters = chapters; - return novel; - }); -}; -exports.parseNovelAndChapters = parseNovelAndChapters; -const parseChapter = function (chapterUrl) { - var _a; - return __awaiter(this, void 0, void 0, function* () { - const id = chapterUrl.split("/").pop(); - const result = yield (0, fetch_1.fetchApi)("https://api.smakolykytl.site/api/user/chapters/" + id); - const json = (yield result.json()); - const chapterRaw = JSON.parse(((_a = json === null || json === void 0 ? void 0 : json.chapter) === null || _a === void 0 ? void 0 : _a.content) || "{}"); - const chapterText = jsonToHtml(chapterRaw); - return chapterText; - }); -}; -exports.parseChapter = parseChapter; -const searchNovels = function (searchTerm) { - var _a, _b; - return __awaiter(this, void 0, void 0, function* () { - const result = yield (0, fetch_1.fetchApi)("https://api.smakolykytl.site/api/user/projects"); - const json = (yield result.json()); - let novels = []; - (_b = (_a = json === null || json === void 0 ? void 0 : json.projects) === null || _a === void 0 ? void 0 : _a.filter((novel) => novel.title.includes(searchTerm) || String(novel.id) === searchTerm)) === null || _b === void 0 ? void 0 : _b.forEach((novel) => novels.push({ - name: novel.title, - cover: novel.image.url, - url: exports.site + "titles/" + novel.id, - })); - return novels; - }); -}; -exports.searchNovels = searchNovels; -exports.fetchImage = fetch_1.fetchFile; -function jsonToHtml(json, html = "") { - json.forEach((element) => { - switch (element.type) { - case "hardBreak": - html += "
"; - break; - case "horizontalRule": - html += "
"; - break; - case "image": - if (element.attrs) { - const attrs = Object.entries(element.attrs) - .filter((attr) => attr === null || attr === void 0 ? void 0 : attr[1]) - .map((attr) => `${attr[0]}="${attr[1]}"`); - html += ""; - } - break; - case "paragraph": - html += - "

" + (element.content ? jsonToHtml(element.content) : "
") + "

"; - break; - case "text": - html += element.text; - break; - default: - html += JSON.stringify(element, null, "\t"); //maybe I missed something. - break; - } - }); - return html; -} diff --git a/js/plugins/vietnamese/LNHako.js b/js/plugins/vietnamese/LNHako.js deleted file mode 100644 index 668d1e7..0000000 --- a/js/plugins/vietnamese/LNHako.js +++ /dev/null @@ -1,162 +0,0 @@ -"use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.fetchImage = exports.searchNovels = exports.parseChapter = exports.parseNovelAndChapters = exports.popularNovels = exports.site = exports.version = exports.icon = exports.name = exports.id = void 0; -const cheerio_1 = require("cheerio"); -const fetch_1 = require("@libs/fetch"); -// import dayjs from "dayjs"; -// import { FilterInputs } from "@libs/filterInputs"; -// import { NovelStatus } from "@libs/novelStatus"; -const isAbsoluteUrl_1 = require("@libs/isAbsoluteUrl"); -// import { parseMadaraDate } from "@libs/parseMadaraDate"; -const pluginId = "ln.hako"; -const baseUrl = "https://ln.hako.vn"; -exports.id = pluginId; // string and must be unique -exports.name = "Hako"; -exports.icon = "src/vi/hakolightnovel/icon.png"; // The relative path to the icon without @icons . For example: 'src/vi/hakolightnovel/icon.png' -exports.version = "1.0.0"; // xx.xx.xx -exports.site = baseUrl; // the link to the site -const popularNovels = (pageNo) => __awaiter(void 0, void 0, void 0, function* () { - const novels = []; - const link = baseUrl + "/danh-sach?truyendich=1&sapxep=topthang&page=" + pageNo; - const result = yield (0, fetch_1.fetchApi)(link); - const body = yield result.text(); - const loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio("main.row > .thumb-item-flow").each(function () { - let url = loadedCheerio(this) - .find("div.thumb_attr.series-title > a") - .attr("href"); - if (url && !(0, isAbsoluteUrl_1.isUrlAbsolute)(url)) { - url = baseUrl + url; - } - if (url) { - const name = loadedCheerio(this) - .find(".series-title") - .text() - .trim(); - let cover = loadedCheerio(this) - .find(".img-in-ratio") - .attr("data-bg"); - if (cover && !(0, isAbsoluteUrl_1.isUrlAbsolute)(cover)) { - cover = baseUrl + cover; - } - const novel = { - name, - url, - cover, - }; - novels.push(novel); - } - }); - return novels; -}); -exports.popularNovels = popularNovels; -const parseNovelAndChapters = (novelUrl) => __awaiter(void 0, void 0, void 0, function* () { - const novel = { - url: novelUrl, - }; - const result = yield (0, fetch_1.fetchApi)(novelUrl); - const body = yield result.text(); - let loadedCheerio = (0, cheerio_1.load)(body); - novel.name = loadedCheerio(".series-name").text(); - const background = loadedCheerio(".series-cover > .a6-ratio > div").attr("style") || ""; - const novelCover = background.substring(background.indexOf("http"), background.length - 2); - novel.cover = novelCover - ? (0, isAbsoluteUrl_1.isUrlAbsolute)(novelCover) - ? novelCover - : baseUrl + novelCover - : ""; - novel.summary = loadedCheerio(".summary-content").text().trim(); - novel.author = loadedCheerio("#mainpart > div:nth-child(2) > div > div:nth-child(1) > section > main > div.top-part > div > div.col-12.col-md-9 > div.series-information > div:nth-child(2) > span.info-value > a") - .text() - .trim(); - novel.genres = loadedCheerio(".series-gernes") - .text() - .trim() - .replace(/ +/g, " ") - .split("\n") - .filter((e) => e.trim()) - .join(", "); - novel.status = loadedCheerio("#mainpart > div:nth-child(2) > div > div:nth-child(1) > section > main > div.top-part > div > div.col-12.col-md-9 > div.series-information > div:nth-child(4) > span.info-value > a") - .text() - .trim(); - const chapters = []; - loadedCheerio(".list-chapters li").each(function () { - let chapterUrl = loadedCheerio(this).find("a").attr("href"); - if (chapterUrl && !(0, isAbsoluteUrl_1.isUrlAbsolute)(chapterUrl)) { - chapterUrl = baseUrl + chapterUrl; - } - if (chapterUrl) { - const chapterName = loadedCheerio(this) - .find(".chapter-name") - .text() - .trim(); - const releaseTime = loadedCheerio(this) - .find(".chapter-time") - .text(); - const chapter = { - name: chapterName, - releaseTime: releaseTime, - url: chapterUrl, - }; - chapters.push(chapter); - } - }); - novel.chapters = chapters; - return novel; -}); -exports.parseNovelAndChapters = parseNovelAndChapters; -const parseChapter = (chapterUrl) => __awaiter(void 0, void 0, void 0, function* () { - const result = yield (0, fetch_1.fetchApi)(chapterUrl); - const body = yield result.text(); - const loadedCheerio = (0, cheerio_1.load)(body); - const chapterText = loadedCheerio("#chapter-content").html() || ""; - return chapterText; -}); -exports.parseChapter = parseChapter; -const searchNovels = (searchTerm) => __awaiter(void 0, void 0, void 0, function* () { - const novels = []; - const url = baseUrl + "/tim-kiem?keywords=" + searchTerm; - const result = yield (0, fetch_1.fetchApi)(url); - const body = yield result.text(); - const loadedCheerio = (0, cheerio_1.load)(body); - loadedCheerio("div.row > .thumb-item-flow").each(function () { - let novelUrl = loadedCheerio(this) - .find("div.thumb_attr.series-title > a") - .attr("href"); - if (novelUrl && !(0, isAbsoluteUrl_1.isUrlAbsolute)(novelUrl)) { - novelUrl = baseUrl + novelUrl; - } - if (novelUrl) { - const novelName = loadedCheerio(this).find(".series-title").text(); - let novelCover = loadedCheerio(this) - .find(".img-in-ratio") - .attr("data-bg"); - if (novelCover && !(0, isAbsoluteUrl_1.isUrlAbsolute)(novelCover)) { - novelCover = baseUrl + novelCover; - } - novels.push({ - name: novelName, - url: novelUrl, - cover: novelCover, - }); - } - }); - return novels; -}); -exports.searchNovels = searchNovels; -const fetchImage = (url) => __awaiter(void 0, void 0, void 0, function* () { - const headers = { - Referer: "https://ln.hako.vn", - }; - return yield (0, fetch_1.fetchFile)(url, { headers: headers }); -}); -exports.fetchImage = fetchImage; diff --git a/libs/fetch.ts b/libs/fetch.ts index 39282ce..b740b0b 100644 --- a/libs/fetch.ts +++ b/libs/fetch.ts @@ -1,26 +1,18 @@ -import { Plugin } from "@typings/plugin"; -import { NodeFetchParams, getNodeFetch } from "./nodeFetch"; - -const fetch = async (...args: NodeFetchParams) => - (await getNodeFetch())(...args); - const defaultUserAgentString = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36"; export async function fetchApi( url: string, - init?: NodeFetchParams[1], - pluginId?: string + init?: RequestInit, ) { const headers = { "User-Agent": defaultUserAgentString, ...init?.headers, }; - if (pluginId) console.log("Enable CloudFlare cookie for", pluginId); return await fetch(url, { ...init, headers }); } -export const fetchFile: Plugin.fetchImage = async function (url, init) { +export const fetchFile = async function (url: string, init?: RequestInit) { if (!init) init = {}; try { const res = await fetch(url, init); diff --git a/libs/filterInputs.ts b/libs/filterInputs.ts index 2327a77..7077d5f 100644 --- a/libs/filterInputs.ts +++ b/libs/filterInputs.ts @@ -2,6 +2,7 @@ export interface FilterValue { label: string; value: string | number; } + export enum FilterInputs { TextInput, Picker, @@ -11,5 +12,5 @@ export interface Filter { key: string; label: string; values: FilterValue[]; - inputType: FilterInputs; + inputType: FilterInputs | string; } diff --git a/libs/nodeFetch.ts b/libs/nodeFetch.ts deleted file mode 100644 index d815177..0000000 --- a/libs/nodeFetch.ts +++ /dev/null @@ -1,9 +0,0 @@ -const nodeFetch = import("node-fetch"); - -export type NodeFetchFunction = Awaited["default"]; - -export type NodeFetchParams = Parameters; - -export const getNodeFetch = async (): Promise => { - return (await nodeFetch).default; -}; diff --git a/nodemon.json b/nodemon.json index 879d47a..533f64e 100644 --- a/nodemon.json +++ b/nodemon.json @@ -1,5 +1,5 @@ { "ext": "js,mjs,json,ts", - "ignore": ["js/**"], - "exec": "tsc && node ./js/index.js" + "ignore": [".js/**", "test_web/**"], + "exec": "tsc && node ./.js/index.js" } \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 3343b8f..27abe72 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,7 +15,6 @@ "dayjs": "^1.11.4", "express": "^4.18.2", "module-alias": "^2.2.2", - "node-fetch": "^3", "ts-node": "^10.9.1", "tsc-alias": "^1.8.6", "typescript": "^5.1.3" @@ -562,14 +561,6 @@ "type": "^1.0.1" } }, - "node_modules/data-uri-to-buffer": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", - "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==", - "engines": { - "node": ">= 12" - } - }, "node_modules/dayjs": { "version": "1.11.4", "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.4.tgz", @@ -888,28 +879,6 @@ "reusify": "^1.0.4" } }, - "node_modules/fetch-blob": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz", - "integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/jimmywarting" - }, - { - "type": "paypal", - "url": "https://paypal.me/jimmywarting" - } - ], - "dependencies": { - "node-domexception": "^1.0.0", - "web-streams-polyfill": "^3.0.3" - }, - "engines": { - "node": "^12.20 || >= 14.13" - } - }, "node_modules/fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", @@ -951,17 +920,6 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, - "node_modules/formdata-polyfill": { - "version": "4.0.10", - "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", - "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==", - "dependencies": { - "fetch-blob": "^3.1.2" - }, - "engines": { - "node": ">=12.20.0" - } - }, "node_modules/forwarded": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", @@ -1352,41 +1310,6 @@ "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz", "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==" }, - "node_modules/node-domexception": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", - "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/jimmywarting" - }, - { - "type": "github", - "url": "https://paypal.me/jimmywarting" - } - ], - "engines": { - "node": ">=10.5.0" - } - }, - "node_modules/node-fetch": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.1.tgz", - "integrity": "sha512-cRVc/kyto/7E5shrWca1Wsea4y6tL9iYJE5FBCius3JQfb/4P4I295PfhgbJQBLTx6lATE4z+wK0rPM4VS2uow==", - "dependencies": { - "data-uri-to-buffer": "^4.0.0", - "fetch-blob": "^3.1.4", - "formdata-polyfill": "^4.0.10" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/node-fetch" - } - }, "node_modules/nodemon": { "version": "2.0.22", "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.22.tgz", @@ -2076,14 +1999,6 @@ "node": ">= 0.8" } }, - "node_modules/web-streams-polyfill": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.2.1.tgz", - "integrity": "sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q==", - "engines": { - "node": ">= 8" - } - }, "node_modules/which": { "version": "1.2.14", "resolved": "https://registry.npmjs.org/which/-/which-1.2.14.tgz", @@ -2553,11 +2468,6 @@ "type": "^1.0.1" } }, - "data-uri-to-buffer": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", - "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==" - }, "dayjs": { "version": "1.11.4", "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.4.tgz", @@ -2820,15 +2730,6 @@ "reusify": "^1.0.4" } }, - "fetch-blob": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz", - "integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==", - "requires": { - "node-domexception": "^1.0.0", - "web-streams-polyfill": "^3.0.3" - } - }, "fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", @@ -2866,14 +2767,6 @@ } } }, - "formdata-polyfill": { - "version": "4.0.10", - "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", - "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==", - "requires": { - "fetch-blob": "^3.1.2" - } - }, "forwarded": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", @@ -3159,21 +3052,6 @@ "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz", "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==" }, - "node-domexception": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", - "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==" - }, - "node-fetch": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.1.tgz", - "integrity": "sha512-cRVc/kyto/7E5shrWca1Wsea4y6tL9iYJE5FBCius3JQfb/4P4I295PfhgbJQBLTx6lATE4z+wK0rPM4VS2uow==", - "requires": { - "data-uri-to-buffer": "^4.0.0", - "fetch-blob": "^3.1.4", - "formdata-polyfill": "^4.0.10" - } - }, "nodemon": { "version": "2.0.22", "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.22.tgz", @@ -3672,11 +3550,6 @@ "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==" }, - "web-streams-polyfill": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.2.1.tgz", - "integrity": "sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q==" - }, "which": { "version": "1.2.14", "resolved": "https://registry.npmjs.org/which/-/which-1.2.14.tgz", diff --git a/package.json b/package.json index 50110ef..1b200fb 100644 --- a/package.json +++ b/package.json @@ -6,8 +6,9 @@ "scripts": { "start": "nodemon", "test": "exit 0", - "json": "tsc && node ./js/scripts/json_plugins.js && git add plugins && git add dist && git add js/plugins", - "generate": "ts-node ./scripts/multisrc/generate.ts" + "json": "tsc && node ./.js/scripts/json_plugins.js && git add plugins && git add .dist && git add .js/plugins", + "generate": "ts-node ./scripts/multisrc/generate.ts", + "clearMulti": "ts-node ./scripts/clearMultisrc.ts" }, "author": "", "license": "MIT", @@ -18,17 +19,16 @@ "dayjs": "^1.11.4", "express": "^4.18.2", "module-alias": "^2.2.2", - "node-fetch": "^3", "ts-node": "^10.9.1", "tsc-alias": "^1.8.6", "typescript": "^5.1.3" }, "_moduleAliases": { - "@libs": "./js/libs", - "@icons": "./js/icons", - "@plugins": "./js/plugins", - "@scripts": "./js/scripts", - "@typings": "./js/types" + "@libs": "./.js/libs", + "@icons": "./.js/icons", + "@plugins": "./.js/plugins", + "@scripts": "./.js/scripts", + "@typings": "./.js/types" }, "devDependencies": { "@types/express": "^4.17.17", diff --git a/plugins/arabic/ArMTL[madara].ts b/plugins/arabic/ArMTL[madara].ts index 6d2ed5e..10066af 100644 --- a/plugins/arabic/ArMTL[madara].ts +++ b/plugins/arabic/ArMTL[madara].ts @@ -1,213 +1,252 @@ +import { fetchApi, fetchFile } from "@libs/fetch"; +import { Filter } from "@libs/filterInputs"; +import { Plugin } from '@typings/plugin' import { load as parseHTML } from "cheerio"; -import { fetchFile, fetchApi } from "@libs/fetch"; -import { Novel, Plugin, Chapter } from "@typings/plugin"; -import { FilterInputs } from "@libs/filterInputs"; import { defaultCover } from "@libs/defaultCover"; -import { NovelStatus } from "@libs/novelStatus" +import { NovelStatus } from "@libs/novelStatus"; import { parseMadaraDate } from "@libs/parseMadaraDate"; import dayjs from "dayjs"; -export const id = "ar-mtl"; -export const name = "ArMTL [madara]"; -export const icon = "multisrc/madara/icons/armtl.png"; -export const version = "1.0.0"; -export const site = "https://ar-mtl.club/"; -const baseUrl = site; +interface MadaraOptionPath{ + genres?: string, + novels?: string, + novel?: string, + chapter?: string, +} -export const popularNovels: Plugin.popularNovels = async (pageNo, {filters, showLatestNovels}) => { - const novels: Novel.Item[] = []; +const MadaraDefaultPath: MadaraOptionPath = { + novels: 'novel', + novel: 'novel', + chapter: 'novel' +} - let url = site; +interface MadaraOptions { + useNewChapterEndpoint?: boolean, + path?: MadaraOptionPath, + lang?: string, + orderBy?: string +} - if (filters?.genres) { - url += "novel-genre/" + filters.genres + '/'; - } else { - url += "novel/"; +export interface MadaraMetadata { + id: string, + sourceSite: string, + sourceName: string, + options?: MadaraOptions, + filters?: Filter[], +} +class MadaraPlugin implements Plugin.PluginBase { + id: string; + name: string; + icon: string; + site: string; + version: string; + userAgent: string; + cookieString: string; + options?: MadaraOptions; + filter?: Filter[] | undefined; + + constructor(metadata: MadaraMetadata){ + this.id = metadata.id; + this.name = metadata.sourceName + "[madara]"; + const iconFileName = metadata.sourceName.replace(/\s+/g, "").toLowerCase(); + this.icon = `multisrc/madara/icons/${iconFileName}.png`; + this.site = metadata.sourceSite; + this.version = "1.0.0"; + this.userAgent = ""; + this.cookieString = ""; + this.options = metadata.options; + this.filter = metadata.filters; } + async popularNovels(pageNo: number, {filters, showLatestNovels}: Plugin.PopularNovelsOptions): Promise { + const novels: Plugin.NovelItem[] = []; - url += '/page/' + pageNo + '/' + - '?m_orderby=' + (showLatestNovels ? 'latest' : (filters?.sort || 'rating')); - - const body = await fetchApi(url).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - - loadedCheerio('.manga-title-badges').remove(); - - loadedCheerio('.page-item-detail').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - - let novelUrl = loadedCheerio(this).find('.post-title') - .find('a') - .attr('href') || ''; - const novel: Novel.Item = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - - novels.push(novel); - }); - - return novels; -}; - -export const parseNovelAndChapters: Plugin.parseNovelAndChapters = async ( - novelUrl -) => { - const novel: Novel.instance = { - url: novelUrl, - }; - - const body = await fetchApi(novelUrl).then(res => res.text()); - - let loadedCheerio = parseHTML(body); - - loadedCheerio('.manga-title-badges').remove(); - - novel.name = loadedCheerio('.post-title h1').text().trim(); - - novel.cover = - loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || - loadedCheerio('.summary_image > a > img').attr('data-src') || - loadedCheerio('.summary_image > a > img').attr('src') || - defaultCover; - - loadedCheerio('.post-content_item, .post-content').each(function () { - const detailName = loadedCheerio(this).find('h5').text().trim(); - const detail = loadedCheerio(this).find('.summary-content').text().trim(); - - switch (detailName) { - case 'Genre(s)': - case 'التصنيفات': - novel.genres = detail.replace(/[\t\n]/g, ','); - break; - case 'Author(s)': - case 'المؤلف': - case 'المؤلف (ين)': - novel.author = detail; - break; - case 'Status': - case 'الحالة': - novel.status = - detail.includes('OnGoing') || detail.includes('مستمرة') - ? NovelStatus.Ongoing - : NovelStatus.Completed; - break; - } - }); - - loadedCheerio('div.summary__content .code-block,script').remove(); - novel.summary = loadedCheerio('div.summary__content').text().trim(); - - - let html; - - if (true) { - const novelId = - loadedCheerio('.rating-post-id').attr('value') || - loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; - - const body = { - action: "manga_get_chapters", - manga: novelId, - } - html = await fetchApi( - baseUrl + 'wp-admin/admin-ajax.php', - { - method: 'POST', - body: JSON.stringify(body), - }) - .then(res => res.text()); - } else { - html = await fetchApi( - baseUrl + 'ajax/chapters/', - { method: 'POST' }) - .then(res => res.text()); - } - - if (html !== '0') { - loadedCheerio = parseHTML(html); - } - - const chapters: Chapter.Item[] = []; - loadedCheerio('.wp-manga-chapter').each(function () { - const chapterName = loadedCheerio(this).find('a').text().trim(); - - let releaseDate = null; - releaseDate = loadedCheerio(this) - .find('span.chapter-release-date') - .text() - .trim(); - - if (releaseDate) { - releaseDate = parseMadaraDate(releaseDate); + let url = this.site; + if (filters?.genres && this.options?.path?.genres) { + url += this.options?.path?.genres + filters.genres + '/'; } else { - /** - * Insert current date - */ - - releaseDate = dayjs().format('LL'); + url += this.options?.path?.novels ? this.options.path.novels : MadaraDefaultPath.novels; } + + url += '/page/' + pageNo + '/' + + '?m_orderby=' + (showLatestNovels ? 'latest' : (filters?.sort || 'rating')); + + const body = await fetchApi(url).then(res => res.text()); + + const loadedCheerio = parseHTML(body); + + loadedCheerio('.manga-title-badges').remove(); + + loadedCheerio('.page-item-detail').each(function () { + const novelName = loadedCheerio(this).find('.post-title').text().trim(); + let image = loadedCheerio(this).find('img'); + const novelCover = image.attr('data-src') || image.attr('src'); + + let novelUrl = loadedCheerio(this).find('.post-title') + .find('a') + .attr('href') || ''; + const novel: Plugin.NovelItem = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + + novels.push(novel); + }); + + return novels; + } + async parseNovelAndChapters(novelUrl: string): Promise { + const novel: Plugin.SourceNovel = { + url: novelUrl, + }; + + const body = await fetchApi(novelUrl).then(res => res.text()); + + let loadedCheerio = parseHTML(body); + + loadedCheerio('.manga-title-badges, #manga-title span').remove(); + novel.name = + loadedCheerio('.post-title h1').text().trim() || + loadedCheerio('#manga-title h1').text(); + + novel.cover = + loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || + loadedCheerio('.summary_image > a > img').attr('data-src') || + loadedCheerio('.summary_image > a > img').attr('src') || + defaultCover; + + loadedCheerio('.post-content_item, .post-content').each(function () { + const detailName = loadedCheerio(this).find('h5').text().trim(); + const detail = loadedCheerio(this).find('.summary-content').text().trim(); + + switch (detailName) { + case 'Genre(s)': + case 'التصنيفات': + novel.genres = detail.replace(/[\\t\\n]/g, ','); + break; + case 'Author(s)': + case 'المؤلف': + case 'المؤلف (ين)': + novel.author = detail; + break; + case 'Status': + case 'الحالة': + novel.status = + detail.includes('OnGoing') || detail.includes('مستمرة') + ? NovelStatus.Ongoing + : NovelStatus.Completed; + break; + } + }); + + loadedCheerio('div.summary__content .code-block,script').remove(); + novel.summary = + loadedCheerio('div.summary__content').text().trim() || + loadedCheerio('#tab-manga-about').text().trim() || + loadedCheerio('.post-content_item h5:contains("Summary")').next().text().trim(); + + let html; + + if (this.options?.useNewChapterEndpoint !== true) { + const novelId = + loadedCheerio('.rating-post-id').attr('value') || + loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; + + const formData = new FormData() + formData.append("action", "manga_get_chapters"); + formData.append("manga", novelId); - let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + html = await fetchApi( + this.site + 'wp-admin/admin-ajax.php', + { + method: 'POST', + body: formData, + }) + .then(res => res.text()); + } else { + html = await fetchApi( + novelUrl + 'ajax/chapters/', + { method: 'POST' }) + .then(res => res.text()); + } + + if (html !== '0') { + loadedCheerio = parseHTML(html); + } + + const chapters: Plugin.ChapterItem[] = []; + loadedCheerio('.wp-manga-chapter').each(function () { + const chapterName = loadedCheerio(this).find('a').text().trim(); + + let releaseDate = null; + releaseDate = loadedCheerio(this) + .find('span.chapter-release-date') + .text() + .trim(); + + if (releaseDate) { + releaseDate = parseMadaraDate(releaseDate); + } else { + /** + * Insert current date + */ + + releaseDate = dayjs().format('LL'); + } + + let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + + chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); + }); + + novel.chapters = chapters.reverse(); + return novel; + } + async parseChapter(chapterUrl: string): Promise { + const body = await fetchApi(chapterUrl).then(res => res.text()); - chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); - }); + const loadedCheerio = parseHTML(body); + const chapterText = + loadedCheerio('.text-left').html() || + loadedCheerio('.text-right').html() || + loadedCheerio('.entry-content').html() || ""; - novel.chapters = chapters.reverse(); - return novel; -}; - -export const parseChapter: Plugin.parseChapter = async (chapterUrl) => { - const url = baseUrl + "/" + "novel" + "/" + chapterUrl; - - const body = await fetchApi(chapterUrl).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - const chapterText = - loadedCheerio('.text-left').html() || - loadedCheerio('.text-right').html() || - loadedCheerio('.entry-content').html(); - - return chapterText; -}; - -export const searchNovels: Plugin.searchNovels = async (searchTerm) => { - const novels: Novel.Item[] = []; - const url = baseUrl + "?s=" + searchTerm + "&post_type=wp-manga"; - - const body = await fetchApi(url).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - - - loadedCheerio('.c-tabs-item__content').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - - let novelUrl = loadedCheerio(this) - .find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - - novels.push(novel); - }); - return novels; -}; - -export const fetchImage: Plugin.fetchImage = async (url) => { - return await fetchFile(url); -}; - -export const filters = []; \ No newline at end of file + return chapterText; + } + async searchNovels(searchTerm: string, pageNo?: number | undefined): Promise { + const novels: Plugin.NovelItem[] = []; + const url = this.site + "?s=" + searchTerm + "&post_type=wp-manga"; + + const body = await fetchApi(url).then(res => res.text()); + + const loadedCheerio = parseHTML(body); + + + loadedCheerio('.c-tabs-item__content').each(function () { + const novelName = loadedCheerio(this).find('.post-title').text().trim(); + + let image = loadedCheerio(this).find('img'); + const novelCover = image.attr('data-src') || image.attr('src'); + + let novelUrl = loadedCheerio(this) + .find('.post-title') + .find('a') + .attr('href') || ''; + const novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + + novels.push(novel); + }); + return novels; + } + async fetchImage(url: string): Promise { + return await fetchFile(url, {}); + } +} +const plugin = new MadaraPlugin({"id":"ar-mtl","sourceSite":"https://ar-mtl.club/","sourceName":"ArMTL","filters":[],"options":{"useNewChapterEndpoint":true,"lang":"Arabic"}}); +export default plugin; + \ No newline at end of file diff --git a/plugins/arabic/ArNovel[madara].ts b/plugins/arabic/ArNovel[madara].ts index 224837d..544282d 100644 --- a/plugins/arabic/ArNovel[madara].ts +++ b/plugins/arabic/ArNovel[madara].ts @@ -1,213 +1,252 @@ +import { fetchApi, fetchFile } from "@libs/fetch"; +import { Filter } from "@libs/filterInputs"; +import { Plugin } from '@typings/plugin' import { load as parseHTML } from "cheerio"; -import { fetchFile, fetchApi } from "@libs/fetch"; -import { Novel, Plugin, Chapter } from "@typings/plugin"; -import { FilterInputs } from "@libs/filterInputs"; import { defaultCover } from "@libs/defaultCover"; -import { NovelStatus } from "@libs/novelStatus" +import { NovelStatus } from "@libs/novelStatus"; import { parseMadaraDate } from "@libs/parseMadaraDate"; import dayjs from "dayjs"; -export const id = "arnovel"; -export const name = "ArNovel [madara]"; -export const icon = "multisrc/madara/icons/arnovel.png"; -export const version = "1.0.0"; -export const site = "https://arnovel.me/"; -const baseUrl = site; +interface MadaraOptionPath{ + genres?: string, + novels?: string, + novel?: string, + chapter?: string, +} -export const popularNovels: Plugin.popularNovels = async (pageNo, {filters, showLatestNovels}) => { - const novels: Novel.Item[] = []; +const MadaraDefaultPath: MadaraOptionPath = { + novels: 'novel', + novel: 'novel', + chapter: 'novel' +} - let url = site; +interface MadaraOptions { + useNewChapterEndpoint?: boolean, + path?: MadaraOptionPath, + lang?: string, + orderBy?: string +} - if (filters?.genres) { - url += "home/novel-genre/" + filters.genres + '/'; - } else { - url += "novel/"; +export interface MadaraMetadata { + id: string, + sourceSite: string, + sourceName: string, + options?: MadaraOptions, + filters?: Filter[], +} +class MadaraPlugin implements Plugin.PluginBase { + id: string; + name: string; + icon: string; + site: string; + version: string; + userAgent: string; + cookieString: string; + options?: MadaraOptions; + filter?: Filter[] | undefined; + + constructor(metadata: MadaraMetadata){ + this.id = metadata.id; + this.name = metadata.sourceName + "[madara]"; + const iconFileName = metadata.sourceName.replace(/\s+/g, "").toLowerCase(); + this.icon = `multisrc/madara/icons/${iconFileName}.png`; + this.site = metadata.sourceSite; + this.version = "1.0.0"; + this.userAgent = ""; + this.cookieString = ""; + this.options = metadata.options; + this.filter = metadata.filters; } + async popularNovels(pageNo: number, {filters, showLatestNovels}: Plugin.PopularNovelsOptions): Promise { + const novels: Plugin.NovelItem[] = []; - url += '/page/' + pageNo + '/' + - '?m_orderby=' + (showLatestNovels ? 'latest' : (filters?.sort || 'rating')); - - const body = await fetchApi(url).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - - loadedCheerio('.manga-title-badges').remove(); - - loadedCheerio('.page-item-detail').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - - let novelUrl = loadedCheerio(this).find('.post-title') - .find('a') - .attr('href') || ''; - const novel: Novel.Item = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - - novels.push(novel); - }); - - return novels; -}; - -export const parseNovelAndChapters: Plugin.parseNovelAndChapters = async ( - novelUrl -) => { - const novel: Novel.instance = { - url: novelUrl, - }; - - const body = await fetchApi(novelUrl).then(res => res.text()); - - let loadedCheerio = parseHTML(body); - - loadedCheerio('.manga-title-badges').remove(); - - novel.name = loadedCheerio('.post-title h1').text().trim(); - - novel.cover = - loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || - loadedCheerio('.summary_image > a > img').attr('data-src') || - loadedCheerio('.summary_image > a > img').attr('src') || - defaultCover; - - loadedCheerio('.post-content_item, .post-content').each(function () { - const detailName = loadedCheerio(this).find('h5').text().trim(); - const detail = loadedCheerio(this).find('.summary-content').text().trim(); - - switch (detailName) { - case 'Genre(s)': - case 'التصنيفات': - novel.genres = detail.replace(/[\t\n]/g, ','); - break; - case 'Author(s)': - case 'المؤلف': - case 'المؤلف (ين)': - novel.author = detail; - break; - case 'Status': - case 'الحالة': - novel.status = - detail.includes('OnGoing') || detail.includes('مستمرة') - ? NovelStatus.Ongoing - : NovelStatus.Completed; - break; - } - }); - - loadedCheerio('div.summary__content .code-block,script').remove(); - novel.summary = loadedCheerio('div.summary__content').text().trim(); - - - let html; - - if (true) { - const novelId = - loadedCheerio('.rating-post-id').attr('value') || - loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; - - const body = { - action: "manga_get_chapters", - manga: novelId, - } - html = await fetchApi( - baseUrl + 'wp-admin/admin-ajax.php', - { - method: 'POST', - body: JSON.stringify(body), - }) - .then(res => res.text()); - } else { - html = await fetchApi( - baseUrl + 'ajax/chapters/', - { method: 'POST' }) - .then(res => res.text()); - } - - if (html !== '0') { - loadedCheerio = parseHTML(html); - } - - const chapters: Chapter.Item[] = []; - loadedCheerio('.wp-manga-chapter').each(function () { - const chapterName = loadedCheerio(this).find('a').text().trim(); - - let releaseDate = null; - releaseDate = loadedCheerio(this) - .find('span.chapter-release-date') - .text() - .trim(); - - if (releaseDate) { - releaseDate = parseMadaraDate(releaseDate); + let url = this.site; + if (filters?.genres && this.options?.path?.genres) { + url += this.options?.path?.genres + filters.genres + '/'; } else { - /** - * Insert current date - */ - - releaseDate = dayjs().format('LL'); + url += this.options?.path?.novels ? this.options.path.novels : MadaraDefaultPath.novels; } + + url += '/page/' + pageNo + '/' + + '?m_orderby=' + (showLatestNovels ? 'latest' : (filters?.sort || 'rating')); + + const body = await fetchApi(url).then(res => res.text()); + + const loadedCheerio = parseHTML(body); + + loadedCheerio('.manga-title-badges').remove(); + + loadedCheerio('.page-item-detail').each(function () { + const novelName = loadedCheerio(this).find('.post-title').text().trim(); + let image = loadedCheerio(this).find('img'); + const novelCover = image.attr('data-src') || image.attr('src'); + + let novelUrl = loadedCheerio(this).find('.post-title') + .find('a') + .attr('href') || ''; + const novel: Plugin.NovelItem = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + + novels.push(novel); + }); + + return novels; + } + async parseNovelAndChapters(novelUrl: string): Promise { + const novel: Plugin.SourceNovel = { + url: novelUrl, + }; + + const body = await fetchApi(novelUrl).then(res => res.text()); + + let loadedCheerio = parseHTML(body); + + loadedCheerio('.manga-title-badges, #manga-title span').remove(); + novel.name = + loadedCheerio('.post-title h1').text().trim() || + loadedCheerio('#manga-title h1').text(); + + novel.cover = + loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || + loadedCheerio('.summary_image > a > img').attr('data-src') || + loadedCheerio('.summary_image > a > img').attr('src') || + defaultCover; + + loadedCheerio('.post-content_item, .post-content').each(function () { + const detailName = loadedCheerio(this).find('h5').text().trim(); + const detail = loadedCheerio(this).find('.summary-content').text().trim(); + + switch (detailName) { + case 'Genre(s)': + case 'التصنيفات': + novel.genres = detail.replace(/[\\t\\n]/g, ','); + break; + case 'Author(s)': + case 'المؤلف': + case 'المؤلف (ين)': + novel.author = detail; + break; + case 'Status': + case 'الحالة': + novel.status = + detail.includes('OnGoing') || detail.includes('مستمرة') + ? NovelStatus.Ongoing + : NovelStatus.Completed; + break; + } + }); + + loadedCheerio('div.summary__content .code-block,script').remove(); + novel.summary = + loadedCheerio('div.summary__content').text().trim() || + loadedCheerio('#tab-manga-about').text().trim() || + loadedCheerio('.post-content_item h5:contains("Summary")').next().text().trim(); + + let html; + + if (this.options?.useNewChapterEndpoint !== true) { + const novelId = + loadedCheerio('.rating-post-id').attr('value') || + loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; + + const formData = new FormData() + formData.append("action", "manga_get_chapters"); + formData.append("manga", novelId); - let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + html = await fetchApi( + this.site + 'wp-admin/admin-ajax.php', + { + method: 'POST', + body: formData, + }) + .then(res => res.text()); + } else { + html = await fetchApi( + novelUrl + 'ajax/chapters/', + { method: 'POST' }) + .then(res => res.text()); + } + + if (html !== '0') { + loadedCheerio = parseHTML(html); + } + + const chapters: Plugin.ChapterItem[] = []; + loadedCheerio('.wp-manga-chapter').each(function () { + const chapterName = loadedCheerio(this).find('a').text().trim(); + + let releaseDate = null; + releaseDate = loadedCheerio(this) + .find('span.chapter-release-date') + .text() + .trim(); + + if (releaseDate) { + releaseDate = parseMadaraDate(releaseDate); + } else { + /** + * Insert current date + */ + + releaseDate = dayjs().format('LL'); + } + + let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + + chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); + }); + + novel.chapters = chapters.reverse(); + return novel; + } + async parseChapter(chapterUrl: string): Promise { + const body = await fetchApi(chapterUrl).then(res => res.text()); - chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); - }); + const loadedCheerio = parseHTML(body); + const chapterText = + loadedCheerio('.text-left').html() || + loadedCheerio('.text-right').html() || + loadedCheerio('.entry-content').html() || ""; - novel.chapters = chapters.reverse(); - return novel; -}; - -export const parseChapter: Plugin.parseChapter = async (chapterUrl) => { - const url = baseUrl + "/" + "novel" + "/" + chapterUrl; - - const body = await fetchApi(chapterUrl).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - const chapterText = - loadedCheerio('.text-left').html() || - loadedCheerio('.text-right').html() || - loadedCheerio('.entry-content').html(); - - return chapterText; -}; - -export const searchNovels: Plugin.searchNovels = async (searchTerm) => { - const novels: Novel.Item[] = []; - const url = baseUrl + "?s=" + searchTerm + "&post_type=wp-manga"; - - const body = await fetchApi(url).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - - - loadedCheerio('.c-tabs-item__content').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - - let novelUrl = loadedCheerio(this) - .find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - - novels.push(novel); - }); - return novels; -}; - -export const fetchImage: Plugin.fetchImage = async (url) => { - return await fetchFile(url); -}; - -export const filters = [{"key":"sort","label":"الترتيب حسب","values":[{"label":"A-Z","value":"alphabet"},{"label":"الآخير","value":"latest"},{"label":"الأكثر مشاهدة","value":"views"},{"label":"التقييم","value":"rating"},{"label":"جديد","value":"new-manga"},{"label":"شائع","value":"trending"}],"inputType":FilterInputs.Picker},{"key":"genres","label":"التصنيفات","values":[{"label":"أكشن","value":"%d8%a3%d9%83%d8%b4%d9%86"},{"label":"إتشي","value":"%d8%a5%d8%aa%d8%b4%d9%80%d9%8a"},{"label":"بالغ","value":"%d8%a8%d8%a7%d9%84%d8%ba"},{"label":"تاريخي","value":"%d8%aa%d8%a7%d8%b1%d9%8a%d8%ae%d9%8a"},{"label":"تراجدي","value":"%d8%aa%d8%b1%d8%a7%d8%ac%d8%af%d9%8a"},{"label":"جوسي","value":"%d8%ac%d9%88%d8%b3%d9%8a"},{"label":"حريم","value":"%d8%ad%d8%b1%d9%8a%d9%85"},{"label":"حياة مدرسية","value":"%d8%ad%d9%8a%d8%a7%d8%a9-%d9%85%d8%af%d8%b1%d8%b3%d9%8a%d8%a9"},{"label":"خارق لطبيعية","value":"%d8%ae%d8%a7%d8%b1%d9%82-%d9%84%d8%b7%d8%a8%d9%8a%d8%b9%d9%8a%d8%a9"},{"label":"خيال","value":"%d8%ae%d9%8a%d8%a7%d9%84"},{"label":"خيال علمي","value":"%d8%ae%d9%8a%d8%a7%d9%84-%d8%b9%d9%84%d9%85%d9%8a"},{"label":"دراما","value":"%d8%af%d8%b1%d8%a7%d9%85%d8%a7"},{"label":"راشد","value":"%d8%b1%d8%a7%d8%b4%d8%af"},{"label":"رعب","value":"%d8%b1%d8%b9%d8%a8"},{"label":"رومنسي","value":"%d8%b1%d9%88%d9%85%d9%86%d8%b3%d9%8a"},{"label":"رياضي","value":"%d8%b1%d9%8a%d8%a7%d8%b6%d9%8a"},{"label":"سينين","value":"%d8%b3%d9%8a%d9%86%d9%8a%d9%86"},{"label":"شريحة من الحياة","value":"%d8%b4%d8%b1%d9%8a%d8%ad%d8%a9-%d9%85%d9%86-%d8%a7%d9%84%d8%ad%d9%8a%d8%a7%d8%a9"},{"label":"شوجو","value":"%d8%b4%d9%88%d8%ac%d9%88"},{"label":"شونين","value":"%d8%b4%d9%88%d9%86%d9%8a%d9%86"},{"label":"غموض","value":"%d8%ba%d9%85%d9%88%d8%b6"},{"label":"فنون قتال","value":"%d9%81%d9%86%d9%88%d9%86-%d9%82%d8%aa%d8%a7%d9%84"},{"label":"كوميديا","value":"%d9%83%d9%88%d9%85%d9%8a%d8%af%d9%8a%d8%a7"},{"label":"مغامرات","value":"%d9%85%d8%ba%d8%a7%d9%85%d8%b1%d8%a7%d8%aa"},{"label":"منتهية","value":"%d9%85%d9%86%d8%aa%d9%87%d9%8a%d8%a9"},{"label":"ميكا","value":"%d9%85%d9%8a%d9%83%d8%a7"},{"label":"نفسي","value":"%d9%86%d9%81%d8%b3%d9%8a"}],"inputType":FilterInputs.Picker}]; \ No newline at end of file + return chapterText; + } + async searchNovels(searchTerm: string, pageNo?: number | undefined): Promise { + const novels: Plugin.NovelItem[] = []; + const url = this.site + "?s=" + searchTerm + "&post_type=wp-manga"; + + const body = await fetchApi(url).then(res => res.text()); + + const loadedCheerio = parseHTML(body); + + + loadedCheerio('.c-tabs-item__content').each(function () { + const novelName = loadedCheerio(this).find('.post-title').text().trim(); + + let image = loadedCheerio(this).find('img'); + const novelCover = image.attr('data-src') || image.attr('src'); + + let novelUrl = loadedCheerio(this) + .find('.post-title') + .find('a') + .attr('href') || ''; + const novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + + novels.push(novel); + }); + return novels; + } + async fetchImage(url: string): Promise { + return await fetchFile(url, {}); + } +} +const plugin = new MadaraPlugin({"id":"arnovel","sourceSite":"https://arnovel.me/","sourceName":"ArNovel","filters":[{"key":"sort","label":"الترتيب حسب","values":[{"label":"A-Z","value":"alphabet"},{"label":"الآخير","value":"latest"},{"label":"الأكثر مشاهدة","value":"views"},{"label":"التقييم","value":"rating"},{"label":"جديد","value":"new-manga"},{"label":"شائع","value":"trending"}],"inputType":"Picker"},{"key":"genres","label":"التصنيفات","values":[{"label":"أكشن","value":"%d8%a3%d9%83%d8%b4%d9%86"},{"label":"إتشي","value":"%d8%a5%d8%aa%d8%b4%d9%80%d9%8a"},{"label":"بالغ","value":"%d8%a8%d8%a7%d9%84%d8%ba"},{"label":"تاريخي","value":"%d8%aa%d8%a7%d8%b1%d9%8a%d8%ae%d9%8a"},{"label":"تراجدي","value":"%d8%aa%d8%b1%d8%a7%d8%ac%d8%af%d9%8a"},{"label":"جوسي","value":"%d8%ac%d9%88%d8%b3%d9%8a"},{"label":"حريم","value":"%d8%ad%d8%b1%d9%8a%d9%85"},{"label":"حياة مدرسية","value":"%d8%ad%d9%8a%d8%a7%d8%a9-%d9%85%d8%af%d8%b1%d8%b3%d9%8a%d8%a9"},{"label":"خارق لطبيعية","value":"%d8%ae%d8%a7%d8%b1%d9%82-%d9%84%d8%b7%d8%a8%d9%8a%d8%b9%d9%8a%d8%a9"},{"label":"خيال","value":"%d8%ae%d9%8a%d8%a7%d9%84"},{"label":"خيال علمي","value":"%d8%ae%d9%8a%d8%a7%d9%84-%d8%b9%d9%84%d9%85%d9%8a"},{"label":"دراما","value":"%d8%af%d8%b1%d8%a7%d9%85%d8%a7"},{"label":"راشد","value":"%d8%b1%d8%a7%d8%b4%d8%af"},{"label":"رعب","value":"%d8%b1%d8%b9%d8%a8"},{"label":"رومنسي","value":"%d8%b1%d9%88%d9%85%d9%86%d8%b3%d9%8a"},{"label":"رياضي","value":"%d8%b1%d9%8a%d8%a7%d8%b6%d9%8a"},{"label":"سينين","value":"%d8%b3%d9%8a%d9%86%d9%8a%d9%86"},{"label":"شريحة من الحياة","value":"%d8%b4%d8%b1%d9%8a%d8%ad%d8%a9-%d9%85%d9%86-%d8%a7%d9%84%d8%ad%d9%8a%d8%a7%d8%a9"},{"label":"شوجو","value":"%d8%b4%d9%88%d8%ac%d9%88"},{"label":"شونين","value":"%d8%b4%d9%88%d9%86%d9%8a%d9%86"},{"label":"غموض","value":"%d8%ba%d9%85%d9%88%d8%b6"},{"label":"فنون قتال","value":"%d9%81%d9%86%d9%88%d9%86-%d9%82%d8%aa%d8%a7%d9%84"},{"label":"كوميديا","value":"%d9%83%d9%88%d9%85%d9%8a%d8%af%d9%8a%d8%a7"},{"label":"مغامرات","value":"%d9%85%d8%ba%d8%a7%d9%85%d8%b1%d8%a7%d8%aa"},{"label":"منتهية","value":"%d9%85%d9%86%d8%aa%d9%87%d9%8a%d8%a9"},{"label":"ميكا","value":"%d9%85%d9%8a%d9%83%d8%a7"},{"label":"نفسي","value":"%d9%86%d9%81%d8%b3%d9%8a"}],"inputType":"Picker"}],"options":{"path":{"genres":"home/novel-genre"},"useNewChapterEndpoint":true,"lang":"Arabic"}}); +export default plugin; + \ No newline at end of file diff --git a/plugins/arabic/HizoManga[madara].ts b/plugins/arabic/HizoManga[madara].ts index 053bb67..b4dbf6e 100644 --- a/plugins/arabic/HizoManga[madara].ts +++ b/plugins/arabic/HizoManga[madara].ts @@ -1,213 +1,252 @@ +import { fetchApi, fetchFile } from "@libs/fetch"; +import { Filter } from "@libs/filterInputs"; +import { Plugin } from '@typings/plugin' import { load as parseHTML } from "cheerio"; -import { fetchFile, fetchApi } from "@libs/fetch"; -import { Novel, Plugin, Chapter } from "@typings/plugin"; -import { FilterInputs } from "@libs/filterInputs"; import { defaultCover } from "@libs/defaultCover"; -import { NovelStatus } from "@libs/novelStatus" +import { NovelStatus } from "@libs/novelStatus"; import { parseMadaraDate } from "@libs/parseMadaraDate"; import dayjs from "dayjs"; -export const id = "hizomanga"; -export const name = "HizoManga [madara]"; -export const icon = "multisrc/madara/icons/hizomanga.png"; -export const version = "1.0.0"; -export const site = "https://hizomanga.com/"; -const baseUrl = site; +interface MadaraOptionPath{ + genres?: string, + novels?: string, + novel?: string, + chapter?: string, +} -export const popularNovels: Plugin.popularNovels = async (pageNo, {filters, showLatestNovels}) => { - const novels: Novel.Item[] = []; +const MadaraDefaultPath: MadaraOptionPath = { + novels: 'novel', + novel: 'novel', + chapter: 'novel' +} - let url = site; +interface MadaraOptions { + useNewChapterEndpoint?: boolean, + path?: MadaraOptionPath, + lang?: string, + orderBy?: string +} - if (filters?.genres) { - url += "manga-genre/" + filters.genres + '/'; - } else { - url += "serie/"; +export interface MadaraMetadata { + id: string, + sourceSite: string, + sourceName: string, + options?: MadaraOptions, + filters?: Filter[], +} +class MadaraPlugin implements Plugin.PluginBase { + id: string; + name: string; + icon: string; + site: string; + version: string; + userAgent: string; + cookieString: string; + options?: MadaraOptions; + filter?: Filter[] | undefined; + + constructor(metadata: MadaraMetadata){ + this.id = metadata.id; + this.name = metadata.sourceName + "[madara]"; + const iconFileName = metadata.sourceName.replace(/\s+/g, "").toLowerCase(); + this.icon = `multisrc/madara/icons/${iconFileName}.png`; + this.site = metadata.sourceSite; + this.version = "1.0.0"; + this.userAgent = ""; + this.cookieString = ""; + this.options = metadata.options; + this.filter = metadata.filters; } + async popularNovels(pageNo: number, {filters, showLatestNovels}: Plugin.PopularNovelsOptions): Promise { + const novels: Plugin.NovelItem[] = []; - url += '/page/' + pageNo + '/' + - '?m_orderby=' + (showLatestNovels ? 'latest' : (filters?.sort || 'rating')); - - const body = await fetchApi(url).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - - loadedCheerio('.manga-title-badges').remove(); - - loadedCheerio('.page-item-detail').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - - let novelUrl = loadedCheerio(this).find('.post-title') - .find('a') - .attr('href') || ''; - const novel: Novel.Item = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - - novels.push(novel); - }); - - return novels; -}; - -export const parseNovelAndChapters: Plugin.parseNovelAndChapters = async ( - novelUrl -) => { - const novel: Novel.instance = { - url: novelUrl, - }; - - const body = await fetchApi(novelUrl).then(res => res.text()); - - let loadedCheerio = parseHTML(body); - - loadedCheerio('.manga-title-badges').remove(); - - novel.name = loadedCheerio('.post-title h1').text().trim(); - - novel.cover = - loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || - loadedCheerio('.summary_image > a > img').attr('data-src') || - loadedCheerio('.summary_image > a > img').attr('src') || - defaultCover; - - loadedCheerio('.post-content_item, .post-content').each(function () { - const detailName = loadedCheerio(this).find('h5').text().trim(); - const detail = loadedCheerio(this).find('.summary-content').text().trim(); - - switch (detailName) { - case 'Genre(s)': - case 'التصنيفات': - novel.genres = detail.replace(/[\t\n]/g, ','); - break; - case 'Author(s)': - case 'المؤلف': - case 'المؤلف (ين)': - novel.author = detail; - break; - case 'Status': - case 'الحالة': - novel.status = - detail.includes('OnGoing') || detail.includes('مستمرة') - ? NovelStatus.Ongoing - : NovelStatus.Completed; - break; - } - }); - - loadedCheerio('div.summary__content .code-block,script').remove(); - novel.summary = loadedCheerio('div.summary__content').text().trim(); - - - let html; - - if (true) { - const novelId = - loadedCheerio('.rating-post-id').attr('value') || - loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; - - const body = { - action: "manga_get_chapters", - manga: novelId, - } - html = await fetchApi( - baseUrl + 'wp-admin/admin-ajax.php', - { - method: 'POST', - body: JSON.stringify(body), - }) - .then(res => res.text()); - } else { - html = await fetchApi( - baseUrl + 'ajax/chapters/', - { method: 'POST' }) - .then(res => res.text()); - } - - if (html !== '0') { - loadedCheerio = parseHTML(html); - } - - const chapters: Chapter.Item[] = []; - loadedCheerio('.wp-manga-chapter').each(function () { - const chapterName = loadedCheerio(this).find('a').text().trim(); - - let releaseDate = null; - releaseDate = loadedCheerio(this) - .find('span.chapter-release-date') - .text() - .trim(); - - if (releaseDate) { - releaseDate = parseMadaraDate(releaseDate); + let url = this.site; + if (filters?.genres && this.options?.path?.genres) { + url += this.options?.path?.genres + filters.genres + '/'; } else { - /** - * Insert current date - */ - - releaseDate = dayjs().format('LL'); + url += this.options?.path?.novels ? this.options.path.novels : MadaraDefaultPath.novels; } + + url += '/page/' + pageNo + '/' + + '?m_orderby=' + (showLatestNovels ? 'latest' : (filters?.sort || 'rating')); + + const body = await fetchApi(url).then(res => res.text()); + + const loadedCheerio = parseHTML(body); + + loadedCheerio('.manga-title-badges').remove(); + + loadedCheerio('.page-item-detail').each(function () { + const novelName = loadedCheerio(this).find('.post-title').text().trim(); + let image = loadedCheerio(this).find('img'); + const novelCover = image.attr('data-src') || image.attr('src'); + + let novelUrl = loadedCheerio(this).find('.post-title') + .find('a') + .attr('href') || ''; + const novel: Plugin.NovelItem = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + + novels.push(novel); + }); + + return novels; + } + async parseNovelAndChapters(novelUrl: string): Promise { + const novel: Plugin.SourceNovel = { + url: novelUrl, + }; + + const body = await fetchApi(novelUrl).then(res => res.text()); + + let loadedCheerio = parseHTML(body); + + loadedCheerio('.manga-title-badges, #manga-title span').remove(); + novel.name = + loadedCheerio('.post-title h1').text().trim() || + loadedCheerio('#manga-title h1').text(); + + novel.cover = + loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || + loadedCheerio('.summary_image > a > img').attr('data-src') || + loadedCheerio('.summary_image > a > img').attr('src') || + defaultCover; + + loadedCheerio('.post-content_item, .post-content').each(function () { + const detailName = loadedCheerio(this).find('h5').text().trim(); + const detail = loadedCheerio(this).find('.summary-content').text().trim(); + + switch (detailName) { + case 'Genre(s)': + case 'التصنيفات': + novel.genres = detail.replace(/[\\t\\n]/g, ','); + break; + case 'Author(s)': + case 'المؤلف': + case 'المؤلف (ين)': + novel.author = detail; + break; + case 'Status': + case 'الحالة': + novel.status = + detail.includes('OnGoing') || detail.includes('مستمرة') + ? NovelStatus.Ongoing + : NovelStatus.Completed; + break; + } + }); + + loadedCheerio('div.summary__content .code-block,script').remove(); + novel.summary = + loadedCheerio('div.summary__content').text().trim() || + loadedCheerio('#tab-manga-about').text().trim() || + loadedCheerio('.post-content_item h5:contains("Summary")').next().text().trim(); + + let html; + + if (this.options?.useNewChapterEndpoint !== true) { + const novelId = + loadedCheerio('.rating-post-id').attr('value') || + loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; + + const formData = new FormData() + formData.append("action", "manga_get_chapters"); + formData.append("manga", novelId); - let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + html = await fetchApi( + this.site + 'wp-admin/admin-ajax.php', + { + method: 'POST', + body: formData, + }) + .then(res => res.text()); + } else { + html = await fetchApi( + novelUrl + 'ajax/chapters/', + { method: 'POST' }) + .then(res => res.text()); + } + + if (html !== '0') { + loadedCheerio = parseHTML(html); + } + + const chapters: Plugin.ChapterItem[] = []; + loadedCheerio('.wp-manga-chapter').each(function () { + const chapterName = loadedCheerio(this).find('a').text().trim(); + + let releaseDate = null; + releaseDate = loadedCheerio(this) + .find('span.chapter-release-date') + .text() + .trim(); + + if (releaseDate) { + releaseDate = parseMadaraDate(releaseDate); + } else { + /** + * Insert current date + */ + + releaseDate = dayjs().format('LL'); + } + + let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + + chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); + }); + + novel.chapters = chapters.reverse(); + return novel; + } + async parseChapter(chapterUrl: string): Promise { + const body = await fetchApi(chapterUrl).then(res => res.text()); - chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); - }); + const loadedCheerio = parseHTML(body); + const chapterText = + loadedCheerio('.text-left').html() || + loadedCheerio('.text-right').html() || + loadedCheerio('.entry-content').html() || ""; - novel.chapters = chapters.reverse(); - return novel; -}; - -export const parseChapter: Plugin.parseChapter = async (chapterUrl) => { - const url = baseUrl + "/" + "serie" + "/" + chapterUrl; - - const body = await fetchApi(chapterUrl).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - const chapterText = - loadedCheerio('.text-left').html() || - loadedCheerio('.text-right').html() || - loadedCheerio('.entry-content').html(); - - return chapterText; -}; - -export const searchNovels: Plugin.searchNovels = async (searchTerm) => { - const novels: Novel.Item[] = []; - const url = baseUrl + "?s=" + searchTerm + "&post_type=wp-manga"; - - const body = await fetchApi(url).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - - - loadedCheerio('.c-tabs-item__content').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - - let novelUrl = loadedCheerio(this) - .find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - - novels.push(novel); - }); - return novels; -}; - -export const fetchImage: Plugin.fetchImage = async (url) => { - return await fetchFile(url); -}; - -export const filters = [{"key":"sort","label":"ترتيب حسب","values":[{"label":"A-Z","value":"alphabet"},{"label":"New","value":"new-manga"},{"label":"الأحدث","value":"latest"},{"label":"الأكثر مشاهدة","value":"views"},{"label":"التقييم","value":"rating"},{"label":"الرائج","value":"trending"}],"inputType":FilterInputs.Picker},{"key":"genres","label":"التصنيفات","values":[{"label":"آلات","value":"mechanisms"},{"label":"أكشن","value":"action"},{"label":"إثارة","value":"excitement"},{"label":"إيسكاي","value":"%d8%a5%d9%8a%d8%b3%d9%83%d8%a7%d9%8a"},{"label":"الحياة اليومية","value":"slice-of-life"},{"label":"الحياة مدرسية","value":"school-life"},{"label":"تاريخي","value":"historical"},{"label":"تراجيدي","value":"tragic"},{"label":"جريمة","value":"%d8%ac%d8%b1%d9%8a%d9%85%d8%a9"},{"label":"جندر بندر","value":"%d8%ac%d9%86%d8%af%d8%b1-%d8%a8%d9%86%d8%af%d8%b1"},{"label":"جوسي","value":"josei"},{"label":"حريم","value":"harem"},{"label":"خارق للطبيعة","value":"supernatural"},{"label":"خيال","value":"fantasy"},{"label":"خيال علمي","value":"sci-fi"},{"label":"دراما","value":"drama"},{"label":"دموي","value":"%d8%af%d9%85%d9%88%d9%8a"},{"label":"راشد","value":"mature"},{"label":"رعب","value":"horror"},{"label":"رومانسي","value":"romance"},{"label":"رياضة","value":"sports"},{"label":"زمنكاني","value":"my-time"},{"label":"زومبي","value":"%d8%b2%d9%88%d9%85%d8%a8%d9%8a"},{"label":"سينين","value":"seinen"},{"label":"شريحة من الحياة","value":"%d8%b4%d8%b1%d9%8a%d8%ad%d8%a9-%d9%85%d9%86-%d8%a7%d9%84%d8%ad%d9%8a%d8%a7%d8%a9"},{"label":"شوجو","value":"shoujo"},{"label":"شونين","value":"shounen"},{"label":"طبي","value":"%d8%b7%d8%a8%d9%8a"},{"label":"غموض","value":"ambiguity"},{"label":"فنون قتالية","value":"martial-arts"},{"label":"قوة خارقة","value":"superpower"},{"label":"كوميدي","value":"comedy"},{"label":"مغامرات","value":"adventure"},{"label":"نفسي","value":"psychological"}],"inputType":FilterInputs.Picker}]; \ No newline at end of file + return chapterText; + } + async searchNovels(searchTerm: string, pageNo?: number | undefined): Promise { + const novels: Plugin.NovelItem[] = []; + const url = this.site + "?s=" + searchTerm + "&post_type=wp-manga"; + + const body = await fetchApi(url).then(res => res.text()); + + const loadedCheerio = parseHTML(body); + + + loadedCheerio('.c-tabs-item__content').each(function () { + const novelName = loadedCheerio(this).find('.post-title').text().trim(); + + let image = loadedCheerio(this).find('img'); + const novelCover = image.attr('data-src') || image.attr('src'); + + let novelUrl = loadedCheerio(this) + .find('.post-title') + .find('a') + .attr('href') || ''; + const novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + + novels.push(novel); + }); + return novels; + } + async fetchImage(url: string): Promise { + return await fetchFile(url, {}); + } +} +const plugin = new MadaraPlugin({"id":"hizomanga","sourceSite":"https://hizomanga.com/","sourceName":"HizoManga","filters":[{"key":"sort","label":"ترتيب حسب","values":[{"label":"A-Z","value":"alphabet"},{"label":"New","value":"new-manga"},{"label":"الأحدث","value":"latest"},{"label":"الأكثر مشاهدة","value":"views"},{"label":"التقييم","value":"rating"},{"label":"الرائج","value":"trending"}],"inputType":"Picker"},{"key":"genres","label":"التصنيفات","values":[{"label":"آلات","value":"mechanisms"},{"label":"أكشن","value":"action"},{"label":"إثارة","value":"excitement"},{"label":"إيسكاي","value":"%d8%a5%d9%8a%d8%b3%d9%83%d8%a7%d9%8a"},{"label":"الحياة اليومية","value":"slice-of-life"},{"label":"الحياة مدرسية","value":"school-life"},{"label":"تاريخي","value":"historical"},{"label":"تراجيدي","value":"tragic"},{"label":"جريمة","value":"%d8%ac%d8%b1%d9%8a%d9%85%d8%a9"},{"label":"جندر بندر","value":"%d8%ac%d9%86%d8%af%d8%b1-%d8%a8%d9%86%d8%af%d8%b1"},{"label":"جوسي","value":"josei"},{"label":"حريم","value":"harem"},{"label":"خارق للطبيعة","value":"supernatural"},{"label":"خيال","value":"fantasy"},{"label":"خيال علمي","value":"sci-fi"},{"label":"دراما","value":"drama"},{"label":"دموي","value":"%d8%af%d9%85%d9%88%d9%8a"},{"label":"راشد","value":"mature"},{"label":"رعب","value":"horror"},{"label":"رومانسي","value":"romance"},{"label":"رياضة","value":"sports"},{"label":"زمنكاني","value":"my-time"},{"label":"زومبي","value":"%d8%b2%d9%88%d9%85%d8%a8%d9%8a"},{"label":"سينين","value":"seinen"},{"label":"شريحة من الحياة","value":"%d8%b4%d8%b1%d9%8a%d8%ad%d8%a9-%d9%85%d9%86-%d8%a7%d9%84%d8%ad%d9%8a%d8%a7%d8%a9"},{"label":"شوجو","value":"shoujo"},{"label":"شونين","value":"shounen"},{"label":"طبي","value":"%d8%b7%d8%a8%d9%8a"},{"label":"غموض","value":"ambiguity"},{"label":"فنون قتالية","value":"martial-arts"},{"label":"قوة خارقة","value":"superpower"},{"label":"كوميدي","value":"comedy"},{"label":"مغامرات","value":"adventure"},{"label":"نفسي","value":"psychological"}],"inputType":"Picker"}],"options":{"path":{"novels":"serie","novel":"serie","chapter":"serie","genres":"manga-genre"},"useNewChapterEndpoint":true,"lang":"Arabic"}}); +export default plugin; + \ No newline at end of file diff --git a/plugins/arabic/Novel4Up[madara].ts b/plugins/arabic/Novel4Up[madara].ts index 0b3788c..04ddfb1 100644 --- a/plugins/arabic/Novel4Up[madara].ts +++ b/plugins/arabic/Novel4Up[madara].ts @@ -1,213 +1,252 @@ +import { fetchApi, fetchFile } from "@libs/fetch"; +import { Filter } from "@libs/filterInputs"; +import { Plugin } from '@typings/plugin' import { load as parseHTML } from "cheerio"; -import { fetchFile, fetchApi } from "@libs/fetch"; -import { Novel, Plugin, Chapter } from "@typings/plugin"; -import { FilterInputs } from "@libs/filterInputs"; import { defaultCover } from "@libs/defaultCover"; -import { NovelStatus } from "@libs/novelStatus" +import { NovelStatus } from "@libs/novelStatus"; import { parseMadaraDate } from "@libs/parseMadaraDate"; import dayjs from "dayjs"; -export const id = "novel4up"; -export const name = "Novel4Up [madara]"; -export const icon = "multisrc/madara/icons/novel4up.png"; -export const version = "1.0.0"; -export const site = "https://novel4up.com/"; -const baseUrl = site; +interface MadaraOptionPath{ + genres?: string, + novels?: string, + novel?: string, + chapter?: string, +} -export const popularNovels: Plugin.popularNovels = async (pageNo, {filters, showLatestNovels}) => { - const novels: Novel.Item[] = []; +const MadaraDefaultPath: MadaraOptionPath = { + novels: 'novel', + novel: 'novel', + chapter: 'novel' +} - let url = site; +interface MadaraOptions { + useNewChapterEndpoint?: boolean, + path?: MadaraOptionPath, + lang?: string, + orderBy?: string +} - if (filters?.genres) { - url += "novel-genre/" + filters.genres + '/'; - } else { - url += "novel/"; +export interface MadaraMetadata { + id: string, + sourceSite: string, + sourceName: string, + options?: MadaraOptions, + filters?: Filter[], +} +class MadaraPlugin implements Plugin.PluginBase { + id: string; + name: string; + icon: string; + site: string; + version: string; + userAgent: string; + cookieString: string; + options?: MadaraOptions; + filter?: Filter[] | undefined; + + constructor(metadata: MadaraMetadata){ + this.id = metadata.id; + this.name = metadata.sourceName + "[madara]"; + const iconFileName = metadata.sourceName.replace(/\s+/g, "").toLowerCase(); + this.icon = `multisrc/madara/icons/${iconFileName}.png`; + this.site = metadata.sourceSite; + this.version = "1.0.0"; + this.userAgent = ""; + this.cookieString = ""; + this.options = metadata.options; + this.filter = metadata.filters; } + async popularNovels(pageNo: number, {filters, showLatestNovels}: Plugin.PopularNovelsOptions): Promise { + const novels: Plugin.NovelItem[] = []; - url += '/page/' + pageNo + '/' + - '?m_orderby=' + (showLatestNovels ? 'latest' : (filters?.sort || 'rating')); - - const body = await fetchApi(url).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - - loadedCheerio('.manga-title-badges').remove(); - - loadedCheerio('.page-item-detail').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - - let novelUrl = loadedCheerio(this).find('.post-title') - .find('a') - .attr('href') || ''; - const novel: Novel.Item = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - - novels.push(novel); - }); - - return novels; -}; - -export const parseNovelAndChapters: Plugin.parseNovelAndChapters = async ( - novelUrl -) => { - const novel: Novel.instance = { - url: novelUrl, - }; - - const body = await fetchApi(novelUrl).then(res => res.text()); - - let loadedCheerio = parseHTML(body); - - loadedCheerio('.manga-title-badges').remove(); - - novel.name = loadedCheerio('.post-title h1').text().trim(); - - novel.cover = - loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || - loadedCheerio('.summary_image > a > img').attr('data-src') || - loadedCheerio('.summary_image > a > img').attr('src') || - defaultCover; - - loadedCheerio('.post-content_item, .post-content').each(function () { - const detailName = loadedCheerio(this).find('h5').text().trim(); - const detail = loadedCheerio(this).find('.summary-content').text().trim(); - - switch (detailName) { - case 'Genre(s)': - case 'التصنيفات': - novel.genres = detail.replace(/[\t\n]/g, ','); - break; - case 'Author(s)': - case 'المؤلف': - case 'المؤلف (ين)': - novel.author = detail; - break; - case 'Status': - case 'الحالة': - novel.status = - detail.includes('OnGoing') || detail.includes('مستمرة') - ? NovelStatus.Ongoing - : NovelStatus.Completed; - break; - } - }); - - loadedCheerio('div.summary__content .code-block,script').remove(); - novel.summary = loadedCheerio('div.summary__content').text().trim(); - - - let html; - - if (false) { - const novelId = - loadedCheerio('.rating-post-id').attr('value') || - loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; - - const body = { - action: "manga_get_chapters", - manga: novelId, - } - html = await fetchApi( - baseUrl + 'wp-admin/admin-ajax.php', - { - method: 'POST', - body: JSON.stringify(body), - }) - .then(res => res.text()); - } else { - html = await fetchApi( - baseUrl + 'ajax/chapters/', - { method: 'POST' }) - .then(res => res.text()); - } - - if (html !== '0') { - loadedCheerio = parseHTML(html); - } - - const chapters: Chapter.Item[] = []; - loadedCheerio('.wp-manga-chapter').each(function () { - const chapterName = loadedCheerio(this).find('a').text().trim(); - - let releaseDate = null; - releaseDate = loadedCheerio(this) - .find('span.chapter-release-date') - .text() - .trim(); - - if (releaseDate) { - releaseDate = parseMadaraDate(releaseDate); + let url = this.site; + if (filters?.genres && this.options?.path?.genres) { + url += this.options?.path?.genres + filters.genres + '/'; } else { - /** - * Insert current date - */ - - releaseDate = dayjs().format('LL'); + url += this.options?.path?.novels ? this.options.path.novels : MadaraDefaultPath.novels; } + + url += '/page/' + pageNo + '/' + + '?m_orderby=' + (showLatestNovels ? 'latest' : (filters?.sort || 'rating')); + + const body = await fetchApi(url).then(res => res.text()); + + const loadedCheerio = parseHTML(body); + + loadedCheerio('.manga-title-badges').remove(); + + loadedCheerio('.page-item-detail').each(function () { + const novelName = loadedCheerio(this).find('.post-title').text().trim(); + let image = loadedCheerio(this).find('img'); + const novelCover = image.attr('data-src') || image.attr('src'); + + let novelUrl = loadedCheerio(this).find('.post-title') + .find('a') + .attr('href') || ''; + const novel: Plugin.NovelItem = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + + novels.push(novel); + }); + + return novels; + } + async parseNovelAndChapters(novelUrl: string): Promise { + const novel: Plugin.SourceNovel = { + url: novelUrl, + }; + + const body = await fetchApi(novelUrl).then(res => res.text()); + + let loadedCheerio = parseHTML(body); + + loadedCheerio('.manga-title-badges, #manga-title span').remove(); + novel.name = + loadedCheerio('.post-title h1').text().trim() || + loadedCheerio('#manga-title h1').text(); + + novel.cover = + loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || + loadedCheerio('.summary_image > a > img').attr('data-src') || + loadedCheerio('.summary_image > a > img').attr('src') || + defaultCover; + + loadedCheerio('.post-content_item, .post-content').each(function () { + const detailName = loadedCheerio(this).find('h5').text().trim(); + const detail = loadedCheerio(this).find('.summary-content').text().trim(); + + switch (detailName) { + case 'Genre(s)': + case 'التصنيفات': + novel.genres = detail.replace(/[\\t\\n]/g, ','); + break; + case 'Author(s)': + case 'المؤلف': + case 'المؤلف (ين)': + novel.author = detail; + break; + case 'Status': + case 'الحالة': + novel.status = + detail.includes('OnGoing') || detail.includes('مستمرة') + ? NovelStatus.Ongoing + : NovelStatus.Completed; + break; + } + }); + + loadedCheerio('div.summary__content .code-block,script').remove(); + novel.summary = + loadedCheerio('div.summary__content').text().trim() || + loadedCheerio('#tab-manga-about').text().trim() || + loadedCheerio('.post-content_item h5:contains("Summary")').next().text().trim(); + + let html; + + if (this.options?.useNewChapterEndpoint !== true) { + const novelId = + loadedCheerio('.rating-post-id').attr('value') || + loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; + + const formData = new FormData() + formData.append("action", "manga_get_chapters"); + formData.append("manga", novelId); - let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + html = await fetchApi( + this.site + 'wp-admin/admin-ajax.php', + { + method: 'POST', + body: formData, + }) + .then(res => res.text()); + } else { + html = await fetchApi( + novelUrl + 'ajax/chapters/', + { method: 'POST' }) + .then(res => res.text()); + } + + if (html !== '0') { + loadedCheerio = parseHTML(html); + } + + const chapters: Plugin.ChapterItem[] = []; + loadedCheerio('.wp-manga-chapter').each(function () { + const chapterName = loadedCheerio(this).find('a').text().trim(); + + let releaseDate = null; + releaseDate = loadedCheerio(this) + .find('span.chapter-release-date') + .text() + .trim(); + + if (releaseDate) { + releaseDate = parseMadaraDate(releaseDate); + } else { + /** + * Insert current date + */ + + releaseDate = dayjs().format('LL'); + } + + let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + + chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); + }); + + novel.chapters = chapters.reverse(); + return novel; + } + async parseChapter(chapterUrl: string): Promise { + const body = await fetchApi(chapterUrl).then(res => res.text()); - chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); - }); + const loadedCheerio = parseHTML(body); + const chapterText = + loadedCheerio('.text-left').html() || + loadedCheerio('.text-right').html() || + loadedCheerio('.entry-content').html() || ""; - novel.chapters = chapters.reverse(); - return novel; -}; - -export const parseChapter: Plugin.parseChapter = async (chapterUrl) => { - const url = baseUrl + "/" + "novel" + "/" + chapterUrl; - - const body = await fetchApi(chapterUrl).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - const chapterText = - loadedCheerio('.text-left').html() || - loadedCheerio('.text-right').html() || - loadedCheerio('.entry-content').html(); - - return chapterText; -}; - -export const searchNovels: Plugin.searchNovels = async (searchTerm) => { - const novels: Novel.Item[] = []; - const url = baseUrl + "?s=" + searchTerm + "&post_type=wp-manga"; - - const body = await fetchApi(url).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - - - loadedCheerio('.c-tabs-item__content').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - - let novelUrl = loadedCheerio(this) - .find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - - novels.push(novel); - }); - return novels; -}; - -export const fetchImage: Plugin.fetchImage = async (url) => { - return await fetchFile(url); -}; - -export const filters = [{"key":"sort","label":"ترتيب حسب:","values":[{"label":"أ-ي","value":"alphabet"},{"label":"الأحدث","value":"latest"},{"label":"الأكثر مشاهدة","value":"views"},{"label":"التقييم","value":"rating"},{"label":"الجديد","value":"new-manga"},{"label":"الشائع","value":"trending"}],"inputType":FilterInputs.Picker},{"key":"genres","label":"التصنيفات","values":[{"label":"أكشن","value":"action"},{"label":"الخارق للطبيعة","value":"supernatural"},{"label":"تاريخي","value":"historical"},{"label":"تحقيق","value":"detective"},{"label":"تراجيديا","value":"tragedy"},{"label":"حريم","value":"harem"},{"label":"حياة مدرسية","value":"school-life"},{"label":"خيال علمي","value":"sci-fi"},{"label":"دراما","value":"drama"},{"label":"رعب","value":"horror"},{"label":"رومانسي","value":"romance"},{"label":"رياضة","value":"sports"},{"label":"سحر","value":"magic"},{"label":"شريحة من الحياة","value":"slice-of-life"},{"label":"شوانهوا","value":"xuanhuan"},{"label":"شوجو","value":"shoujo"},{"label":"شونين","value":"shounen"},{"label":"غموض","value":"mystery"},{"label":"فانتازيا","value":"fantasy"},{"label":"فنون قتال","value":"martial-arts"},{"label":"كوميديا","value":"comedy"},{"label":"مغامرة","value":"adventure"},{"label":"ميكا","value":"mecha"},{"label":"نفسي","value":"psychological"},{"label":"ون شوت","value":"one-shot"},{"label":"ووشيا","value":"wuxia"}],"inputType":FilterInputs.Picker}]; \ No newline at end of file + return chapterText; + } + async searchNovels(searchTerm: string, pageNo?: number | undefined): Promise { + const novels: Plugin.NovelItem[] = []; + const url = this.site + "?s=" + searchTerm + "&post_type=wp-manga"; + + const body = await fetchApi(url).then(res => res.text()); + + const loadedCheerio = parseHTML(body); + + + loadedCheerio('.c-tabs-item__content').each(function () { + const novelName = loadedCheerio(this).find('.post-title').text().trim(); + + let image = loadedCheerio(this).find('img'); + const novelCover = image.attr('data-src') || image.attr('src'); + + let novelUrl = loadedCheerio(this) + .find('.post-title') + .find('a') + .attr('href') || ''; + const novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + + novels.push(novel); + }); + return novels; + } + async fetchImage(url: string): Promise { + return await fetchFile(url, {}); + } +} +const plugin = new MadaraPlugin({"id":"novel4up","sourceSite":"https://novel4up.com/","sourceName":"Novel4Up","filters":[{"key":"sort","label":"ترتيب حسب:","values":[{"label":"أ-ي","value":"alphabet"},{"label":"الأحدث","value":"latest"},{"label":"الأكثر مشاهدة","value":"views"},{"label":"التقييم","value":"rating"},{"label":"الجديد","value":"new-manga"},{"label":"الشائع","value":"trending"}],"inputType":"Picker"},{"key":"genres","label":"التصنيفات","values":[{"label":"أكشن","value":"action"},{"label":"الخارق للطبيعة","value":"supernatural"},{"label":"تاريخي","value":"historical"},{"label":"تحقيق","value":"detective"},{"label":"تراجيديا","value":"tragedy"},{"label":"حريم","value":"harem"},{"label":"حياة مدرسية","value":"school-life"},{"label":"خيال علمي","value":"sci-fi"},{"label":"دراما","value":"drama"},{"label":"رعب","value":"horror"},{"label":"رومانسي","value":"romance"},{"label":"رياضة","value":"sports"},{"label":"سحر","value":"magic"},{"label":"شريحة من الحياة","value":"slice-of-life"},{"label":"شوانهوا","value":"xuanhuan"},{"label":"شوجو","value":"shoujo"},{"label":"شونين","value":"shounen"},{"label":"غموض","value":"mystery"},{"label":"فانتازيا","value":"fantasy"},{"label":"فنون قتال","value":"martial-arts"},{"label":"كوميديا","value":"comedy"},{"label":"مغامرة","value":"adventure"},{"label":"ميكا","value":"mecha"},{"label":"نفسي","value":"psychological"},{"label":"ون شوت","value":"one-shot"},{"label":"ووشيا","value":"wuxia"}],"inputType":"Picker"}],"options":{"lang":"Arabic"}}); +export default plugin; + \ No newline at end of file diff --git a/plugins/arabic/Riwyat[madara].ts b/plugins/arabic/Riwyat[madara].ts index 9f3f0ae..e2064ce 100644 --- a/plugins/arabic/Riwyat[madara].ts +++ b/plugins/arabic/Riwyat[madara].ts @@ -1,213 +1,252 @@ +import { fetchApi, fetchFile } from "@libs/fetch"; +import { Filter } from "@libs/filterInputs"; +import { Plugin } from '@typings/plugin' import { load as parseHTML } from "cheerio"; -import { fetchFile, fetchApi } from "@libs/fetch"; -import { Novel, Plugin, Chapter } from "@typings/plugin"; -import { FilterInputs } from "@libs/filterInputs"; import { defaultCover } from "@libs/defaultCover"; -import { NovelStatus } from "@libs/novelStatus" +import { NovelStatus } from "@libs/novelStatus"; import { parseMadaraDate } from "@libs/parseMadaraDate"; import dayjs from "dayjs"; -export const id = "riwyat"; -export const name = "Riwyat [madara]"; -export const icon = "multisrc/madara/icons/riwyat.png"; -export const version = "1.0.0"; -export const site = "https://riwyat.com/"; -const baseUrl = site; +interface MadaraOptionPath{ + genres?: string, + novels?: string, + novel?: string, + chapter?: string, +} -export const popularNovels: Plugin.popularNovels = async (pageNo, {filters, showLatestNovels}) => { - const novels: Novel.Item[] = []; +const MadaraDefaultPath: MadaraOptionPath = { + novels: 'novel', + novel: 'novel', + chapter: 'novel' +} - let url = site; +interface MadaraOptions { + useNewChapterEndpoint?: boolean, + path?: MadaraOptionPath, + lang?: string, + orderBy?: string +} - if (filters?.genres) { - url += "novel-genre/" + filters.genres + '/'; - } else { - url += "novel/"; +export interface MadaraMetadata { + id: string, + sourceSite: string, + sourceName: string, + options?: MadaraOptions, + filters?: Filter[], +} +class MadaraPlugin implements Plugin.PluginBase { + id: string; + name: string; + icon: string; + site: string; + version: string; + userAgent: string; + cookieString: string; + options?: MadaraOptions; + filter?: Filter[] | undefined; + + constructor(metadata: MadaraMetadata){ + this.id = metadata.id; + this.name = metadata.sourceName + "[madara]"; + const iconFileName = metadata.sourceName.replace(/\s+/g, "").toLowerCase(); + this.icon = `multisrc/madara/icons/${iconFileName}.png`; + this.site = metadata.sourceSite; + this.version = "1.0.0"; + this.userAgent = ""; + this.cookieString = ""; + this.options = metadata.options; + this.filter = metadata.filters; } + async popularNovels(pageNo: number, {filters, showLatestNovels}: Plugin.PopularNovelsOptions): Promise { + const novels: Plugin.NovelItem[] = []; - url += '/page/' + pageNo + '/' + - '?m_orderby=' + (showLatestNovels ? 'latest' : (filters?.sort || 'rating')); - - const body = await fetchApi(url).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - - loadedCheerio('.manga-title-badges').remove(); - - loadedCheerio('.page-item-detail').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - - let novelUrl = loadedCheerio(this).find('.post-title') - .find('a') - .attr('href') || ''; - const novel: Novel.Item = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - - novels.push(novel); - }); - - return novels; -}; - -export const parseNovelAndChapters: Plugin.parseNovelAndChapters = async ( - novelUrl -) => { - const novel: Novel.instance = { - url: novelUrl, - }; - - const body = await fetchApi(novelUrl).then(res => res.text()); - - let loadedCheerio = parseHTML(body); - - loadedCheerio('.manga-title-badges').remove(); - - novel.name = loadedCheerio('.post-title h1').text().trim(); - - novel.cover = - loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || - loadedCheerio('.summary_image > a > img').attr('data-src') || - loadedCheerio('.summary_image > a > img').attr('src') || - defaultCover; - - loadedCheerio('.post-content_item, .post-content').each(function () { - const detailName = loadedCheerio(this).find('h5').text().trim(); - const detail = loadedCheerio(this).find('.summary-content').text().trim(); - - switch (detailName) { - case 'Genre(s)': - case 'التصنيفات': - novel.genres = detail.replace(/[\t\n]/g, ','); - break; - case 'Author(s)': - case 'المؤلف': - case 'المؤلف (ين)': - novel.author = detail; - break; - case 'Status': - case 'الحالة': - novel.status = - detail.includes('OnGoing') || detail.includes('مستمرة') - ? NovelStatus.Ongoing - : NovelStatus.Completed; - break; - } - }); - - loadedCheerio('div.summary__content .code-block,script').remove(); - novel.summary = loadedCheerio('div.summary__content').text().trim(); - - - let html; - - if (true) { - const novelId = - loadedCheerio('.rating-post-id').attr('value') || - loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; - - const body = { - action: "manga_get_chapters", - manga: novelId, - } - html = await fetchApi( - baseUrl + 'wp-admin/admin-ajax.php', - { - method: 'POST', - body: JSON.stringify(body), - }) - .then(res => res.text()); - } else { - html = await fetchApi( - baseUrl + 'ajax/chapters/', - { method: 'POST' }) - .then(res => res.text()); - } - - if (html !== '0') { - loadedCheerio = parseHTML(html); - } - - const chapters: Chapter.Item[] = []; - loadedCheerio('.wp-manga-chapter').each(function () { - const chapterName = loadedCheerio(this).find('a').text().trim(); - - let releaseDate = null; - releaseDate = loadedCheerio(this) - .find('span.chapter-release-date') - .text() - .trim(); - - if (releaseDate) { - releaseDate = parseMadaraDate(releaseDate); + let url = this.site; + if (filters?.genres && this.options?.path?.genres) { + url += this.options?.path?.genres + filters.genres + '/'; } else { - /** - * Insert current date - */ - - releaseDate = dayjs().format('LL'); + url += this.options?.path?.novels ? this.options.path.novels : MadaraDefaultPath.novels; } + + url += '/page/' + pageNo + '/' + + '?m_orderby=' + (showLatestNovels ? 'latest' : (filters?.sort || 'rating')); + + const body = await fetchApi(url).then(res => res.text()); + + const loadedCheerio = parseHTML(body); + + loadedCheerio('.manga-title-badges').remove(); + + loadedCheerio('.page-item-detail').each(function () { + const novelName = loadedCheerio(this).find('.post-title').text().trim(); + let image = loadedCheerio(this).find('img'); + const novelCover = image.attr('data-src') || image.attr('src'); + + let novelUrl = loadedCheerio(this).find('.post-title') + .find('a') + .attr('href') || ''; + const novel: Plugin.NovelItem = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + + novels.push(novel); + }); + + return novels; + } + async parseNovelAndChapters(novelUrl: string): Promise { + const novel: Plugin.SourceNovel = { + url: novelUrl, + }; + + const body = await fetchApi(novelUrl).then(res => res.text()); + + let loadedCheerio = parseHTML(body); + + loadedCheerio('.manga-title-badges, #manga-title span').remove(); + novel.name = + loadedCheerio('.post-title h1').text().trim() || + loadedCheerio('#manga-title h1').text(); + + novel.cover = + loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || + loadedCheerio('.summary_image > a > img').attr('data-src') || + loadedCheerio('.summary_image > a > img').attr('src') || + defaultCover; + + loadedCheerio('.post-content_item, .post-content').each(function () { + const detailName = loadedCheerio(this).find('h5').text().trim(); + const detail = loadedCheerio(this).find('.summary-content').text().trim(); + + switch (detailName) { + case 'Genre(s)': + case 'التصنيفات': + novel.genres = detail.replace(/[\\t\\n]/g, ','); + break; + case 'Author(s)': + case 'المؤلف': + case 'المؤلف (ين)': + novel.author = detail; + break; + case 'Status': + case 'الحالة': + novel.status = + detail.includes('OnGoing') || detail.includes('مستمرة') + ? NovelStatus.Ongoing + : NovelStatus.Completed; + break; + } + }); + + loadedCheerio('div.summary__content .code-block,script').remove(); + novel.summary = + loadedCheerio('div.summary__content').text().trim() || + loadedCheerio('#tab-manga-about').text().trim() || + loadedCheerio('.post-content_item h5:contains("Summary")').next().text().trim(); + + let html; + + if (this.options?.useNewChapterEndpoint !== true) { + const novelId = + loadedCheerio('.rating-post-id').attr('value') || + loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; + + const formData = new FormData() + formData.append("action", "manga_get_chapters"); + formData.append("manga", novelId); - let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + html = await fetchApi( + this.site + 'wp-admin/admin-ajax.php', + { + method: 'POST', + body: formData, + }) + .then(res => res.text()); + } else { + html = await fetchApi( + novelUrl + 'ajax/chapters/', + { method: 'POST' }) + .then(res => res.text()); + } + + if (html !== '0') { + loadedCheerio = parseHTML(html); + } + + const chapters: Plugin.ChapterItem[] = []; + loadedCheerio('.wp-manga-chapter').each(function () { + const chapterName = loadedCheerio(this).find('a').text().trim(); + + let releaseDate = null; + releaseDate = loadedCheerio(this) + .find('span.chapter-release-date') + .text() + .trim(); + + if (releaseDate) { + releaseDate = parseMadaraDate(releaseDate); + } else { + /** + * Insert current date + */ + + releaseDate = dayjs().format('LL'); + } + + let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + + chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); + }); + + novel.chapters = chapters.reverse(); + return novel; + } + async parseChapter(chapterUrl: string): Promise { + const body = await fetchApi(chapterUrl).then(res => res.text()); - chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); - }); + const loadedCheerio = parseHTML(body); + const chapterText = + loadedCheerio('.text-left').html() || + loadedCheerio('.text-right').html() || + loadedCheerio('.entry-content').html() || ""; - novel.chapters = chapters.reverse(); - return novel; -}; - -export const parseChapter: Plugin.parseChapter = async (chapterUrl) => { - const url = baseUrl + "/" + "novel" + "/" + chapterUrl; - - const body = await fetchApi(chapterUrl).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - const chapterText = - loadedCheerio('.text-left').html() || - loadedCheerio('.text-right').html() || - loadedCheerio('.entry-content').html(); - - return chapterText; -}; - -export const searchNovels: Plugin.searchNovels = async (searchTerm) => { - const novels: Novel.Item[] = []; - const url = baseUrl + "?s=" + searchTerm + "&post_type=wp-manga"; - - const body = await fetchApi(url).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - - - loadedCheerio('.c-tabs-item__content').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - - let novelUrl = loadedCheerio(this) - .find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - - novels.push(novel); - }); - return novels; -}; - -export const fetchImage: Plugin.fetchImage = async (url) => { - return await fetchFile(url); -}; - -export const filters = [{"key":"sort","label":"Order by","values":[{"label":"Rating","value":"rating"},{"label":"A-Z","value":"alphabet"},{"label":"Latest","value":"latest"},{"label":"Most Views","value":"views"},{"label":"New","value":"new-manga"},{"label":"Trending","value":"trending"}],"inputType":FilterInputs.Picker},{"key":"genres","label":"GENRES","values":[{"label":"أكشن","value":"%d8%a3%d9%83%d8%b4%d9%86"},{"label":"أيتشي","value":"%d8%a3%d9%8a%d8%aa%d8%b4%d9%8a"},{"label":"استراتجي","value":"%d8%a7%d8%b3%d8%aa%d8%b1%d8%a7%d8%aa%d8%ac%d9%8a"},{"label":"العصر الحديث","value":"%d8%a7%d9%84%d8%b9%d8%b5%d8%b1-%d8%a7%d9%84%d8%ad%d8%af%d9%8a%d8%ab"},{"label":"انتقام","value":"%d8%a7%d9%86%d8%aa%d9%82%d8%a7%d9%85"},{"label":"بالغ","value":"%d8%a8%d8%a7%d9%84%d8%ba"},{"label":"بناء مملكة","value":"%d8%a8%d9%86%d8%a7%d8%a1-%d9%85%d9%85%d9%84%d9%83%d8%a9"},{"label":"بوليسي","value":"%d8%a8%d9%88%d9%84%d9%8a%d8%b3%d9%8a"},{"label":"تاريخي","value":"%d8%aa%d8%a7%d8%b1%d9%8a%d8%ae%d9%8a"},{"label":"جوسي","value":"%d8%ac%d9%88%d8%b3%d9%8a"},{"label":"حريم","value":"%d8%ad%d8%b1%d9%8a%d9%85"},{"label":"حياة يومية","value":"%d8%ad%d9%8a%d8%a7%d8%a9-%d9%8a%d9%88%d9%85%d9%8a%d8%a9"},{"label":"خيال","value":"%d8%ae%d9%8a%d8%a7%d9%84"},{"label":"خيال علمي","value":"%d8%ae%d9%8a%d8%a7%d9%84-%d8%b9%d9%84%d9%85%d9%8a"},{"label":"دراما","value":"%d8%af%d8%b1%d8%a7%d9%85%d8%a7"},{"label":"رعب","value":"%d8%b1%d8%b9%d8%a8"},{"label":"رومانسية","value":"%d8%b1%d9%88%d9%85%d8%a7%d9%86%d8%b3%d9%8a%d8%a9"},{"label":"رياضي","value":"%d8%b1%d9%8a%d8%a7%d8%b6%d9%8a"},{"label":"زيانشيا","value":"xianxia"},{"label":"سنين","value":"%d8%b3%d9%86%d9%8a%d9%86"},{"label":"شريحة حياة","value":"%d8%b4%d8%b1%d9%8a%d8%ad%d8%a9-%d8%ad%d9%8a%d8%a7%d8%a9"},{"label":"شوانهوان","value":"xuanhuan"},{"label":"شوجو","value":"%d8%b4%d9%88%d8%ac%d9%88"},{"label":"شونين","value":"%d8%b4%d9%88%d9%86%d9%8a%d9%86"},{"label":"شيانشيا","value":"%d8%b4%d9%8a%d8%a7%d9%86%d8%b4%d9%8a%d8%a7"},{"label":"عسكري","value":"%d8%b9%d8%b3%d9%83%d8%b1%d9%8a"},{"label":"غموض","value":"%d8%ba%d9%85%d9%88%d8%b6"},{"label":"فانتازيا","value":"%d9%81%d8%a7%d9%86%d8%aa%d8%a7%d8%b2%d9%8a%d8%a7"},{"label":"فنون قتالية","value":"%d9%81%d9%86%d9%88%d9%86-%d9%82%d8%aa%d8%a7%d9%84%d9%8a%d8%a9"},{"label":"قوى خارقة","value":"%d9%82%d9%88%d9%89-%d8%ae%d8%a7%d8%b1%d9%82%d8%a9"},{"label":"كوميديا","value":"%d9%83%d9%88%d9%85%d9%8a%d8%af%d9%8a%d8%a7"},{"label":"كوميك","value":"%d9%83%d9%88%d9%85%d9%8a%d9%83"},{"label":"للكبار","value":"%d9%84%d9%84%d9%83%d8%a8%d8%a7%d8%b1"},{"label":"مأساة","value":"%d9%85%d8%a3%d8%b3%d8%a7%d8%a9"},{"label":"مانجا","value":"%d9%85%d8%a7%d9%86%d8%ac%d8%a7"},{"label":"مانها","value":"%d9%85%d8%a7%d9%86%d9%87%d8%a7"},{"label":"مانهوا","value":"%d9%85%d8%a7%d9%86%d9%87%d9%88%d8%a7"},{"label":"مدرسي","value":"%d9%85%d8%af%d8%b1%d8%b3%d9%8a"},{"label":"مصاصي دماء","value":"%d9%85%d8%b5%d8%a7%d8%b5%d9%8a-%d8%af%d9%85%d8%a7%d8%a1"},{"label":"مغامرة","value":"%d9%85%d8%ba%d8%a7%d9%85%d8%b1%d8%a9"},{"label":"مكتملة","value":"%d9%85%d9%83%d8%aa%d9%85%d9%84%d8%a9"},{"label":"نفسي","value":"%d9%86%d9%81%d8%b3%d9%8a"},{"label":"نهاية العالم","value":"%d9%86%d9%87%d8%a7%d9%8a%d8%a9-%d8%a7%d9%84%d8%b9%d8%a7%d9%84%d9%85"},{"label":"واب تون","value":"%d9%88%d8%a7%d8%a8-%d8%aa%d9%88%d9%86"},{"label":"وان شوت","value":"%d9%88%d8%a7%d9%86-%d8%b4%d9%88%d8%aa"}],"inputType":FilterInputs.Picker}]; \ No newline at end of file + return chapterText; + } + async searchNovels(searchTerm: string, pageNo?: number | undefined): Promise { + const novels: Plugin.NovelItem[] = []; + const url = this.site + "?s=" + searchTerm + "&post_type=wp-manga"; + + const body = await fetchApi(url).then(res => res.text()); + + const loadedCheerio = parseHTML(body); + + + loadedCheerio('.c-tabs-item__content').each(function () { + const novelName = loadedCheerio(this).find('.post-title').text().trim(); + + let image = loadedCheerio(this).find('img'); + const novelCover = image.attr('data-src') || image.attr('src'); + + let novelUrl = loadedCheerio(this) + .find('.post-title') + .find('a') + .attr('href') || ''; + const novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + + novels.push(novel); + }); + return novels; + } + async fetchImage(url: string): Promise { + return await fetchFile(url, {}); + } +} +const plugin = new MadaraPlugin({"id":"riwyat","sourceSite":"https://riwyat.com/","sourceName":"Riwyat","filters":[{"key":"sort","label":"Order by","values":[{"label":"Rating","value":"rating"},{"label":"A-Z","value":"alphabet"},{"label":"Latest","value":"latest"},{"label":"Most Views","value":"views"},{"label":"New","value":"new-manga"},{"label":"Trending","value":"trending"}],"inputType":"Picker"},{"key":"genres","label":"GENRES","values":[{"label":"أكشن","value":"%d8%a3%d9%83%d8%b4%d9%86"},{"label":"أيتشي","value":"%d8%a3%d9%8a%d8%aa%d8%b4%d9%8a"},{"label":"استراتجي","value":"%d8%a7%d8%b3%d8%aa%d8%b1%d8%a7%d8%aa%d8%ac%d9%8a"},{"label":"العصر الحديث","value":"%d8%a7%d9%84%d8%b9%d8%b5%d8%b1-%d8%a7%d9%84%d8%ad%d8%af%d9%8a%d8%ab"},{"label":"انتقام","value":"%d8%a7%d9%86%d8%aa%d9%82%d8%a7%d9%85"},{"label":"بالغ","value":"%d8%a8%d8%a7%d9%84%d8%ba"},{"label":"بناء مملكة","value":"%d8%a8%d9%86%d8%a7%d8%a1-%d9%85%d9%85%d9%84%d9%83%d8%a9"},{"label":"بوليسي","value":"%d8%a8%d9%88%d9%84%d9%8a%d8%b3%d9%8a"},{"label":"تاريخي","value":"%d8%aa%d8%a7%d8%b1%d9%8a%d8%ae%d9%8a"},{"label":"جوسي","value":"%d8%ac%d9%88%d8%b3%d9%8a"},{"label":"حريم","value":"%d8%ad%d8%b1%d9%8a%d9%85"},{"label":"حياة يومية","value":"%d8%ad%d9%8a%d8%a7%d8%a9-%d9%8a%d9%88%d9%85%d9%8a%d8%a9"},{"label":"خيال","value":"%d8%ae%d9%8a%d8%a7%d9%84"},{"label":"خيال علمي","value":"%d8%ae%d9%8a%d8%a7%d9%84-%d8%b9%d9%84%d9%85%d9%8a"},{"label":"دراما","value":"%d8%af%d8%b1%d8%a7%d9%85%d8%a7"},{"label":"رعب","value":"%d8%b1%d8%b9%d8%a8"},{"label":"رومانسية","value":"%d8%b1%d9%88%d9%85%d8%a7%d9%86%d8%b3%d9%8a%d8%a9"},{"label":"رياضي","value":"%d8%b1%d9%8a%d8%a7%d8%b6%d9%8a"},{"label":"زيانشيا","value":"xianxia"},{"label":"سنين","value":"%d8%b3%d9%86%d9%8a%d9%86"},{"label":"شريحة حياة","value":"%d8%b4%d8%b1%d9%8a%d8%ad%d8%a9-%d8%ad%d9%8a%d8%a7%d8%a9"},{"label":"شوانهوان","value":"xuanhuan"},{"label":"شوجو","value":"%d8%b4%d9%88%d8%ac%d9%88"},{"label":"شونين","value":"%d8%b4%d9%88%d9%86%d9%8a%d9%86"},{"label":"شيانشيا","value":"%d8%b4%d9%8a%d8%a7%d9%86%d8%b4%d9%8a%d8%a7"},{"label":"عسكري","value":"%d8%b9%d8%b3%d9%83%d8%b1%d9%8a"},{"label":"غموض","value":"%d8%ba%d9%85%d9%88%d8%b6"},{"label":"فانتازيا","value":"%d9%81%d8%a7%d9%86%d8%aa%d8%a7%d8%b2%d9%8a%d8%a7"},{"label":"فنون قتالية","value":"%d9%81%d9%86%d9%88%d9%86-%d9%82%d8%aa%d8%a7%d9%84%d9%8a%d8%a9"},{"label":"قوى خارقة","value":"%d9%82%d9%88%d9%89-%d8%ae%d8%a7%d8%b1%d9%82%d8%a9"},{"label":"كوميديا","value":"%d9%83%d9%88%d9%85%d9%8a%d8%af%d9%8a%d8%a7"},{"label":"كوميك","value":"%d9%83%d9%88%d9%85%d9%8a%d9%83"},{"label":"للكبار","value":"%d9%84%d9%84%d9%83%d8%a8%d8%a7%d8%b1"},{"label":"مأساة","value":"%d9%85%d8%a3%d8%b3%d8%a7%d8%a9"},{"label":"مانجا","value":"%d9%85%d8%a7%d9%86%d8%ac%d8%a7"},{"label":"مانها","value":"%d9%85%d8%a7%d9%86%d9%87%d8%a7"},{"label":"مانهوا","value":"%d9%85%d8%a7%d9%86%d9%87%d9%88%d8%a7"},{"label":"مدرسي","value":"%d9%85%d8%af%d8%b1%d8%b3%d9%8a"},{"label":"مصاصي دماء","value":"%d9%85%d8%b5%d8%a7%d8%b5%d9%8a-%d8%af%d9%85%d8%a7%d8%a1"},{"label":"مغامرة","value":"%d9%85%d8%ba%d8%a7%d9%85%d8%b1%d8%a9"},{"label":"مكتملة","value":"%d9%85%d9%83%d8%aa%d9%85%d9%84%d8%a9"},{"label":"نفسي","value":"%d9%86%d9%81%d8%b3%d9%8a"},{"label":"نهاية العالم","value":"%d9%86%d9%87%d8%a7%d9%8a%d8%a9-%d8%a7%d9%84%d8%b9%d8%a7%d9%84%d9%85"},{"label":"واب تون","value":"%d9%88%d8%a7%d8%a8-%d8%aa%d9%88%d9%86"},{"label":"وان شوت","value":"%d9%88%d8%a7%d9%86-%d8%b4%d9%88%d8%aa"}],"inputType":"Picker"}],"options":{"useNewChapterEndpoint":true,"lang":"Arabic"}}); +export default plugin; + \ No newline at end of file diff --git a/plugins/arabic/TeamXNovel[madara].ts b/plugins/arabic/TeamXNovel[madara].ts index cad5251..060d16d 100644 --- a/plugins/arabic/TeamXNovel[madara].ts +++ b/plugins/arabic/TeamXNovel[madara].ts @@ -1,213 +1,252 @@ +import { fetchApi, fetchFile } from "@libs/fetch"; +import { Filter } from "@libs/filterInputs"; +import { Plugin } from '@typings/plugin' import { load as parseHTML } from "cheerio"; -import { fetchFile, fetchApi } from "@libs/fetch"; -import { Novel, Plugin, Chapter } from "@typings/plugin"; -import { FilterInputs } from "@libs/filterInputs"; import { defaultCover } from "@libs/defaultCover"; -import { NovelStatus } from "@libs/novelStatus" +import { NovelStatus } from "@libs/novelStatus"; import { parseMadaraDate } from "@libs/parseMadaraDate"; import dayjs from "dayjs"; -export const id = "teamxnovel"; -export const name = "TeamXNovel [madara]"; -export const icon = "multisrc/madara/icons/teamxnovel.png"; -export const version = "1.0.0"; -export const site = "https://teamxnovel.com/"; -const baseUrl = site; +interface MadaraOptionPath{ + genres?: string, + novels?: string, + novel?: string, + chapter?: string, +} -export const popularNovels: Plugin.popularNovels = async (pageNo, {filters, showLatestNovels}) => { - const novels: Novel.Item[] = []; +const MadaraDefaultPath: MadaraOptionPath = { + novels: 'novel', + novel: 'novel', + chapter: 'novel' +} - let url = site; +interface MadaraOptions { + useNewChapterEndpoint?: boolean, + path?: MadaraOptionPath, + lang?: string, + orderBy?: string +} - if (filters?.genres) { - url += "novel-genre/" + filters.genres + '/'; - } else { - url += "novel/"; +export interface MadaraMetadata { + id: string, + sourceSite: string, + sourceName: string, + options?: MadaraOptions, + filters?: Filter[], +} +class MadaraPlugin implements Plugin.PluginBase { + id: string; + name: string; + icon: string; + site: string; + version: string; + userAgent: string; + cookieString: string; + options?: MadaraOptions; + filter?: Filter[] | undefined; + + constructor(metadata: MadaraMetadata){ + this.id = metadata.id; + this.name = metadata.sourceName + "[madara]"; + const iconFileName = metadata.sourceName.replace(/\s+/g, "").toLowerCase(); + this.icon = `multisrc/madara/icons/${iconFileName}.png`; + this.site = metadata.sourceSite; + this.version = "1.0.0"; + this.userAgent = ""; + this.cookieString = ""; + this.options = metadata.options; + this.filter = metadata.filters; } + async popularNovels(pageNo: number, {filters, showLatestNovels}: Plugin.PopularNovelsOptions): Promise { + const novels: Plugin.NovelItem[] = []; - url += '/page/' + pageNo + '/' + - '?m_orderby=' + (showLatestNovels ? 'latest' : (filters?.sort || 'rating')); - - const body = await fetchApi(url).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - - loadedCheerio('.manga-title-badges').remove(); - - loadedCheerio('.page-item-detail').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - - let novelUrl = loadedCheerio(this).find('.post-title') - .find('a') - .attr('href') || ''; - const novel: Novel.Item = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - - novels.push(novel); - }); - - return novels; -}; - -export const parseNovelAndChapters: Plugin.parseNovelAndChapters = async ( - novelUrl -) => { - const novel: Novel.instance = { - url: novelUrl, - }; - - const body = await fetchApi(novelUrl).then(res => res.text()); - - let loadedCheerio = parseHTML(body); - - loadedCheerio('.manga-title-badges').remove(); - - novel.name = loadedCheerio('.post-title h1').text().trim(); - - novel.cover = - loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || - loadedCheerio('.summary_image > a > img').attr('data-src') || - loadedCheerio('.summary_image > a > img').attr('src') || - defaultCover; - - loadedCheerio('.post-content_item, .post-content').each(function () { - const detailName = loadedCheerio(this).find('h5').text().trim(); - const detail = loadedCheerio(this).find('.summary-content').text().trim(); - - switch (detailName) { - case 'Genre(s)': - case 'التصنيفات': - novel.genres = detail.replace(/[\t\n]/g, ','); - break; - case 'Author(s)': - case 'المؤلف': - case 'المؤلف (ين)': - novel.author = detail; - break; - case 'Status': - case 'الحالة': - novel.status = - detail.includes('OnGoing') || detail.includes('مستمرة') - ? NovelStatus.Ongoing - : NovelStatus.Completed; - break; - } - }); - - loadedCheerio('div.summary__content .code-block,script').remove(); - novel.summary = loadedCheerio('div.summary__content').text().trim(); - - - let html; - - if (true) { - const novelId = - loadedCheerio('.rating-post-id').attr('value') || - loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; - - const body = { - action: "manga_get_chapters", - manga: novelId, - } - html = await fetchApi( - baseUrl + 'wp-admin/admin-ajax.php', - { - method: 'POST', - body: JSON.stringify(body), - }) - .then(res => res.text()); - } else { - html = await fetchApi( - baseUrl + 'ajax/chapters/', - { method: 'POST' }) - .then(res => res.text()); - } - - if (html !== '0') { - loadedCheerio = parseHTML(html); - } - - const chapters: Chapter.Item[] = []; - loadedCheerio('.wp-manga-chapter').each(function () { - const chapterName = loadedCheerio(this).find('a').text().trim(); - - let releaseDate = null; - releaseDate = loadedCheerio(this) - .find('span.chapter-release-date') - .text() - .trim(); - - if (releaseDate) { - releaseDate = parseMadaraDate(releaseDate); + let url = this.site; + if (filters?.genres && this.options?.path?.genres) { + url += this.options?.path?.genres + filters.genres + '/'; } else { - /** - * Insert current date - */ - - releaseDate = dayjs().format('LL'); + url += this.options?.path?.novels ? this.options.path.novels : MadaraDefaultPath.novels; } + + url += '/page/' + pageNo + '/' + + '?m_orderby=' + (showLatestNovels ? 'latest' : (filters?.sort || 'rating')); + + const body = await fetchApi(url).then(res => res.text()); + + const loadedCheerio = parseHTML(body); + + loadedCheerio('.manga-title-badges').remove(); + + loadedCheerio('.page-item-detail').each(function () { + const novelName = loadedCheerio(this).find('.post-title').text().trim(); + let image = loadedCheerio(this).find('img'); + const novelCover = image.attr('data-src') || image.attr('src'); + + let novelUrl = loadedCheerio(this).find('.post-title') + .find('a') + .attr('href') || ''; + const novel: Plugin.NovelItem = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + + novels.push(novel); + }); + + return novels; + } + async parseNovelAndChapters(novelUrl: string): Promise { + const novel: Plugin.SourceNovel = { + url: novelUrl, + }; + + const body = await fetchApi(novelUrl).then(res => res.text()); + + let loadedCheerio = parseHTML(body); + + loadedCheerio('.manga-title-badges, #manga-title span').remove(); + novel.name = + loadedCheerio('.post-title h1').text().trim() || + loadedCheerio('#manga-title h1').text(); + + novel.cover = + loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || + loadedCheerio('.summary_image > a > img').attr('data-src') || + loadedCheerio('.summary_image > a > img').attr('src') || + defaultCover; + + loadedCheerio('.post-content_item, .post-content').each(function () { + const detailName = loadedCheerio(this).find('h5').text().trim(); + const detail = loadedCheerio(this).find('.summary-content').text().trim(); + + switch (detailName) { + case 'Genre(s)': + case 'التصنيفات': + novel.genres = detail.replace(/[\\t\\n]/g, ','); + break; + case 'Author(s)': + case 'المؤلف': + case 'المؤلف (ين)': + novel.author = detail; + break; + case 'Status': + case 'الحالة': + novel.status = + detail.includes('OnGoing') || detail.includes('مستمرة') + ? NovelStatus.Ongoing + : NovelStatus.Completed; + break; + } + }); + + loadedCheerio('div.summary__content .code-block,script').remove(); + novel.summary = + loadedCheerio('div.summary__content').text().trim() || + loadedCheerio('#tab-manga-about').text().trim() || + loadedCheerio('.post-content_item h5:contains("Summary")').next().text().trim(); + + let html; + + if (this.options?.useNewChapterEndpoint !== true) { + const novelId = + loadedCheerio('.rating-post-id').attr('value') || + loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; + + const formData = new FormData() + formData.append("action", "manga_get_chapters"); + formData.append("manga", novelId); - let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + html = await fetchApi( + this.site + 'wp-admin/admin-ajax.php', + { + method: 'POST', + body: formData, + }) + .then(res => res.text()); + } else { + html = await fetchApi( + novelUrl + 'ajax/chapters/', + { method: 'POST' }) + .then(res => res.text()); + } + + if (html !== '0') { + loadedCheerio = parseHTML(html); + } + + const chapters: Plugin.ChapterItem[] = []; + loadedCheerio('.wp-manga-chapter').each(function () { + const chapterName = loadedCheerio(this).find('a').text().trim(); + + let releaseDate = null; + releaseDate = loadedCheerio(this) + .find('span.chapter-release-date') + .text() + .trim(); + + if (releaseDate) { + releaseDate = parseMadaraDate(releaseDate); + } else { + /** + * Insert current date + */ + + releaseDate = dayjs().format('LL'); + } + + let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + + chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); + }); + + novel.chapters = chapters.reverse(); + return novel; + } + async parseChapter(chapterUrl: string): Promise { + const body = await fetchApi(chapterUrl).then(res => res.text()); - chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); - }); + const loadedCheerio = parseHTML(body); + const chapterText = + loadedCheerio('.text-left').html() || + loadedCheerio('.text-right').html() || + loadedCheerio('.entry-content').html() || ""; - novel.chapters = chapters.reverse(); - return novel; -}; - -export const parseChapter: Plugin.parseChapter = async (chapterUrl) => { - const url = baseUrl + "/" + "novel" + "/" + chapterUrl; - - const body = await fetchApi(chapterUrl).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - const chapterText = - loadedCheerio('.text-left').html() || - loadedCheerio('.text-right').html() || - loadedCheerio('.entry-content').html(); - - return chapterText; -}; - -export const searchNovels: Plugin.searchNovels = async (searchTerm) => { - const novels: Novel.Item[] = []; - const url = baseUrl + "?s=" + searchTerm + "&post_type=wp-manga"; - - const body = await fetchApi(url).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - - - loadedCheerio('.c-tabs-item__content').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - - let novelUrl = loadedCheerio(this) - .find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - - novels.push(novel); - }); - return novels; -}; - -export const fetchImage: Plugin.fetchImage = async (url) => { - return await fetchFile(url); -}; - -export const filters = []; \ No newline at end of file + return chapterText; + } + async searchNovels(searchTerm: string, pageNo?: number | undefined): Promise { + const novels: Plugin.NovelItem[] = []; + const url = this.site + "?s=" + searchTerm + "&post_type=wp-manga"; + + const body = await fetchApi(url).then(res => res.text()); + + const loadedCheerio = parseHTML(body); + + + loadedCheerio('.c-tabs-item__content').each(function () { + const novelName = loadedCheerio(this).find('.post-title').text().trim(); + + let image = loadedCheerio(this).find('img'); + const novelCover = image.attr('data-src') || image.attr('src'); + + let novelUrl = loadedCheerio(this) + .find('.post-title') + .find('a') + .attr('href') || ''; + const novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + + novels.push(novel); + }); + return novels; + } + async fetchImage(url: string): Promise { + return await fetchFile(url, {}); + } +} +const plugin = new MadaraPlugin({"id":"teamxnovel","sourceSite":"https://teamxnovel.com/","sourceName":"TeamXNovel","filters":[],"options":{"useNewChapterEndpoint":true,"lang":"Arabic"}}); +export default plugin; + \ No newline at end of file diff --git a/plugins/arabic/kolnovel.ts b/plugins/arabic/kolnovel.ts index f9e786e..5d0d62f 100644 --- a/plugins/arabic/kolnovel.ts +++ b/plugins/arabic/kolnovel.ts @@ -1,74 +1,73 @@ import { load as parseHTML } from "cheerio"; import { fetchApi, fetchFile } from "@libs/fetch"; -import { FilterInputs } from "@libs/filterInputs"; -import { Chapter, Novel, Plugin } from "@typings/plugin"; +import { Filter, FilterInputs } from "@libs/filterInputs"; +import { Plugin } from "@typings/plugin"; -export const id = "kolnovel"; -export const name = "KolNovel"; -export const version = "1.0.0"; -export const icon = "multisrc/wpmangastream/icons/kolnovel.png"; -export const site = "https://kolnovel.com/"; +class KolNovel implements Plugin.PluginBase { + id = "kolnovel"; + name = "KolNovel"; + icon = "multisrc/wpmangastream/icons/kolnovel.png" + site = "https://kolnovel.lol/"; + version = "1.0.0"; + userAgent = ""; + cookieString = ""; + async popularNovels(pageNo: number, {filters}: Plugin.PopularNovelsOptions): Promise { + let link = `${this.site}series/?page=${pageNo}`; + if (filters) { + if (Array.isArray(filters.genres) && filters.genres.length) { + link += filters.genres.map((i) => `&genre[]=${i}`).join(""); + } -const pluginId = id; -const baseUrl = site; - -export const popularNovels: Plugin.popularNovels = async function ( - page, - { filters } -) { - let link = `${baseUrl}series/?page=${page}`; - - if (filters) { - if (Array.isArray(filters.genres) && filters.genres.length) { - link += filters.genres.map((i) => `&genre[]=${i}`).join(""); + if (Array.isArray(filters.type) && filters.type.length) + link += filters.type.map((i) => `&lang[]=${i}`).join(""); } + link += "&status=" + (filters?.status ? filters.status : ""); - if (Array.isArray(filters.type) && filters.type.length) - link += filters.type.map((i) => `&lang[]=${i}`).join(""); + link += "&order=" + (filters?.order ? filters.order : "popular"); + const headers = new Headers(); + if(this.cookieString){ + headers.append("cookie", this.cookieString); + } + const body = await fetchApi(link, {headers}).then((result) => + result.text() + ); + + const loadedCheerio = parseHTML(body); + + const novels: Plugin.NovelItem[] = []; + + loadedCheerio("article.maindet").each(function () { + const novelName = loadedCheerio(this).find("h2").text(); + let image = loadedCheerio(this).find("img"); + const novelCover = image.attr("data-src") || image.attr("src"); + const novelUrl = loadedCheerio(this).find("h2 a").attr("href"); + + if (!novelUrl) return; + + const novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + + novels.push(novel); + }); + + return novels; } - link += "&status=" + (filters?.status ? filters.status : ""); - - link += "&order=" + (filters?.order ? filters.order : "popular"); - - const body = await fetchApi(link, {}, pluginId).then((result) => - result.text() - ); - - const loadedCheerio = parseHTML(body); - - const novels: Novel.Item[] = []; - - loadedCheerio("article.maindet").each(function () { - const novelName = loadedCheerio(this).find("h2").text(); - let image = loadedCheerio(this).find("img"); - const novelCover = image.attr("data-src") || image.attr("src"); - const novelUrl = loadedCheerio(this).find("h2 a").attr("href"); - - if (!novelUrl) return; - - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - - novels.push(novel); - }); - - return novels; -}; - -export const parseNovelAndChapters: Plugin.parseNovelAndChapters = - async function parseNovelAndChapters(novelUrl) { + async parseNovelAndChapters(novelUrl: string): Promise { const url = novelUrl; - - const result = await fetchApi(url, {}, pluginId); + const headers = new Headers(); + if(this.cookieString){ + headers.append("cookie", this.cookieString); + } + const result = await fetch(url, {headers}); const body = await result.text(); let loadedCheerio = parseHTML(body); - const novel: Novel.instance = { + const novel: Plugin.SourceNovel = { url, chapters: [], }; @@ -105,7 +104,7 @@ export const parseNovelAndChapters: Plugin.parseNovelAndChapters = .end() .text(); - let chapter: Chapter.Item[] = []; + let chapter: Plugin.ChapterItem[] = []; loadedCheerio(".eplister") .find("li") @@ -134,190 +133,193 @@ export const parseNovelAndChapters: Plugin.parseNovelAndChapters = novel.chapters = chapter.reverse(); return novel; - }; + } + async parseChapter(chapterUrl: string): Promise { + const headers = new Headers(); + if(this.cookieString){ + headers.append("cookie", this.cookieString); + } + const result = await fetch(chapterUrl, {headers}); + const body = await result.text(); + + const loadedCheerio = parseHTML(body); -export const parseChapter: Plugin.parseChapter = async function parseChapter( - chapterUrl -) { - const result = await fetchApi(chapterUrl, {}, pluginId); - const body = await result.text(); + loadedCheerio('.epcontent > div, i').remove(); + let ignore = loadedCheerio('article > style').text().trim().split(','); + ignore.push(...(ignore.pop()?.match(/^\.\w+/) || [])); + ignore.map(tag => loadedCheerio(`p${tag}`).remove()); - const loadedCheerio = parseHTML(body); + let chapterText = loadedCheerio('.epcontent').html() || ""; + + return chapterText; + } + async searchNovels(searchTerm: string, pageNo?: number | undefined): Promise { + const url = `${this.site}?s=${searchTerm}`; + const headers = new Headers(); + if(this.cookieString){ + headers.append("cookie", this.cookieString); + } + const result = await fetchApi(url, {headers}); + const body = await result.text(); - let ignore = loadedCheerio(".epcontent > p").next().attr("class"); - loadedCheerio(`p.${ignore}`).remove(); - let chapterText = loadedCheerio(".epcontent").html(); + const loadedCheerio = parseHTML(body); - return chapterText; -}; -export const searchNovels: Plugin.searchNovels = async function searchNovels( - searchTerm -) { - const url = `${baseUrl}?s=${searchTerm}`; + const novels: Plugin.NovelItem[] = []; - const result = await fetchApi(url, {}, pluginId); - const body = await result.text(); + loadedCheerio("article.maindet").each(function () { + const novelName = loadedCheerio(this).find("h2").text(); + let image = loadedCheerio(this).find("img"); + const novelCover = image.attr("data-src") || image.attr("src"); + const novelUrl = loadedCheerio(this).find("h2 a").attr("href"); - const loadedCheerio = parseHTML(body); + if (!novelUrl) return; - const novels: Novel.Item[] = []; - - loadedCheerio("article.maindet").each(function () { - const novelName = loadedCheerio(this).find("h2").text(); - let image = loadedCheerio(this).find("img"); - const novelCover = image.attr("data-src") || image.attr("src"); - const novelUrl = loadedCheerio(this).find("h2 a").attr("href"); - - if (!novelUrl) return; - - novels.push({ - name: novelName, - url: novelUrl, - cover: novelCover, + novels.push({ + name: novelName, + url: novelUrl, + cover: novelCover, + }); }); - }); - return novels; -}; + return novels; + } + async fetchImage(url: string): Promise { + return await fetchFile(url); + } + filters = [ + { + key: "order", + label: "ترتيب حسب", + values: [ + { label: "الإعداد الأولي", value: "" }, + + { label: "A-Z", value: "title" }, + + { label: "Z-A", value: "titlereverse" }, + + { label: "أخر التحديثات", value: "update" }, + + { label: "أخر ما تم إضافته", value: "latest" }, + + { label: "الرائجة", value: "popular" }, + ], + inputType: FilterInputs.Picker, + }, + { + key: "status", + label: "الحالة", + values: [ + { label: "All", value: "" }, + + { label: "Ongoing", value: "ongoing" }, + + { label: "Hiatus", value: "hiatus" }, + + { label: "Completed", value: "completed" }, + ], + inputType: FilterInputs.Picker, + }, + { + key: "type", + label: "النوع", + values: [ + { label: "إنجليزية", value: "english" }, + + { label: "روايةلايت", value: "light-novel" }, + + { label: "روايةويب", value: "web-novel" }, + + { label: "صينية", value: "chinese" }, + + { label: "عربية", value: "arabic" }, + + { label: "كورية", value: "korean" }, + + { label: "يابانية", value: "japanese" }, + ], + inputType: FilterInputs.Checkbox, + }, + { + key: "genres", + label: "تصنيف", + values: [ + { label: "Wuxia", value: "wuxia" }, + + { label: "Xianxia", value: "xianxia" }, + + { label: "XUANHUAN", value: "xuanhuan" }, + + { label: "أكشن", value: "action" }, + + { label: "إثارة", value: "excitement" }, + + { label: "إنتقالالىعالمأخر", value: "isekai" }, + + { label: "إيتشي", value: "etchi" }, + + { label: "الخيالالعلمي", value: "sci-fi" }, + + { label: "بوليسي", value: "policy" }, + + { label: "تاريخي", value: "historical" }, + + { label: "تحقيقات", value: "%d8%aa%d8%ad%d9%82%d9%8a%d9%82" }, + + { label: "تقمصشخصيات", value: "rpg" }, + + { label: "جريمة", value: "crime" }, + + { label: "جوسى", value: "josei" }, + + { label: "حريم", value: "harem" }, + + { label: "حياةمدرسية", value: "school-life" }, + + { label: "خيالي(فانتازيا)", value: "fantasy" }, + + { label: "دراما", value: "drama" }, + + { label: "رعب", value: "horror" }, + + { label: "رومانسي", value: "romantic" }, + + { label: "سحر", value: "magic" }, + + { label: "سينن", value: "senen" }, + + { label: "شريحةمنالحياة", value: "slice-of-life" }, + + { label: "شوجو", value: "shojo" }, + + { label: "شونين", value: "shonen" }, + + { label: "طبي", value: "medical" }, + + { label: "ظواهرخارقةللطبيعة", value: "supernatural" }, + + { label: "غموض", value: "mysteries" }, + + { label: "فنونالقتال", value: "martial-arts" }, + + { label: "قوىخارقة", value: "superpower" }, + + { label: "كوميدي", value: "comedy" }, + + { label: "مأساوي", value: "tragedy" }, + + { label: "مابعدالكارثة", value: "after-the-disaster" }, + + { label: "مغامرة", value: "adventure" }, + + { label: "ميكا", value: "mechanical" }, + + { label: "ناضج", value: "mature" }, + + { label: "نفسي", value: "psychological" }, + ], + inputType: FilterInputs.Checkbox, + }, + ]; +} -export const fetchImage: Plugin.fetchImage = async function fetchImage(url) { - const headers = { - Referer: baseUrl, - }; - return await fetchFile(url, { headers: headers }); -}; - -export const filters = [ - { - key: "order", - label: "ترتيب حسب", - values: [ - { label: "الإعداد الأولي", value: "" }, - - { label: "A-Z", value: "title" }, - - { label: "Z-A", value: "titlereverse" }, - - { label: "أخر التحديثات", value: "update" }, - - { label: "أخر ما تم إضافته", value: "latest" }, - - { label: "الرائجة", value: "popular" }, - ], - inputType: FilterInputs.Picker, - }, - { - key: "status", - label: "الحالة", - values: [ - { label: "All", value: "" }, - - { label: "Ongoing", value: "ongoing" }, - - { label: "Hiatus", value: "hiatus" }, - - { label: "Completed", value: "completed" }, - ], - inputType: FilterInputs.Picker, - }, - { - key: "type", - label: "النوع", - values: [ - { label: "إنجليزية", value: "english" }, - - { label: "روايةلايت", value: "light-novel" }, - - { label: "روايةويب", value: "web-novel" }, - - { label: "صينية", value: "chinese" }, - - { label: "عربية", value: "arabic" }, - - { label: "كورية", value: "korean" }, - - { label: "يابانية", value: "japanese" }, - ], - inputType: FilterInputs.Checkbox, - }, - { - key: "genres", - label: "تصنيف", - values: [ - { label: "Wuxia", value: "wuxia" }, - - { label: "Xianxia", value: "xianxia" }, - - { label: "XUANHUAN", value: "xuanhuan" }, - - { label: "أكشن", value: "action" }, - - { label: "إثارة", value: "excitement" }, - - { label: "إنتقالالىعالمأخر", value: "isekai" }, - - { label: "إيتشي", value: "etchi" }, - - { label: "الخيالالعلمي", value: "sci-fi" }, - - { label: "بوليسي", value: "policy" }, - - { label: "تاريخي", value: "historical" }, - - { label: "تحقيقات", value: "%d8%aa%d8%ad%d9%82%d9%8a%d9%82" }, - - { label: "تقمصشخصيات", value: "rpg" }, - - { label: "جريمة", value: "crime" }, - - { label: "جوسى", value: "josei" }, - - { label: "حريم", value: "harem" }, - - { label: "حياةمدرسية", value: "school-life" }, - - { label: "خيالي(فانتازيا)", value: "fantasy" }, - - { label: "دراما", value: "drama" }, - - { label: "رعب", value: "horror" }, - - { label: "رومانسي", value: "romantic" }, - - { label: "سحر", value: "magic" }, - - { label: "سينن", value: "senen" }, - - { label: "شريحةمنالحياة", value: "slice-of-life" }, - - { label: "شوجو", value: "shojo" }, - - { label: "شونين", value: "shonen" }, - - { label: "طبي", value: "medical" }, - - { label: "ظواهرخارقةللطبيعة", value: "supernatural" }, - - { label: "غموض", value: "mysteries" }, - - { label: "فنونالقتال", value: "martial-arts" }, - - { label: "قوىخارقة", value: "superpower" }, - - { label: "كوميدي", value: "comedy" }, - - { label: "مأساوي", value: "tragedy" }, - - { label: "مابعدالكارثة", value: "after-the-disaster" }, - - { label: "مغامرة", value: "adventure" }, - - { label: "ميكا", value: "mechanical" }, - - { label: "ناضج", value: "mature" }, - - { label: "نفسي", value: "psychological" }, - ], - inputType: FilterInputs.Checkbox, - }, -]; +export default new KolNovel(); \ No newline at end of file diff --git a/plugins/chinese/.chinese b/plugins/chinese/.gitkeep similarity index 100% rename from plugins/chinese/.chinese rename to plugins/chinese/.gitkeep diff --git a/plugins/chinese/linovelib.ts b/plugins/chinese/linovelib.ts new file mode 100644 index 0000000..b73ad0d --- /dev/null +++ b/plugins/chinese/linovelib.ts @@ -0,0 +1,559 @@ +import { CheerioAPI, load as parseHTML } from "cheerio"; +import { fetchApi, fetchFile } from "@libs/fetch"; +import { Filter, FilterInputs } from "@libs/filterInputs"; +import { Plugin } from "@typings/plugin"; +import { showToast } from "@libs/showToast"; + +class Linovelib implements Plugin.PluginBase { + id = "linovelib"; + name = "Linovelib"; + icon = "src/cn/linovelib/icon.png"; + site = "https://w.linovelib.com"; + version = "1.0.0"; + userAgent = ""; + cookieString = ""; + async popularNovels(pageNo: number, {filters}: Plugin.PopularNovelsOptions): Promise { + let link = `${this.site}/top/`; + + link += (filters?.sort ? filters.sort : "monthvisit"); + + link += `/${pageNo}.html`; + + const headers = new Headers(); + if(this.cookieString){ + headers.append("cookie", this.cookieString); + } + const body = await fetchApi(link, {headers}).then((result) => + result.text() + ); + + const loadedCheerio = parseHTML(body); + + const novels: Plugin.NovelItem[] = []; + + loadedCheerio(".module-rank-booklist .book-layout").each((i, el) => { + let url = loadedCheerio(el).attr('href'); + + const novelName = loadedCheerio(el).find('.book-title').text(); + const novelCover = loadedCheerio(el) + .find('img.book-cover') + .attr('data-src'); + const novelUrl = this.site + url; + + if (!url) return; + + const novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + + novels.push(novel); + }); + + return novels; + }; + + async parseNovelAndChapters(novelUrl: string): Promise { + const url = novelUrl; + const headers = new Headers(); + if(this.cookieString){ + headers.append("cookie", this.cookieString); + } + const result = await fetchApi(url, {headers}); + const body = await result.text(); + + let loadedCheerio = parseHTML(body); + + const novel: Plugin.SourceNovel = { + url, + chapters: [], + }; + + novel.name = loadedCheerio('#bookDetailWrapper .book-title').text(); + + novel.cover = loadedCheerio('#bookDetailWrapper img.book-cover').attr( + 'src', + ); + + novel.summary = loadedCheerio('#bookSummary content').text(); + + novel.author = loadedCheerio('#bookDetailWrapper .book-rand-a a').text(); + + // TODO: Need some regex and dirty selector to get it + // Need to look into how to translate that message + novel.status = undefined; + + novel.genres = loadedCheerio('.tag-small.red') + .children("a") + .map((i, el) => loadedCheerio(el).text()) + .toArray() + .join(","); + + // Table of Content is on a different page than the summary page + let chapter: Plugin.ChapterItem[] = []; + + const idPattern = /\/(\d+)\.html/; + const novelId = url.match(idPattern)?.[1]; + + const chaptersUrl = this.site + loadedCheerio('#btnReadBook').attr('href'); + const chaptersResult = await fetchApi(chaptersUrl, {headers}); + const chaptersBody = await chaptersResult.text(); + + const chaptersLoadedCheerio = parseHTML(chaptersBody); + + let volumeName:string, chapterId:number; + + chaptersLoadedCheerio('#volumes .chapter-li').each((i, el) => { + if (chaptersLoadedCheerio(el).hasClass('chapter-bar')) { + volumeName = chaptersLoadedCheerio(el).text(); + } else { + const urlPart = chaptersLoadedCheerio(el) + .find('.chapter-li-a') + .attr('href'); + const chapterIdMatch = urlPart?.match(idPattern); + + // Sometimes the href attribute does not contain the url, but javascript:cid(0). + // Increment the previous chapter ID should result in the right URL + if (chapterIdMatch) { + chapterId = +chapterIdMatch[1]; + } else { + chapterId++; + }} + + + const chapterUrl = `${this.site}/novel/${novelId}/${chapterId}.html`; + const chapterName = + volumeName + + ' — ' + + chaptersLoadedCheerio(el).find('.chapter-index').text().trim(); + const releaseDate = null; + + if (!chapterId) return; + + chapter.push({ + name: chapterName, + releaseTime: releaseDate, + url: chapterUrl, + }); + }); + + novel.chapters = chapter; + + return novel; + } + + async parseChapter(chapterUrl: string): Promise { + const headers = new Headers(); + if(this.cookieString){ + headers.append("cookie", this.cookieString); + } + let chapterName, chapterText = "", hasNextPage, pageHasNextPage, pageText = ""; + let pageNumber = 1; + + /* + * TODO: Maybe there are other ways to get the translation table + * It is embed and encrypted inside readtool.js + * UPDATE: Decrypted, see skillgg + */ + // const mapping_dict = { + // '“': '「', + // '’': '』', + // '': '是', + // '': '不', + // '': '好', + // '': '个', + // '': '开', + // '': '样', + // '': '想', + // '': '说', + // '': '年', + // '': '那', + // '': '她', + // '': '美', + // '': '自', + // '': '家', + // '': '而', + // '': '去', + // '': '都', + // '': '于', + // '': '舔', + // '': '他', + // '': '只', + // '': '看', + // '': '来', + // '': '用', + // '': '道', + // '': '得', + // '': '乳', + // '': '茎', + // '': '肉', + // '': '胸', + // '': '淫', + // '': '性', + // '': '骚', + // '”': '」', + // '': '的', + // '': '当', + // '': '人', + // '': '有', + // '': '上', + // '': '到', + // '': '地', + // '': '中', + // '': '生', + // '': '着', + // '': '和', + // '': '起', + // '': '交', + // '': '以', + // '': '可', + // '': '过', + // '': '能', + // '': '多', + // '': '心', + // '': '小', + // '': '成', + // '': '了', + // '': '把', + // '': '发', + // '': '第', + // '': '子', + // '': '事', + // '': '阴', + // '': '欲', + // '': '里', + // '': '私', + // '': '臀', + // '': '脱', + // '': '唇', + // '‘': '『', + // '': '一', + // '': '我', + // '': '在', + // '': '这', + // '': '们', + // '': '时', + // '': '为', + // '': '你', + // '': '国', + // '': '就', + // '': '要', + // '': '也', + // '': '后', + // '': '没', + // '': '下', + // '': '天', + // '': '对', + // '': '然', + // '': '学', + // '': '之', + // '': '出', + // '': '没', + // '': '如', + // '': '还', + // '': '大', + // '': '作', + // '': '种', + // '': '液', + // '': '呻', + // '': '射', + // '': '穴', + // '': '么', + // '': '裸', + // }; + const skillgg: Record = { + '\u201c': '\u300c', + '\u201d': '\u300d', + '\u2018': '\u300e', + '\u2019': '\u300f', + '\ue82c': '\u7684', + '\ue852': '\u4e00', + '\ue82d': '\u662f', + '\ue819': '\u4e86', + '\ue856': '\u6211', + '\ue857': '\u4e0d', + '\ue816': '\u4eba', + '\ue83c': '\u5728', + '\ue830': '\u4ed6', + '\ue82e': '\u6709', + '\ue836': '\u8fd9', + '\ue859': '\u4e2a', + '\ue80a': '\u4e0a', + '\ue855': '\u4eec', + '\ue842': '\u6765', + '\ue858': '\u5230', + '\ue80b': '\u65f6', + '\ue81f': '\u5927', + '\ue84a': '\u5730', + '\ue853': '\u4e3a', + '\ue81e': '\u5b50', + '\ue822': '\u4e2d', + '\ue813': '\u4f60', + '\ue85b': '\u8bf4', + '\ue807': '\u751f', + '\ue818': '\u56fd', + '\ue810': '\u5e74', + '\ue812': '\u7740', + '\ue851': '\u5c31', + '\ue801': '\u90a3', + '\ue80c': '\u548c', + '\ue815': '\u8981', + '\ue84c': '\u5979', + '\ue840': '\u51fa', + '\ue848': '\u4e5f', + '\ue835': '\u5f97', + '\ue800': '\u91cc', + '\ue826': '\u540e', + '\ue863': '\u81ea', + '\ue861': '\u4ee5', + '\ue854': '\u4f1a', + '\ue827': '\u5bb6', + '\ue83b': '\u53ef', + '\ue85d': '\u4e0b', + '\ue84d': '\u800c', + '\ue862': '\u8fc7', + '\ue81c': '\u5929', + '\ue81d': '\u53bb', + '\ue860': '\u80fd', + '\ue843': '\u5bf9', + '\ue82f': '\u5c0f', + '\ue802': '\u591a', + '\ue831': '\u7136', + '\ue84b': '\u4e8e', + '\ue837': '\u5fc3', + '\ue829': '\u5b66', + '\ue85e': '\u4e48', + '\ue83a': '\u4e4b', + '\ue832': '\u90fd', + '\ue808': '\u597d', + '\ue841': '\u770b', + '\ue821': '\u8d77', + '\ue845': '\u53d1', + '\ue803': '\u5f53', + '\ue828': '\u6ca1', + '\ue81b': '\u6210', + '\ue83e': '\u53ea', + '\ue820': '\u5982', + '\ue84e': '\u4e8b', + '\ue85a': '\u628a', + '\ue806': '\u8fd8', + '\ue83f': '\u7528', + '\ue833': '\u7b2c', + '\ue811': '\u6837', + '\ue804': '\u9053', + '\ue814': '\u60f3', + '\ue80f': '\u4f5c', + '\ue84f': '\u79cd', + '\ue80e': '\u5f00', + '\ue823': '\u7f8e', + '\ue849': '\u4e73', + '\ue805': '\u9634', + '\ue809': '\u6db2', + '\ue81a': '\u830e', + '\ue844': '\u6b32', + '\ue847': '\u547b', + '\ue850': '\u8089', + '\ue824': '\u4ea4', + '\ue85f': '\u6027', + '\ue817': '\u80f8', + '\ue85c': '\u79c1', + '\ue838': '\u7a74', + '\ue82a': '\u6deb', + '\ue83d': '\u81c0', + '\ue82b': '\u8214', + '\ue80d': '\u5c04', + '\ue839': '\u8131', + '\ue834': '\u88f8', + '\ue846': '\u9a9a', + '\ue825': '\u5507', + }; + const addPage = async (pageCheerio: CheerioAPI) => { + const formatPage = async () => { + // Remove JS + pageCheerio('#ccacontent .cgo').remove(); + + // Load lazyloaded images + pageCheerio('#ccacontent img.imagecontent').each((i, el) => { + // Sometimes images are either in data-src or src + const imgSrc = + pageCheerio(el).attr('data-src') || pageCheerio(el).attr('src'); + if (imgSrc) { + // The original CDN URL is locked behind a CF-like challenge, switch the URL to bypass that + // There are no react-native-url-polyfill lib, can't use URL API + const regex = /\/\/.+\.com\//; + const imgUrl = imgSrc.replace(regex, '//img.linovelib.com/'); + // Clean up img element + pageCheerio(el) + .attr('src', imgUrl) + .removeAttr('data-src') + .removeClass('lazyload'); + } + }); + + // Recover the original character + pageText = pageCheerio('#ccacontent').html() || ""; + pageText = pageText.replace(/./g, char => skillgg[char] || char); + + return Promise.resolve(); + }; + + await formatPage(); + chapterName = + pageCheerio('#atitle + h3').text() + + ' — ' + + pageCheerio('#atitle').text(); + if (chapterText === "") { + chapterText = '

' + chapterName + '

'; + } + chapterText += pageText; + }; + + const loadPage = async (url:string) => { + const result = await fetchApi(url, {headers}); + const body = await result.text(); + const pageCheerio = parseHTML(body); + await addPage(pageCheerio); + pageHasNextPage = + pageCheerio('#footlink a:last').text() === '下一页' ? true : false; + return { pageCheerio, pageHasNextPage }; + }; + + let url = chapterUrl; + do { + const page = await loadPage(url); + hasNextPage = page.pageHasNextPage; + if (hasNextPage === true) { + pageNumber++; + url = chapterUrl.replace(/\.html/gi, `_${pageNumber}` + '.html'); + } + } while (hasNextPage === true); + + return chapterText; + } + + async searchNovels(searchTerm: string, pageNo?: number | undefined): Promise { + const searchUrl = `${this.site}/search/`; + const Term = encodeURI(searchTerm); + const headers = new Headers(); + if(this.cookieString){ + headers.append("cookie", this.cookieString); + } + let NextPage, NoNextPage:boolean, DeadEnd; + pageNo = 1; + const novels: Plugin.NovelItem[] = []; + + const addPage = async (pageCheerio: CheerioAPI, redirect: string) => { + const loadSearchResults = () => { + pageCheerio('.book-ol .book-layout').each((i, el) => { + let nUrl = pageCheerio(el).attr('href'); + + const novelName = pageCheerio(el).find('.book-title').text(); + const novelCover = pageCheerio(el) + .find('img.book-cover') + .attr('data-src'); + const novelUrl = this.site + nUrl; + + if (!nUrl) return; + + novels.push({ + name: novelName, + url: novelUrl, + cover: novelCover, + }); + } + ); + }; + + const novelResults = pageCheerio('.book-ol a.book-layout'); + if (novelResults.length === 0) { + showToast('Bypass check by searching in Webview'); + } else { + loadSearchResults(); + } + + if (redirect.length) { + novels.length = 0; + const novelName = pageCheerio('#bookDetailWrapper .book-title').text(); + + const novelCover = pageCheerio('#bookDetailWrapper img.book-cover').attr( + 'src', + ); + const novelUrl = + this.site + + pageCheerio('#btnReadBook').attr('href')?.slice(0, -8) + + '.html'; + novels.push({ + name: novelName, + url: novelUrl, + cover: novelCover, + }); + } + }; + + const loadPage = async (url:string) => { + const result = await fetchApi(url, {headers}); + const body = await result.text(); + const pageCheerio = parseHTML(body); + const redirect = pageCheerio('div.book-layout').text(); + await addPage(pageCheerio, redirect); + NextPage = pageCheerio('.next').attr('href'); + if (!NextPage) { + NoNextPage === true; + } else { + NoNextPage = NextPage === '#' ? true : false; + } + return { pageCheerio, NoNextPage }; + }; + + let url = `${searchUrl}${Term}_${pageNo}.html`; + do { + const page = await loadPage(url); + DeadEnd = page.NoNextPage; + if (DeadEnd === false) { + pageNo++; + url = `${searchUrl}${Term}_${pageNo}.html`; + } + } while (DeadEnd === false); + + return novels; + }; + + async fetchImage(url: string): Promise { + return await fetchFile(url); + } + filters = [ + { + key: "sort", + label: "Sort By", + values: [ + { label: "月点击榜", value: "monthvisit" }, + + { label: "周点击榜", value: "weekvisit" }, + + { label: "月推荐榜", value: "monthvote" }, + + { label: "周推荐榜", value: "weekvote" }, + + { label: "月鲜花榜", value: "monthflower" }, + + { label: "周鲜花榜", value: "weekflower" }, + + { label: "月鸡蛋榜", value: "monthegg" }, + + { label: "周鸡蛋榜", value: "weekegg" }, + + { label: "最近更新", value: "lastupdate" }, + + { label: "最新入库", value: "postdate" }, + + { label: "收藏榜", value: "goodnum" }, + + { label: "新书榜", value: "newhot" }, + ], + inputType: FilterInputs.Picker, + }, + ]; +} + +export default new Linovelib(); diff --git a/plugins/english/.english b/plugins/english/.english deleted file mode 100644 index e69de29..0000000 diff --git a/plugins/english/BoxNovel[madara].ts b/plugins/english/BoxNovel[madara].ts index a472494..a82bf1a 100644 --- a/plugins/english/BoxNovel[madara].ts +++ b/plugins/english/BoxNovel[madara].ts @@ -1,213 +1,252 @@ +import { fetchApi, fetchFile } from "@libs/fetch"; +import { Filter } from "@libs/filterInputs"; +import { Plugin } from '@typings/plugin' import { load as parseHTML } from "cheerio"; -import { fetchFile, fetchApi } from "@libs/fetch"; -import { Novel, Plugin, Chapter } from "@typings/plugin"; -import { FilterInputs } from "@libs/filterInputs"; import { defaultCover } from "@libs/defaultCover"; -import { NovelStatus } from "@libs/novelStatus" +import { NovelStatus } from "@libs/novelStatus"; import { parseMadaraDate } from "@libs/parseMadaraDate"; import dayjs from "dayjs"; -export const id = "boxnovel"; -export const name = "BoxNovel [madara]"; -export const icon = "multisrc/madara/icons/boxnovel.png"; -export const version = "1.0.0"; -export const site = "https://boxnovel.com/"; -const baseUrl = site; +interface MadaraOptionPath{ + genres?: string, + novels?: string, + novel?: string, + chapter?: string, +} -export const popularNovels: Plugin.popularNovels = async (pageNo, {filters, showLatestNovels}) => { - const novels: Novel.Item[] = []; +const MadaraDefaultPath: MadaraOptionPath = { + novels: 'novel', + novel: 'novel', + chapter: 'novel' +} - let url = site; +interface MadaraOptions { + useNewChapterEndpoint?: boolean, + path?: MadaraOptionPath, + lang?: string, + orderBy?: string +} - if (filters?.genres) { - url += "manga-genre/" + filters.genres + '/'; - } else { - url += "novel/"; +export interface MadaraMetadata { + id: string, + sourceSite: string, + sourceName: string, + options?: MadaraOptions, + filters?: Filter[], +} +class MadaraPlugin implements Plugin.PluginBase { + id: string; + name: string; + icon: string; + site: string; + version: string; + userAgent: string; + cookieString: string; + options?: MadaraOptions; + filter?: Filter[] | undefined; + + constructor(metadata: MadaraMetadata){ + this.id = metadata.id; + this.name = metadata.sourceName + "[madara]"; + const iconFileName = metadata.sourceName.replace(/\s+/g, "").toLowerCase(); + this.icon = `multisrc/madara/icons/${iconFileName}.png`; + this.site = metadata.sourceSite; + this.version = "1.0.0"; + this.userAgent = ""; + this.cookieString = ""; + this.options = metadata.options; + this.filter = metadata.filters; } + async popularNovels(pageNo: number, {filters, showLatestNovels}: Plugin.PopularNovelsOptions): Promise { + const novels: Plugin.NovelItem[] = []; - url += '/page/' + pageNo + '/' + - '?m_orderby=' + (showLatestNovels ? 'latest' : (filters?.sort || 'rating')); - - const body = await fetchApi(url).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - - loadedCheerio('.manga-title-badges').remove(); - - loadedCheerio('.page-item-detail').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - - let novelUrl = loadedCheerio(this).find('.post-title') - .find('a') - .attr('href') || ''; - const novel: Novel.Item = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - - novels.push(novel); - }); - - return novels; -}; - -export const parseNovelAndChapters: Plugin.parseNovelAndChapters = async ( - novelUrl -) => { - const novel: Novel.instance = { - url: novelUrl, - }; - - const body = await fetchApi(novelUrl).then(res => res.text()); - - let loadedCheerio = parseHTML(body); - - loadedCheerio('.manga-title-badges').remove(); - - novel.name = loadedCheerio('.post-title h1').text().trim(); - - novel.cover = - loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || - loadedCheerio('.summary_image > a > img').attr('data-src') || - loadedCheerio('.summary_image > a > img').attr('src') || - defaultCover; - - loadedCheerio('.post-content_item, .post-content').each(function () { - const detailName = loadedCheerio(this).find('h5').text().trim(); - const detail = loadedCheerio(this).find('.summary-content').text().trim(); - - switch (detailName) { - case 'Genre(s)': - case 'التصنيفات': - novel.genres = detail.replace(/[\t\n]/g, ','); - break; - case 'Author(s)': - case 'المؤلف': - case 'المؤلف (ين)': - novel.author = detail; - break; - case 'Status': - case 'الحالة': - novel.status = - detail.includes('OnGoing') || detail.includes('مستمرة') - ? NovelStatus.Ongoing - : NovelStatus.Completed; - break; - } - }); - - loadedCheerio('div.summary__content .code-block,script').remove(); - novel.summary = loadedCheerio('div.summary__content').text().trim(); - - - let html; - - if (true) { - const novelId = - loadedCheerio('.rating-post-id').attr('value') || - loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; - - const body = { - action: "manga_get_chapters", - manga: novelId, - } - html = await fetchApi( - baseUrl + 'wp-admin/admin-ajax.php', - { - method: 'POST', - body: JSON.stringify(body), - }) - .then(res => res.text()); - } else { - html = await fetchApi( - baseUrl + 'ajax/chapters/', - { method: 'POST' }) - .then(res => res.text()); - } - - if (html !== '0') { - loadedCheerio = parseHTML(html); - } - - const chapters: Chapter.Item[] = []; - loadedCheerio('.wp-manga-chapter').each(function () { - const chapterName = loadedCheerio(this).find('a').text().trim(); - - let releaseDate = null; - releaseDate = loadedCheerio(this) - .find('span.chapter-release-date') - .text() - .trim(); - - if (releaseDate) { - releaseDate = parseMadaraDate(releaseDate); + let url = this.site; + if (filters?.genres && this.options?.path?.genres) { + url += this.options?.path?.genres + filters.genres + '/'; } else { - /** - * Insert current date - */ - - releaseDate = dayjs().format('LL'); + url += this.options?.path?.novels ? this.options.path.novels : MadaraDefaultPath.novels; } + + url += '/page/' + pageNo + '/' + + '?m_orderby=' + (showLatestNovels ? 'latest' : (filters?.sort || 'rating')); + + const body = await fetchApi(url).then(res => res.text()); + + const loadedCheerio = parseHTML(body); + + loadedCheerio('.manga-title-badges').remove(); + + loadedCheerio('.page-item-detail').each(function () { + const novelName = loadedCheerio(this).find('.post-title').text().trim(); + let image = loadedCheerio(this).find('img'); + const novelCover = image.attr('data-src') || image.attr('src'); + + let novelUrl = loadedCheerio(this).find('.post-title') + .find('a') + .attr('href') || ''; + const novel: Plugin.NovelItem = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + + novels.push(novel); + }); + + return novels; + } + async parseNovelAndChapters(novelUrl: string): Promise { + const novel: Plugin.SourceNovel = { + url: novelUrl, + }; + + const body = await fetchApi(novelUrl).then(res => res.text()); + + let loadedCheerio = parseHTML(body); + + loadedCheerio('.manga-title-badges, #manga-title span').remove(); + novel.name = + loadedCheerio('.post-title h1').text().trim() || + loadedCheerio('#manga-title h1').text(); + + novel.cover = + loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || + loadedCheerio('.summary_image > a > img').attr('data-src') || + loadedCheerio('.summary_image > a > img').attr('src') || + defaultCover; + + loadedCheerio('.post-content_item, .post-content').each(function () { + const detailName = loadedCheerio(this).find('h5').text().trim(); + const detail = loadedCheerio(this).find('.summary-content').text().trim(); + + switch (detailName) { + case 'Genre(s)': + case 'التصنيفات': + novel.genres = detail.replace(/[\\t\\n]/g, ','); + break; + case 'Author(s)': + case 'المؤلف': + case 'المؤلف (ين)': + novel.author = detail; + break; + case 'Status': + case 'الحالة': + novel.status = + detail.includes('OnGoing') || detail.includes('مستمرة') + ? NovelStatus.Ongoing + : NovelStatus.Completed; + break; + } + }); + + loadedCheerio('div.summary__content .code-block,script').remove(); + novel.summary = + loadedCheerio('div.summary__content').text().trim() || + loadedCheerio('#tab-manga-about').text().trim() || + loadedCheerio('.post-content_item h5:contains("Summary")').next().text().trim(); + + let html; + + if (this.options?.useNewChapterEndpoint !== true) { + const novelId = + loadedCheerio('.rating-post-id').attr('value') || + loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; + + const formData = new FormData() + formData.append("action", "manga_get_chapters"); + formData.append("manga", novelId); - let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + html = await fetchApi( + this.site + 'wp-admin/admin-ajax.php', + { + method: 'POST', + body: formData, + }) + .then(res => res.text()); + } else { + html = await fetchApi( + novelUrl + 'ajax/chapters/', + { method: 'POST' }) + .then(res => res.text()); + } + + if (html !== '0') { + loadedCheerio = parseHTML(html); + } + + const chapters: Plugin.ChapterItem[] = []; + loadedCheerio('.wp-manga-chapter').each(function () { + const chapterName = loadedCheerio(this).find('a').text().trim(); + + let releaseDate = null; + releaseDate = loadedCheerio(this) + .find('span.chapter-release-date') + .text() + .trim(); + + if (releaseDate) { + releaseDate = parseMadaraDate(releaseDate); + } else { + /** + * Insert current date + */ + + releaseDate = dayjs().format('LL'); + } + + let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + + chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); + }); + + novel.chapters = chapters.reverse(); + return novel; + } + async parseChapter(chapterUrl: string): Promise { + const body = await fetchApi(chapterUrl).then(res => res.text()); - chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); - }); + const loadedCheerio = parseHTML(body); + const chapterText = + loadedCheerio('.text-left').html() || + loadedCheerio('.text-right').html() || + loadedCheerio('.entry-content').html() || ""; - novel.chapters = chapters.reverse(); - return novel; -}; - -export const parseChapter: Plugin.parseChapter = async (chapterUrl) => { - const url = baseUrl + "/" + "novel" + "/" + chapterUrl; - - const body = await fetchApi(chapterUrl).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - const chapterText = - loadedCheerio('.text-left').html() || - loadedCheerio('.text-right').html() || - loadedCheerio('.entry-content').html(); - - return chapterText; -}; - -export const searchNovels: Plugin.searchNovels = async (searchTerm) => { - const novels: Novel.Item[] = []; - const url = baseUrl + "?s=" + searchTerm + "&post_type=wp-manga"; - - const body = await fetchApi(url).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - - - loadedCheerio('.c-tabs-item__content').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - - let novelUrl = loadedCheerio(this) - .find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - - novels.push(novel); - }); - return novels; -}; - -export const fetchImage: Plugin.fetchImage = async (url) => { - return await fetchFile(url); -}; - -export const filters = [{"key":"sort","label":"Order by","values":[{"label":"Rating","value":"rating"},{"label":"A-Z","value":"alphabet"},{"label":"Latest","value":"latest"},{"label":"Most Views","value":"views"},{"label":"New","value":"new-manga"},{"label":"Trending","value":"trending"}],"inputType":FilterInputs.Picker},{"key":"genres","label":"GENRES","values":[{"label":"Action","value":"action"},{"label":"Adventure","value":"adventure"},{"label":"Comedy","value":"comedy"},{"label":"Drama","value":"drama"},{"label":"Ecchi","value":"ecchi"},{"label":"Fantasy","value":"fantasy"},{"label":"Gender Bender","value":"gender-bender"},{"label":"Harem","value":"harem"},{"label":"Historical","value":"historical"},{"label":"Horror","value":"horror"},{"label":"Josei","value":"josei"},{"label":"Martial Arts","value":"martial-arts"},{"label":"Mature","value":"mature"},{"label":"Mecha","value":"mecha"},{"label":"Mystery","value":"mystery"},{"label":"Psychological","value":"psychological"},{"label":"Romance","value":"romance"},{"label":"School Life","value":"school-life"},{"label":"Sci-fi","value":"sci-fi"},{"label":"Seinen","value":"seinen"},{"label":"Shoujo","value":"shoujo"},{"label":"Shounen","value":"shounen"},{"label":"Slice of Life","value":"slice-of-life"},{"label":"Smut","value":"smut"},{"label":"Sports","value":"sports"},{"label":"Supernatural","value":"supernatural"},{"label":"Tragedy","value":"tragedy"},{"label":"Wuxia","value":"wuxia"},{"label":"Xianxia","value":"xianxia"},{"label":"Xuanhuan","value":"xuanhuan"},{"label":"Yaoi","value":"yaoi"}],"inputType":FilterInputs.Picker}]; \ No newline at end of file + return chapterText; + } + async searchNovels(searchTerm: string, pageNo?: number | undefined): Promise { + const novels: Plugin.NovelItem[] = []; + const url = this.site + "?s=" + searchTerm + "&post_type=wp-manga"; + + const body = await fetchApi(url).then(res => res.text()); + + const loadedCheerio = parseHTML(body); + + + loadedCheerio('.c-tabs-item__content').each(function () { + const novelName = loadedCheerio(this).find('.post-title').text().trim(); + + let image = loadedCheerio(this).find('img'); + const novelCover = image.attr('data-src') || image.attr('src'); + + let novelUrl = loadedCheerio(this) + .find('.post-title') + .find('a') + .attr('href') || ''; + const novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + + novels.push(novel); + }); + return novels; + } + async fetchImage(url: string): Promise { + return await fetchFile(url, {}); + } +} +const plugin = new MadaraPlugin({"id":"boxnovel","sourceSite":"https://boxnovel.com/","sourceName":"BoxNovel","filters":[{"key":"sort","label":"Order by","values":[{"label":"Rating","value":"rating"},{"label":"A-Z","value":"alphabet"},{"label":"Latest","value":"latest"},{"label":"Most Views","value":"views"},{"label":"New","value":"new-manga"},{"label":"Trending","value":"trending"}],"inputType":"Picker"},{"key":"genres","label":"GENRES","values":[{"label":"Action","value":"action"},{"label":"Adventure","value":"adventure"},{"label":"Comedy","value":"comedy"},{"label":"Drama","value":"drama"},{"label":"Ecchi","value":"ecchi"},{"label":"Fantasy","value":"fantasy"},{"label":"Gender Bender","value":"gender-bender"},{"label":"Harem","value":"harem"},{"label":"Historical","value":"historical"},{"label":"Horror","value":"horror"},{"label":"Josei","value":"josei"},{"label":"Martial Arts","value":"martial-arts"},{"label":"Mature","value":"mature"},{"label":"Mecha","value":"mecha"},{"label":"Mystery","value":"mystery"},{"label":"Psychological","value":"psychological"},{"label":"Romance","value":"romance"},{"label":"School Life","value":"school-life"},{"label":"Sci-fi","value":"sci-fi"},{"label":"Seinen","value":"seinen"},{"label":"Shoujo","value":"shoujo"},{"label":"Shounen","value":"shounen"},{"label":"Slice of Life","value":"slice-of-life"},{"label":"Smut","value":"smut"},{"label":"Sports","value":"sports"},{"label":"Supernatural","value":"supernatural"},{"label":"Tragedy","value":"tragedy"},{"label":"Wuxia","value":"wuxia"},{"label":"Xianxia","value":"xianxia"},{"label":"Xuanhuan","value":"xuanhuan"},{"label":"Yaoi","value":"yaoi"}],"inputType":"Picker"}],"options":{"path":{"genres":"manga-genre"},"useNewChapterEndpoint":true,"lang":"English"}}); +export default plugin; + \ No newline at end of file diff --git a/plugins/english/ClickNovel[madara].ts b/plugins/english/ClickNovel[madara].ts index 50b0040..dcb66fb 100644 --- a/plugins/english/ClickNovel[madara].ts +++ b/plugins/english/ClickNovel[madara].ts @@ -1,213 +1,252 @@ +import { fetchApi, fetchFile } from "@libs/fetch"; +import { Filter } from "@libs/filterInputs"; +import { Plugin } from '@typings/plugin' import { load as parseHTML } from "cheerio"; -import { fetchFile, fetchApi } from "@libs/fetch"; -import { Novel, Plugin, Chapter } from "@typings/plugin"; -import { FilterInputs } from "@libs/filterInputs"; import { defaultCover } from "@libs/defaultCover"; -import { NovelStatus } from "@libs/novelStatus" +import { NovelStatus } from "@libs/novelStatus"; import { parseMadaraDate } from "@libs/parseMadaraDate"; import dayjs from "dayjs"; -export const id = "clicknovel"; -export const name = "ClickNovel [madara]"; -export const icon = "multisrc/madara/icons/clicknovel.png"; -export const version = "1.0.0"; -export const site = "https://clicknovel.net/"; -const baseUrl = site; +interface MadaraOptionPath{ + genres?: string, + novels?: string, + novel?: string, + chapter?: string, +} -export const popularNovels: Plugin.popularNovels = async (pageNo, {filters, showLatestNovels}) => { - const novels: Novel.Item[] = []; +const MadaraDefaultPath: MadaraOptionPath = { + novels: 'novel', + novel: 'novel', + chapter: 'novel' +} - let url = site; +interface MadaraOptions { + useNewChapterEndpoint?: boolean, + path?: MadaraOptionPath, + lang?: string, + orderBy?: string +} - if (filters?.genres) { - url += "novel-genre/" + filters.genres + '/'; - } else { - url += "novel/"; +export interface MadaraMetadata { + id: string, + sourceSite: string, + sourceName: string, + options?: MadaraOptions, + filters?: Filter[], +} +class MadaraPlugin implements Plugin.PluginBase { + id: string; + name: string; + icon: string; + site: string; + version: string; + userAgent: string; + cookieString: string; + options?: MadaraOptions; + filter?: Filter[] | undefined; + + constructor(metadata: MadaraMetadata){ + this.id = metadata.id; + this.name = metadata.sourceName + "[madara]"; + const iconFileName = metadata.sourceName.replace(/\s+/g, "").toLowerCase(); + this.icon = `multisrc/madara/icons/${iconFileName}.png`; + this.site = metadata.sourceSite; + this.version = "1.0.0"; + this.userAgent = ""; + this.cookieString = ""; + this.options = metadata.options; + this.filter = metadata.filters; } + async popularNovels(pageNo: number, {filters, showLatestNovels}: Plugin.PopularNovelsOptions): Promise { + const novels: Plugin.NovelItem[] = []; - url += '/page/' + pageNo + '/' + - '?m_orderby=' + (showLatestNovels ? 'latest' : (filters?.sort || 'rating')); - - const body = await fetchApi(url).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - - loadedCheerio('.manga-title-badges').remove(); - - loadedCheerio('.page-item-detail').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - - let novelUrl = loadedCheerio(this).find('.post-title') - .find('a') - .attr('href') || ''; - const novel: Novel.Item = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - - novels.push(novel); - }); - - return novels; -}; - -export const parseNovelAndChapters: Plugin.parseNovelAndChapters = async ( - novelUrl -) => { - const novel: Novel.instance = { - url: novelUrl, - }; - - const body = await fetchApi(novelUrl).then(res => res.text()); - - let loadedCheerio = parseHTML(body); - - loadedCheerio('.manga-title-badges').remove(); - - novel.name = loadedCheerio('.post-title h1').text().trim(); - - novel.cover = - loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || - loadedCheerio('.summary_image > a > img').attr('data-src') || - loadedCheerio('.summary_image > a > img').attr('src') || - defaultCover; - - loadedCheerio('.post-content_item, .post-content').each(function () { - const detailName = loadedCheerio(this).find('h5').text().trim(); - const detail = loadedCheerio(this).find('.summary-content').text().trim(); - - switch (detailName) { - case 'Genre(s)': - case 'التصنيفات': - novel.genres = detail.replace(/[\t\n]/g, ','); - break; - case 'Author(s)': - case 'المؤلف': - case 'المؤلف (ين)': - novel.author = detail; - break; - case 'Status': - case 'الحالة': - novel.status = - detail.includes('OnGoing') || detail.includes('مستمرة') - ? NovelStatus.Ongoing - : NovelStatus.Completed; - break; - } - }); - - loadedCheerio('div.summary__content .code-block,script').remove(); - novel.summary = loadedCheerio('div.summary__content').text().trim(); - - - let html; - - if (false) { - const novelId = - loadedCheerio('.rating-post-id').attr('value') || - loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; - - const body = { - action: "manga_get_chapters", - manga: novelId, - } - html = await fetchApi( - baseUrl + 'wp-admin/admin-ajax.php', - { - method: 'POST', - body: JSON.stringify(body), - }) - .then(res => res.text()); - } else { - html = await fetchApi( - baseUrl + 'ajax/chapters/', - { method: 'POST' }) - .then(res => res.text()); - } - - if (html !== '0') { - loadedCheerio = parseHTML(html); - } - - const chapters: Chapter.Item[] = []; - loadedCheerio('.wp-manga-chapter').each(function () { - const chapterName = loadedCheerio(this).find('a').text().trim(); - - let releaseDate = null; - releaseDate = loadedCheerio(this) - .find('span.chapter-release-date') - .text() - .trim(); - - if (releaseDate) { - releaseDate = parseMadaraDate(releaseDate); + let url = this.site; + if (filters?.genres && this.options?.path?.genres) { + url += this.options?.path?.genres + filters.genres + '/'; } else { - /** - * Insert current date - */ - - releaseDate = dayjs().format('LL'); + url += this.options?.path?.novels ? this.options.path.novels : MadaraDefaultPath.novels; } + + url += '/page/' + pageNo + '/' + + '?m_orderby=' + (showLatestNovels ? 'latest' : (filters?.sort || 'rating')); + + const body = await fetchApi(url).then(res => res.text()); + + const loadedCheerio = parseHTML(body); + + loadedCheerio('.manga-title-badges').remove(); + + loadedCheerio('.page-item-detail').each(function () { + const novelName = loadedCheerio(this).find('.post-title').text().trim(); + let image = loadedCheerio(this).find('img'); + const novelCover = image.attr('data-src') || image.attr('src'); + + let novelUrl = loadedCheerio(this).find('.post-title') + .find('a') + .attr('href') || ''; + const novel: Plugin.NovelItem = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + + novels.push(novel); + }); + + return novels; + } + async parseNovelAndChapters(novelUrl: string): Promise { + const novel: Plugin.SourceNovel = { + url: novelUrl, + }; + + const body = await fetchApi(novelUrl).then(res => res.text()); + + let loadedCheerio = parseHTML(body); + + loadedCheerio('.manga-title-badges, #manga-title span').remove(); + novel.name = + loadedCheerio('.post-title h1').text().trim() || + loadedCheerio('#manga-title h1').text(); + + novel.cover = + loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || + loadedCheerio('.summary_image > a > img').attr('data-src') || + loadedCheerio('.summary_image > a > img').attr('src') || + defaultCover; + + loadedCheerio('.post-content_item, .post-content').each(function () { + const detailName = loadedCheerio(this).find('h5').text().trim(); + const detail = loadedCheerio(this).find('.summary-content').text().trim(); + + switch (detailName) { + case 'Genre(s)': + case 'التصنيفات': + novel.genres = detail.replace(/[\\t\\n]/g, ','); + break; + case 'Author(s)': + case 'المؤلف': + case 'المؤلف (ين)': + novel.author = detail; + break; + case 'Status': + case 'الحالة': + novel.status = + detail.includes('OnGoing') || detail.includes('مستمرة') + ? NovelStatus.Ongoing + : NovelStatus.Completed; + break; + } + }); + + loadedCheerio('div.summary__content .code-block,script').remove(); + novel.summary = + loadedCheerio('div.summary__content').text().trim() || + loadedCheerio('#tab-manga-about').text().trim() || + loadedCheerio('.post-content_item h5:contains("Summary")').next().text().trim(); + + let html; + + if (this.options?.useNewChapterEndpoint !== true) { + const novelId = + loadedCheerio('.rating-post-id').attr('value') || + loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; + + const formData = new FormData() + formData.append("action", "manga_get_chapters"); + formData.append("manga", novelId); - let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + html = await fetchApi( + this.site + 'wp-admin/admin-ajax.php', + { + method: 'POST', + body: formData, + }) + .then(res => res.text()); + } else { + html = await fetchApi( + novelUrl + 'ajax/chapters/', + { method: 'POST' }) + .then(res => res.text()); + } + + if (html !== '0') { + loadedCheerio = parseHTML(html); + } + + const chapters: Plugin.ChapterItem[] = []; + loadedCheerio('.wp-manga-chapter').each(function () { + const chapterName = loadedCheerio(this).find('a').text().trim(); + + let releaseDate = null; + releaseDate = loadedCheerio(this) + .find('span.chapter-release-date') + .text() + .trim(); + + if (releaseDate) { + releaseDate = parseMadaraDate(releaseDate); + } else { + /** + * Insert current date + */ + + releaseDate = dayjs().format('LL'); + } + + let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + + chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); + }); + + novel.chapters = chapters.reverse(); + return novel; + } + async parseChapter(chapterUrl: string): Promise { + const body = await fetchApi(chapterUrl).then(res => res.text()); - chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); - }); + const loadedCheerio = parseHTML(body); + const chapterText = + loadedCheerio('.text-left').html() || + loadedCheerio('.text-right').html() || + loadedCheerio('.entry-content').html() || ""; - novel.chapters = chapters.reverse(); - return novel; -}; - -export const parseChapter: Plugin.parseChapter = async (chapterUrl) => { - const url = baseUrl + "/" + "novel" + "/" + chapterUrl; - - const body = await fetchApi(chapterUrl).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - const chapterText = - loadedCheerio('.text-left').html() || - loadedCheerio('.text-right').html() || - loadedCheerio('.entry-content').html(); - - return chapterText; -}; - -export const searchNovels: Plugin.searchNovels = async (searchTerm) => { - const novels: Novel.Item[] = []; - const url = baseUrl + "?s=" + searchTerm + "&post_type=wp-manga"; - - const body = await fetchApi(url).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - - - loadedCheerio('.c-tabs-item__content').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - - let novelUrl = loadedCheerio(this) - .find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - - novels.push(novel); - }); - return novels; -}; - -export const fetchImage: Plugin.fetchImage = async (url) => { - return await fetchFile(url); -}; - -export const filters = []; \ No newline at end of file + return chapterText; + } + async searchNovels(searchTerm: string, pageNo?: number | undefined): Promise { + const novels: Plugin.NovelItem[] = []; + const url = this.site + "?s=" + searchTerm + "&post_type=wp-manga"; + + const body = await fetchApi(url).then(res => res.text()); + + const loadedCheerio = parseHTML(body); + + + loadedCheerio('.c-tabs-item__content').each(function () { + const novelName = loadedCheerio(this).find('.post-title').text().trim(); + + let image = loadedCheerio(this).find('img'); + const novelCover = image.attr('data-src') || image.attr('src'); + + let novelUrl = loadedCheerio(this) + .find('.post-title') + .find('a') + .attr('href') || ''; + const novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + + novels.push(novel); + }); + return novels; + } + async fetchImage(url: string): Promise { + return await fetchFile(url, {}); + } +} +const plugin = new MadaraPlugin({"id":"clicknovel","sourceSite":"https://clicknovel.net/","sourceName":"ClickNovel","filters":[],"options":{"lang":"English"}}); +export default plugin; + \ No newline at end of file diff --git a/plugins/english/CrateNovel[madara].ts b/plugins/english/CrateNovel[madara].ts index 33239e6..dd0fa3e 100644 --- a/plugins/english/CrateNovel[madara].ts +++ b/plugins/english/CrateNovel[madara].ts @@ -1,213 +1,252 @@ +import { fetchApi, fetchFile } from "@libs/fetch"; +import { Filter } from "@libs/filterInputs"; +import { Plugin } from '@typings/plugin' import { load as parseHTML } from "cheerio"; -import { fetchFile, fetchApi } from "@libs/fetch"; -import { Novel, Plugin, Chapter } from "@typings/plugin"; -import { FilterInputs } from "@libs/filterInputs"; import { defaultCover } from "@libs/defaultCover"; -import { NovelStatus } from "@libs/novelStatus" +import { NovelStatus } from "@libs/novelStatus"; import { parseMadaraDate } from "@libs/parseMadaraDate"; import dayjs from "dayjs"; -export const id = "cratenovel"; -export const name = "CrateNovel [madara]"; -export const icon = "multisrc/madara/icons/cratenovel.png"; -export const version = "1.0.0"; -export const site = "https://cratenovel.com/"; -const baseUrl = site; +interface MadaraOptionPath{ + genres?: string, + novels?: string, + novel?: string, + chapter?: string, +} -export const popularNovels: Plugin.popularNovels = async (pageNo, {filters, showLatestNovels}) => { - const novels: Novel.Item[] = []; +const MadaraDefaultPath: MadaraOptionPath = { + novels: 'novel', + novel: 'novel', + chapter: 'novel' +} - let url = site; +interface MadaraOptions { + useNewChapterEndpoint?: boolean, + path?: MadaraOptionPath, + lang?: string, + orderBy?: string +} - if (filters?.genres) { - url += "novel-genre/" + filters.genres + '/'; - } else { - url += "novel/"; +export interface MadaraMetadata { + id: string, + sourceSite: string, + sourceName: string, + options?: MadaraOptions, + filters?: Filter[], +} +class MadaraPlugin implements Plugin.PluginBase { + id: string; + name: string; + icon: string; + site: string; + version: string; + userAgent: string; + cookieString: string; + options?: MadaraOptions; + filter?: Filter[] | undefined; + + constructor(metadata: MadaraMetadata){ + this.id = metadata.id; + this.name = metadata.sourceName + "[madara]"; + const iconFileName = metadata.sourceName.replace(/\s+/g, "").toLowerCase(); + this.icon = `multisrc/madara/icons/${iconFileName}.png`; + this.site = metadata.sourceSite; + this.version = "1.0.0"; + this.userAgent = ""; + this.cookieString = ""; + this.options = metadata.options; + this.filter = metadata.filters; } + async popularNovels(pageNo: number, {filters, showLatestNovels}: Plugin.PopularNovelsOptions): Promise { + const novels: Plugin.NovelItem[] = []; - url += '/page/' + pageNo + '/' + - '?m_orderby=' + (showLatestNovels ? 'latest' : (filters?.sort || 'rating')); - - const body = await fetchApi(url).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - - loadedCheerio('.manga-title-badges').remove(); - - loadedCheerio('.page-item-detail').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - - let novelUrl = loadedCheerio(this).find('.post-title') - .find('a') - .attr('href') || ''; - const novel: Novel.Item = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - - novels.push(novel); - }); - - return novels; -}; - -export const parseNovelAndChapters: Plugin.parseNovelAndChapters = async ( - novelUrl -) => { - const novel: Novel.instance = { - url: novelUrl, - }; - - const body = await fetchApi(novelUrl).then(res => res.text()); - - let loadedCheerio = parseHTML(body); - - loadedCheerio('.manga-title-badges').remove(); - - novel.name = loadedCheerio('.post-title h1').text().trim(); - - novel.cover = - loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || - loadedCheerio('.summary_image > a > img').attr('data-src') || - loadedCheerio('.summary_image > a > img').attr('src') || - defaultCover; - - loadedCheerio('.post-content_item, .post-content').each(function () { - const detailName = loadedCheerio(this).find('h5').text().trim(); - const detail = loadedCheerio(this).find('.summary-content').text().trim(); - - switch (detailName) { - case 'Genre(s)': - case 'التصنيفات': - novel.genres = detail.replace(/[\t\n]/g, ','); - break; - case 'Author(s)': - case 'المؤلف': - case 'المؤلف (ين)': - novel.author = detail; - break; - case 'Status': - case 'الحالة': - novel.status = - detail.includes('OnGoing') || detail.includes('مستمرة') - ? NovelStatus.Ongoing - : NovelStatus.Completed; - break; - } - }); - - loadedCheerio('div.summary__content .code-block,script').remove(); - novel.summary = loadedCheerio('div.summary__content').text().trim(); - - - let html; - - if (true) { - const novelId = - loadedCheerio('.rating-post-id').attr('value') || - loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; - - const body = { - action: "manga_get_chapters", - manga: novelId, - } - html = await fetchApi( - baseUrl + 'wp-admin/admin-ajax.php', - { - method: 'POST', - body: JSON.stringify(body), - }) - .then(res => res.text()); - } else { - html = await fetchApi( - baseUrl + 'ajax/chapters/', - { method: 'POST' }) - .then(res => res.text()); - } - - if (html !== '0') { - loadedCheerio = parseHTML(html); - } - - const chapters: Chapter.Item[] = []; - loadedCheerio('.wp-manga-chapter').each(function () { - const chapterName = loadedCheerio(this).find('a').text().trim(); - - let releaseDate = null; - releaseDate = loadedCheerio(this) - .find('span.chapter-release-date') - .text() - .trim(); - - if (releaseDate) { - releaseDate = parseMadaraDate(releaseDate); + let url = this.site; + if (filters?.genres && this.options?.path?.genres) { + url += this.options?.path?.genres + filters.genres + '/'; } else { - /** - * Insert current date - */ - - releaseDate = dayjs().format('LL'); + url += this.options?.path?.novels ? this.options.path.novels : MadaraDefaultPath.novels; } + + url += '/page/' + pageNo + '/' + + '?m_orderby=' + (showLatestNovels ? 'latest' : (filters?.sort || 'rating')); + + const body = await fetchApi(url).then(res => res.text()); + + const loadedCheerio = parseHTML(body); + + loadedCheerio('.manga-title-badges').remove(); + + loadedCheerio('.page-item-detail').each(function () { + const novelName = loadedCheerio(this).find('.post-title').text().trim(); + let image = loadedCheerio(this).find('img'); + const novelCover = image.attr('data-src') || image.attr('src'); + + let novelUrl = loadedCheerio(this).find('.post-title') + .find('a') + .attr('href') || ''; + const novel: Plugin.NovelItem = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + + novels.push(novel); + }); + + return novels; + } + async parseNovelAndChapters(novelUrl: string): Promise { + const novel: Plugin.SourceNovel = { + url: novelUrl, + }; + + const body = await fetchApi(novelUrl).then(res => res.text()); + + let loadedCheerio = parseHTML(body); + + loadedCheerio('.manga-title-badges, #manga-title span').remove(); + novel.name = + loadedCheerio('.post-title h1').text().trim() || + loadedCheerio('#manga-title h1').text(); + + novel.cover = + loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || + loadedCheerio('.summary_image > a > img').attr('data-src') || + loadedCheerio('.summary_image > a > img').attr('src') || + defaultCover; + + loadedCheerio('.post-content_item, .post-content').each(function () { + const detailName = loadedCheerio(this).find('h5').text().trim(); + const detail = loadedCheerio(this).find('.summary-content').text().trim(); + + switch (detailName) { + case 'Genre(s)': + case 'التصنيفات': + novel.genres = detail.replace(/[\\t\\n]/g, ','); + break; + case 'Author(s)': + case 'المؤلف': + case 'المؤلف (ين)': + novel.author = detail; + break; + case 'Status': + case 'الحالة': + novel.status = + detail.includes('OnGoing') || detail.includes('مستمرة') + ? NovelStatus.Ongoing + : NovelStatus.Completed; + break; + } + }); + + loadedCheerio('div.summary__content .code-block,script').remove(); + novel.summary = + loadedCheerio('div.summary__content').text().trim() || + loadedCheerio('#tab-manga-about').text().trim() || + loadedCheerio('.post-content_item h5:contains("Summary")').next().text().trim(); + + let html; + + if (this.options?.useNewChapterEndpoint !== true) { + const novelId = + loadedCheerio('.rating-post-id').attr('value') || + loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; + + const formData = new FormData() + formData.append("action", "manga_get_chapters"); + formData.append("manga", novelId); - let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + html = await fetchApi( + this.site + 'wp-admin/admin-ajax.php', + { + method: 'POST', + body: formData, + }) + .then(res => res.text()); + } else { + html = await fetchApi( + novelUrl + 'ajax/chapters/', + { method: 'POST' }) + .then(res => res.text()); + } + + if (html !== '0') { + loadedCheerio = parseHTML(html); + } + + const chapters: Plugin.ChapterItem[] = []; + loadedCheerio('.wp-manga-chapter').each(function () { + const chapterName = loadedCheerio(this).find('a').text().trim(); + + let releaseDate = null; + releaseDate = loadedCheerio(this) + .find('span.chapter-release-date') + .text() + .trim(); + + if (releaseDate) { + releaseDate = parseMadaraDate(releaseDate); + } else { + /** + * Insert current date + */ + + releaseDate = dayjs().format('LL'); + } + + let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + + chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); + }); + + novel.chapters = chapters.reverse(); + return novel; + } + async parseChapter(chapterUrl: string): Promise { + const body = await fetchApi(chapterUrl).then(res => res.text()); - chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); - }); + const loadedCheerio = parseHTML(body); + const chapterText = + loadedCheerio('.text-left').html() || + loadedCheerio('.text-right').html() || + loadedCheerio('.entry-content').html() || ""; - novel.chapters = chapters.reverse(); - return novel; -}; - -export const parseChapter: Plugin.parseChapter = async (chapterUrl) => { - const url = baseUrl + "/" + "novel" + "/" + chapterUrl; - - const body = await fetchApi(chapterUrl).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - const chapterText = - loadedCheerio('.text-left').html() || - loadedCheerio('.text-right').html() || - loadedCheerio('.entry-content').html(); - - return chapterText; -}; - -export const searchNovels: Plugin.searchNovels = async (searchTerm) => { - const novels: Novel.Item[] = []; - const url = baseUrl + "?s=" + searchTerm + "&post_type=wp-manga"; - - const body = await fetchApi(url).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - - - loadedCheerio('.c-tabs-item__content').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - - let novelUrl = loadedCheerio(this) - .find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - - novels.push(novel); - }); - return novels; -}; - -export const fetchImage: Plugin.fetchImage = async (url) => { - return await fetchFile(url); -}; - -export const filters = []; \ No newline at end of file + return chapterText; + } + async searchNovels(searchTerm: string, pageNo?: number | undefined): Promise { + const novels: Plugin.NovelItem[] = []; + const url = this.site + "?s=" + searchTerm + "&post_type=wp-manga"; + + const body = await fetchApi(url).then(res => res.text()); + + const loadedCheerio = parseHTML(body); + + + loadedCheerio('.c-tabs-item__content').each(function () { + const novelName = loadedCheerio(this).find('.post-title').text().trim(); + + let image = loadedCheerio(this).find('img'); + const novelCover = image.attr('data-src') || image.attr('src'); + + let novelUrl = loadedCheerio(this) + .find('.post-title') + .find('a') + .attr('href') || ''; + const novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + + novels.push(novel); + }); + return novels; + } + async fetchImage(url: string): Promise { + return await fetchFile(url, {}); + } +} +const plugin = new MadaraPlugin({"id":"cratenovel","sourceSite":"https://cratenovel.com/","sourceName":"CrateNovel","filters":[],"options":{"useNewChapterEndpoint":true,"lang":"English"}}); +export default plugin; + \ No newline at end of file diff --git a/plugins/english/DaoNovel[madara].ts b/plugins/english/DaoNovel[madara].ts index ec316a7..ae84271 100644 --- a/plugins/english/DaoNovel[madara].ts +++ b/plugins/english/DaoNovel[madara].ts @@ -1,213 +1,252 @@ +import { fetchApi, fetchFile } from "@libs/fetch"; +import { Filter } from "@libs/filterInputs"; +import { Plugin } from '@typings/plugin' import { load as parseHTML } from "cheerio"; -import { fetchFile, fetchApi } from "@libs/fetch"; -import { Novel, Plugin, Chapter } from "@typings/plugin"; -import { FilterInputs } from "@libs/filterInputs"; import { defaultCover } from "@libs/defaultCover"; -import { NovelStatus } from "@libs/novelStatus" +import { NovelStatus } from "@libs/novelStatus"; import { parseMadaraDate } from "@libs/parseMadaraDate"; import dayjs from "dayjs"; -export const id = "daonovel"; -export const name = "DaoNovel [madara]"; -export const icon = "multisrc/madara/icons/daonovel.png"; -export const version = "1.0.0"; -export const site = "https://daonovel.com/"; -const baseUrl = site; +interface MadaraOptionPath{ + genres?: string, + novels?: string, + novel?: string, + chapter?: string, +} -export const popularNovels: Plugin.popularNovels = async (pageNo, {filters, showLatestNovels}) => { - const novels: Novel.Item[] = []; +const MadaraDefaultPath: MadaraOptionPath = { + novels: 'novel', + novel: 'novel', + chapter: 'novel' +} - let url = site; +interface MadaraOptions { + useNewChapterEndpoint?: boolean, + path?: MadaraOptionPath, + lang?: string, + orderBy?: string +} - if (filters?.genres) { - url += "novel-genre/" + filters.genres + '/'; - } else { - url += "novels-list/"; +export interface MadaraMetadata { + id: string, + sourceSite: string, + sourceName: string, + options?: MadaraOptions, + filters?: Filter[], +} +class MadaraPlugin implements Plugin.PluginBase { + id: string; + name: string; + icon: string; + site: string; + version: string; + userAgent: string; + cookieString: string; + options?: MadaraOptions; + filter?: Filter[] | undefined; + + constructor(metadata: MadaraMetadata){ + this.id = metadata.id; + this.name = metadata.sourceName + "[madara]"; + const iconFileName = metadata.sourceName.replace(/\s+/g, "").toLowerCase(); + this.icon = `multisrc/madara/icons/${iconFileName}.png`; + this.site = metadata.sourceSite; + this.version = "1.0.0"; + this.userAgent = ""; + this.cookieString = ""; + this.options = metadata.options; + this.filter = metadata.filters; } + async popularNovels(pageNo: number, {filters, showLatestNovels}: Plugin.PopularNovelsOptions): Promise { + const novels: Plugin.NovelItem[] = []; - url += '/page/' + pageNo + '/' + - '?m_orderby=' + (showLatestNovels ? 'latest' : (filters?.sort || 'rating')); - - const body = await fetchApi(url).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - - loadedCheerio('.manga-title-badges').remove(); - - loadedCheerio('.page-item-detail').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - - let novelUrl = loadedCheerio(this).find('.post-title') - .find('a') - .attr('href') || ''; - const novel: Novel.Item = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - - novels.push(novel); - }); - - return novels; -}; - -export const parseNovelAndChapters: Plugin.parseNovelAndChapters = async ( - novelUrl -) => { - const novel: Novel.instance = { - url: novelUrl, - }; - - const body = await fetchApi(novelUrl).then(res => res.text()); - - let loadedCheerio = parseHTML(body); - - loadedCheerio('.manga-title-badges').remove(); - - novel.name = loadedCheerio('.post-title h1').text().trim(); - - novel.cover = - loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || - loadedCheerio('.summary_image > a > img').attr('data-src') || - loadedCheerio('.summary_image > a > img').attr('src') || - defaultCover; - - loadedCheerio('.post-content_item, .post-content').each(function () { - const detailName = loadedCheerio(this).find('h5').text().trim(); - const detail = loadedCheerio(this).find('.summary-content').text().trim(); - - switch (detailName) { - case 'Genre(s)': - case 'التصنيفات': - novel.genres = detail.replace(/[\t\n]/g, ','); - break; - case 'Author(s)': - case 'المؤلف': - case 'المؤلف (ين)': - novel.author = detail; - break; - case 'Status': - case 'الحالة': - novel.status = - detail.includes('OnGoing') || detail.includes('مستمرة') - ? NovelStatus.Ongoing - : NovelStatus.Completed; - break; - } - }); - - loadedCheerio('div.summary__content .code-block,script').remove(); - novel.summary = loadedCheerio('div.summary__content').text().trim(); - - - let html; - - if (true) { - const novelId = - loadedCheerio('.rating-post-id').attr('value') || - loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; - - const body = { - action: "manga_get_chapters", - manga: novelId, - } - html = await fetchApi( - baseUrl + 'wp-admin/admin-ajax.php', - { - method: 'POST', - body: JSON.stringify(body), - }) - .then(res => res.text()); - } else { - html = await fetchApi( - baseUrl + 'ajax/chapters/', - { method: 'POST' }) - .then(res => res.text()); - } - - if (html !== '0') { - loadedCheerio = parseHTML(html); - } - - const chapters: Chapter.Item[] = []; - loadedCheerio('.wp-manga-chapter').each(function () { - const chapterName = loadedCheerio(this).find('a').text().trim(); - - let releaseDate = null; - releaseDate = loadedCheerio(this) - .find('span.chapter-release-date') - .text() - .trim(); - - if (releaseDate) { - releaseDate = parseMadaraDate(releaseDate); + let url = this.site; + if (filters?.genres && this.options?.path?.genres) { + url += this.options?.path?.genres + filters.genres + '/'; } else { - /** - * Insert current date - */ - - releaseDate = dayjs().format('LL'); + url += this.options?.path?.novels ? this.options.path.novels : MadaraDefaultPath.novels; } + + url += '/page/' + pageNo + '/' + + '?m_orderby=' + (showLatestNovels ? 'latest' : (filters?.sort || 'rating')); + + const body = await fetchApi(url).then(res => res.text()); + + const loadedCheerio = parseHTML(body); + + loadedCheerio('.manga-title-badges').remove(); + + loadedCheerio('.page-item-detail').each(function () { + const novelName = loadedCheerio(this).find('.post-title').text().trim(); + let image = loadedCheerio(this).find('img'); + const novelCover = image.attr('data-src') || image.attr('src'); + + let novelUrl = loadedCheerio(this).find('.post-title') + .find('a') + .attr('href') || ''; + const novel: Plugin.NovelItem = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + + novels.push(novel); + }); + + return novels; + } + async parseNovelAndChapters(novelUrl: string): Promise { + const novel: Plugin.SourceNovel = { + url: novelUrl, + }; + + const body = await fetchApi(novelUrl).then(res => res.text()); + + let loadedCheerio = parseHTML(body); + + loadedCheerio('.manga-title-badges, #manga-title span').remove(); + novel.name = + loadedCheerio('.post-title h1').text().trim() || + loadedCheerio('#manga-title h1').text(); + + novel.cover = + loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || + loadedCheerio('.summary_image > a > img').attr('data-src') || + loadedCheerio('.summary_image > a > img').attr('src') || + defaultCover; + + loadedCheerio('.post-content_item, .post-content').each(function () { + const detailName = loadedCheerio(this).find('h5').text().trim(); + const detail = loadedCheerio(this).find('.summary-content').text().trim(); + + switch (detailName) { + case 'Genre(s)': + case 'التصنيفات': + novel.genres = detail.replace(/[\\t\\n]/g, ','); + break; + case 'Author(s)': + case 'المؤلف': + case 'المؤلف (ين)': + novel.author = detail; + break; + case 'Status': + case 'الحالة': + novel.status = + detail.includes('OnGoing') || detail.includes('مستمرة') + ? NovelStatus.Ongoing + : NovelStatus.Completed; + break; + } + }); + + loadedCheerio('div.summary__content .code-block,script').remove(); + novel.summary = + loadedCheerio('div.summary__content').text().trim() || + loadedCheerio('#tab-manga-about').text().trim() || + loadedCheerio('.post-content_item h5:contains("Summary")').next().text().trim(); + + let html; + + if (this.options?.useNewChapterEndpoint !== true) { + const novelId = + loadedCheerio('.rating-post-id').attr('value') || + loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; + + const formData = new FormData() + formData.append("action", "manga_get_chapters"); + formData.append("manga", novelId); - let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + html = await fetchApi( + this.site + 'wp-admin/admin-ajax.php', + { + method: 'POST', + body: formData, + }) + .then(res => res.text()); + } else { + html = await fetchApi( + novelUrl + 'ajax/chapters/', + { method: 'POST' }) + .then(res => res.text()); + } + + if (html !== '0') { + loadedCheerio = parseHTML(html); + } + + const chapters: Plugin.ChapterItem[] = []; + loadedCheerio('.wp-manga-chapter').each(function () { + const chapterName = loadedCheerio(this).find('a').text().trim(); + + let releaseDate = null; + releaseDate = loadedCheerio(this) + .find('span.chapter-release-date') + .text() + .trim(); + + if (releaseDate) { + releaseDate = parseMadaraDate(releaseDate); + } else { + /** + * Insert current date + */ + + releaseDate = dayjs().format('LL'); + } + + let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + + chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); + }); + + novel.chapters = chapters.reverse(); + return novel; + } + async parseChapter(chapterUrl: string): Promise { + const body = await fetchApi(chapterUrl).then(res => res.text()); - chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); - }); + const loadedCheerio = parseHTML(body); + const chapterText = + loadedCheerio('.text-left').html() || + loadedCheerio('.text-right').html() || + loadedCheerio('.entry-content').html() || ""; - novel.chapters = chapters.reverse(); - return novel; -}; - -export const parseChapter: Plugin.parseChapter = async (chapterUrl) => { - const url = baseUrl + "/" + "novels" + "/" + chapterUrl; - - const body = await fetchApi(chapterUrl).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - const chapterText = - loadedCheerio('.text-left').html() || - loadedCheerio('.text-right').html() || - loadedCheerio('.entry-content').html(); - - return chapterText; -}; - -export const searchNovels: Plugin.searchNovels = async (searchTerm) => { - const novels: Novel.Item[] = []; - const url = baseUrl + "?s=" + searchTerm + "&post_type=wp-manga"; - - const body = await fetchApi(url).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - - - loadedCheerio('.c-tabs-item__content').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - - let novelUrl = loadedCheerio(this) - .find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - - novels.push(novel); - }); - return novels; -}; - -export const fetchImage: Plugin.fetchImage = async (url) => { - return await fetchFile(url); -}; - -export const filters = [{"key":"sort","label":"Order by","values":[{"label":"Rating","value":"rating"},{"label":"A-Z","value":"alphabet"},{"label":"Latest","value":"latest"},{"label":"Most Views","value":"views"},{"label":"New","value":"new-manga"},{"label":"Trending","value":"trending"}],"inputType":FilterInputs.Picker}]; \ No newline at end of file + return chapterText; + } + async searchNovels(searchTerm: string, pageNo?: number | undefined): Promise { + const novels: Plugin.NovelItem[] = []; + const url = this.site + "?s=" + searchTerm + "&post_type=wp-manga"; + + const body = await fetchApi(url).then(res => res.text()); + + const loadedCheerio = parseHTML(body); + + + loadedCheerio('.c-tabs-item__content').each(function () { + const novelName = loadedCheerio(this).find('.post-title').text().trim(); + + let image = loadedCheerio(this).find('img'); + const novelCover = image.attr('data-src') || image.attr('src'); + + let novelUrl = loadedCheerio(this) + .find('.post-title') + .find('a') + .attr('href') || ''; + const novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + + novels.push(novel); + }); + return novels; + } + async fetchImage(url: string): Promise { + return await fetchFile(url, {}); + } +} +const plugin = new MadaraPlugin({"id":"daonovel","sourceSite":"https://daonovel.com/","sourceName":"DaoNovel","filters":[{"key":"sort","label":"Order by","values":[{"label":"Rating","value":"rating"},{"label":"A-Z","value":"alphabet"},{"label":"Latest","value":"latest"},{"label":"Most Views","value":"views"},{"label":"New","value":"new-manga"},{"label":"Trending","value":"trending"}],"inputType":"Picker"}],"options":{"path":{"novels":"novels-list","novel":"novels","chapter":"novels"},"useNewChapterEndpoint":true,"lang":"English"}}); +export default plugin; + \ No newline at end of file diff --git a/plugins/english/FansTranslations[madara].ts b/plugins/english/FansTranslations[madara].ts index 347e7d9..4e1666e 100644 --- a/plugins/english/FansTranslations[madara].ts +++ b/plugins/english/FansTranslations[madara].ts @@ -1,213 +1,252 @@ +import { fetchApi, fetchFile } from "@libs/fetch"; +import { Filter } from "@libs/filterInputs"; +import { Plugin } from '@typings/plugin' import { load as parseHTML } from "cheerio"; -import { fetchFile, fetchApi } from "@libs/fetch"; -import { Novel, Plugin, Chapter } from "@typings/plugin"; -import { FilterInputs } from "@libs/filterInputs"; import { defaultCover } from "@libs/defaultCover"; -import { NovelStatus } from "@libs/novelStatus" +import { NovelStatus } from "@libs/novelStatus"; import { parseMadaraDate } from "@libs/parseMadaraDate"; import dayjs from "dayjs"; -export const id = "fanTLS"; -export const name = "Fans Translations [madara]"; -export const icon = "multisrc/madara/icons/fanstranslations.png"; -export const version = "1.0.0"; -export const site = "https://fanstranslations.com/"; -const baseUrl = site; +interface MadaraOptionPath{ + genres?: string, + novels?: string, + novel?: string, + chapter?: string, +} -export const popularNovels: Plugin.popularNovels = async (pageNo, {filters, showLatestNovels}) => { - const novels: Novel.Item[] = []; +const MadaraDefaultPath: MadaraOptionPath = { + novels: 'novel', + novel: 'novel', + chapter: 'novel' +} - let url = site; +interface MadaraOptions { + useNewChapterEndpoint?: boolean, + path?: MadaraOptionPath, + lang?: string, + orderBy?: string +} - if (filters?.genres) { - url += "novel-genre/" + filters.genres + '/'; - } else { - url += "novel/"; +export interface MadaraMetadata { + id: string, + sourceSite: string, + sourceName: string, + options?: MadaraOptions, + filters?: Filter[], +} +class MadaraPlugin implements Plugin.PluginBase { + id: string; + name: string; + icon: string; + site: string; + version: string; + userAgent: string; + cookieString: string; + options?: MadaraOptions; + filter?: Filter[] | undefined; + + constructor(metadata: MadaraMetadata){ + this.id = metadata.id; + this.name = metadata.sourceName + "[madara]"; + const iconFileName = metadata.sourceName.replace(/\s+/g, "").toLowerCase(); + this.icon = `multisrc/madara/icons/${iconFileName}.png`; + this.site = metadata.sourceSite; + this.version = "1.0.0"; + this.userAgent = ""; + this.cookieString = ""; + this.options = metadata.options; + this.filter = metadata.filters; } + async popularNovels(pageNo: number, {filters, showLatestNovels}: Plugin.PopularNovelsOptions): Promise { + const novels: Plugin.NovelItem[] = []; - url += '/page/' + pageNo + '/' + - '?m_orderby=' + (showLatestNovels ? 'latest' : (filters?.sort || 'rating')); - - const body = await fetchApi(url).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - - loadedCheerio('.manga-title-badges').remove(); - - loadedCheerio('.page-item-detail').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - - let novelUrl = loadedCheerio(this).find('.post-title') - .find('a') - .attr('href') || ''; - const novel: Novel.Item = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - - novels.push(novel); - }); - - return novels; -}; - -export const parseNovelAndChapters: Plugin.parseNovelAndChapters = async ( - novelUrl -) => { - const novel: Novel.instance = { - url: novelUrl, - }; - - const body = await fetchApi(novelUrl).then(res => res.text()); - - let loadedCheerio = parseHTML(body); - - loadedCheerio('.manga-title-badges').remove(); - - novel.name = loadedCheerio('.post-title h1').text().trim(); - - novel.cover = - loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || - loadedCheerio('.summary_image > a > img').attr('data-src') || - loadedCheerio('.summary_image > a > img').attr('src') || - defaultCover; - - loadedCheerio('.post-content_item, .post-content').each(function () { - const detailName = loadedCheerio(this).find('h5').text().trim(); - const detail = loadedCheerio(this).find('.summary-content').text().trim(); - - switch (detailName) { - case 'Genre(s)': - case 'التصنيفات': - novel.genres = detail.replace(/[\t\n]/g, ','); - break; - case 'Author(s)': - case 'المؤلف': - case 'المؤلف (ين)': - novel.author = detail; - break; - case 'Status': - case 'الحالة': - novel.status = - detail.includes('OnGoing') || detail.includes('مستمرة') - ? NovelStatus.Ongoing - : NovelStatus.Completed; - break; - } - }); - - loadedCheerio('div.summary__content .code-block,script').remove(); - novel.summary = loadedCheerio('div.summary__content').text().trim(); - - - let html; - - if (true) { - const novelId = - loadedCheerio('.rating-post-id').attr('value') || - loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; - - const body = { - action: "manga_get_chapters", - manga: novelId, - } - html = await fetchApi( - baseUrl + 'wp-admin/admin-ajax.php', - { - method: 'POST', - body: JSON.stringify(body), - }) - .then(res => res.text()); - } else { - html = await fetchApi( - baseUrl + 'ajax/chapters/', - { method: 'POST' }) - .then(res => res.text()); - } - - if (html !== '0') { - loadedCheerio = parseHTML(html); - } - - const chapters: Chapter.Item[] = []; - loadedCheerio('.wp-manga-chapter').each(function () { - const chapterName = loadedCheerio(this).find('a').text().trim(); - - let releaseDate = null; - releaseDate = loadedCheerio(this) - .find('span.chapter-release-date') - .text() - .trim(); - - if (releaseDate) { - releaseDate = parseMadaraDate(releaseDate); + let url = this.site; + if (filters?.genres && this.options?.path?.genres) { + url += this.options?.path?.genres + filters.genres + '/'; } else { - /** - * Insert current date - */ - - releaseDate = dayjs().format('LL'); + url += this.options?.path?.novels ? this.options.path.novels : MadaraDefaultPath.novels; } + + url += '/page/' + pageNo + '/' + + '?m_orderby=' + (showLatestNovels ? 'latest' : (filters?.sort || 'rating')); + + const body = await fetchApi(url).then(res => res.text()); + + const loadedCheerio = parseHTML(body); + + loadedCheerio('.manga-title-badges').remove(); + + loadedCheerio('.page-item-detail').each(function () { + const novelName = loadedCheerio(this).find('.post-title').text().trim(); + let image = loadedCheerio(this).find('img'); + const novelCover = image.attr('data-src') || image.attr('src'); + + let novelUrl = loadedCheerio(this).find('.post-title') + .find('a') + .attr('href') || ''; + const novel: Plugin.NovelItem = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + + novels.push(novel); + }); + + return novels; + } + async parseNovelAndChapters(novelUrl: string): Promise { + const novel: Plugin.SourceNovel = { + url: novelUrl, + }; + + const body = await fetchApi(novelUrl).then(res => res.text()); + + let loadedCheerio = parseHTML(body); + + loadedCheerio('.manga-title-badges, #manga-title span').remove(); + novel.name = + loadedCheerio('.post-title h1').text().trim() || + loadedCheerio('#manga-title h1').text(); + + novel.cover = + loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || + loadedCheerio('.summary_image > a > img').attr('data-src') || + loadedCheerio('.summary_image > a > img').attr('src') || + defaultCover; + + loadedCheerio('.post-content_item, .post-content').each(function () { + const detailName = loadedCheerio(this).find('h5').text().trim(); + const detail = loadedCheerio(this).find('.summary-content').text().trim(); + + switch (detailName) { + case 'Genre(s)': + case 'التصنيفات': + novel.genres = detail.replace(/[\\t\\n]/g, ','); + break; + case 'Author(s)': + case 'المؤلف': + case 'المؤلف (ين)': + novel.author = detail; + break; + case 'Status': + case 'الحالة': + novel.status = + detail.includes('OnGoing') || detail.includes('مستمرة') + ? NovelStatus.Ongoing + : NovelStatus.Completed; + break; + } + }); + + loadedCheerio('div.summary__content .code-block,script').remove(); + novel.summary = + loadedCheerio('div.summary__content').text().trim() || + loadedCheerio('#tab-manga-about').text().trim() || + loadedCheerio('.post-content_item h5:contains("Summary")').next().text().trim(); + + let html; + + if (this.options?.useNewChapterEndpoint !== true) { + const novelId = + loadedCheerio('.rating-post-id').attr('value') || + loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; + + const formData = new FormData() + formData.append("action", "manga_get_chapters"); + formData.append("manga", novelId); - let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + html = await fetchApi( + this.site + 'wp-admin/admin-ajax.php', + { + method: 'POST', + body: formData, + }) + .then(res => res.text()); + } else { + html = await fetchApi( + novelUrl + 'ajax/chapters/', + { method: 'POST' }) + .then(res => res.text()); + } + + if (html !== '0') { + loadedCheerio = parseHTML(html); + } + + const chapters: Plugin.ChapterItem[] = []; + loadedCheerio('.wp-manga-chapter').each(function () { + const chapterName = loadedCheerio(this).find('a').text().trim(); + + let releaseDate = null; + releaseDate = loadedCheerio(this) + .find('span.chapter-release-date') + .text() + .trim(); + + if (releaseDate) { + releaseDate = parseMadaraDate(releaseDate); + } else { + /** + * Insert current date + */ + + releaseDate = dayjs().format('LL'); + } + + let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + + chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); + }); + + novel.chapters = chapters.reverse(); + return novel; + } + async parseChapter(chapterUrl: string): Promise { + const body = await fetchApi(chapterUrl).then(res => res.text()); - chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); - }); + const loadedCheerio = parseHTML(body); + const chapterText = + loadedCheerio('.text-left').html() || + loadedCheerio('.text-right').html() || + loadedCheerio('.entry-content').html() || ""; - novel.chapters = chapters.reverse(); - return novel; -}; - -export const parseChapter: Plugin.parseChapter = async (chapterUrl) => { - const url = baseUrl + "/" + "novel" + "/" + chapterUrl; - - const body = await fetchApi(chapterUrl).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - const chapterText = - loadedCheerio('.text-left').html() || - loadedCheerio('.text-right').html() || - loadedCheerio('.entry-content').html(); - - return chapterText; -}; - -export const searchNovels: Plugin.searchNovels = async (searchTerm) => { - const novels: Novel.Item[] = []; - const url = baseUrl + "?s=" + searchTerm + "&post_type=wp-manga"; - - const body = await fetchApi(url).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - - - loadedCheerio('.c-tabs-item__content').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - - let novelUrl = loadedCheerio(this) - .find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - - novels.push(novel); - }); - return novels; -}; - -export const fetchImage: Plugin.fetchImage = async (url) => { - return await fetchFile(url); -}; - -export const filters = [{"key":"sort","label":"Order by","values":[{"label":"Rating","value":"rating"},{"label":"A-Z","value":"alphabet"},{"label":"Latest","value":"latest"},{"label":"Most Views","value":"views"},{"label":"New","value":"new-manga"},{"label":"Trending","value":"trending"}],"inputType":FilterInputs.Picker}]; \ No newline at end of file + return chapterText; + } + async searchNovels(searchTerm: string, pageNo?: number | undefined): Promise { + const novels: Plugin.NovelItem[] = []; + const url = this.site + "?s=" + searchTerm + "&post_type=wp-manga"; + + const body = await fetchApi(url).then(res => res.text()); + + const loadedCheerio = parseHTML(body); + + + loadedCheerio('.c-tabs-item__content').each(function () { + const novelName = loadedCheerio(this).find('.post-title').text().trim(); + + let image = loadedCheerio(this).find('img'); + const novelCover = image.attr('data-src') || image.attr('src'); + + let novelUrl = loadedCheerio(this) + .find('.post-title') + .find('a') + .attr('href') || ''; + const novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + + novels.push(novel); + }); + return novels; + } + async fetchImage(url: string): Promise { + return await fetchFile(url, {}); + } +} +const plugin = new MadaraPlugin({"id":"fanTLS","sourceSite":"https://fanstranslations.com/","sourceName":"Fans Translations","filters":[{"key":"sort","label":"Order by","values":[{"label":"Rating","value":"rating"},{"label":"A-Z","value":"alphabet"},{"label":"Latest","value":"latest"},{"label":"Most Views","value":"views"},{"label":"New","value":"new-manga"},{"label":"Trending","value":"trending"}],"inputType":"Picker"}],"options":{"useNewChapterEndpoint":true,"lang":"English"}}); +export default plugin; + \ No newline at end of file diff --git a/plugins/english/FirstKissNovel[madara].ts b/plugins/english/FirstKissNovel[madara].ts index f763f88..86086c6 100644 --- a/plugins/english/FirstKissNovel[madara].ts +++ b/plugins/english/FirstKissNovel[madara].ts @@ -1,213 +1,252 @@ +import { fetchApi, fetchFile } from "@libs/fetch"; +import { Filter } from "@libs/filterInputs"; +import { Plugin } from '@typings/plugin' import { load as parseHTML } from "cheerio"; -import { fetchFile, fetchApi } from "@libs/fetch"; -import { Novel, Plugin, Chapter } from "@typings/plugin"; -import { FilterInputs } from "@libs/filterInputs"; import { defaultCover } from "@libs/defaultCover"; -import { NovelStatus } from "@libs/novelStatus" +import { NovelStatus } from "@libs/novelStatus"; import { parseMadaraDate } from "@libs/parseMadaraDate"; import dayjs from "dayjs"; -export const id = "1stkissnovel"; -export const name = "FirstKissNovel [madara]"; -export const icon = "multisrc/madara/icons/firstkissnovel.png"; -export const version = "1.0.0"; -export const site = "https://1stkissnovel.org/"; -const baseUrl = site; +interface MadaraOptionPath{ + genres?: string, + novels?: string, + novel?: string, + chapter?: string, +} -export const popularNovels: Plugin.popularNovels = async (pageNo, {filters, showLatestNovels}) => { - const novels: Novel.Item[] = []; +const MadaraDefaultPath: MadaraOptionPath = { + novels: 'novel', + novel: 'novel', + chapter: 'novel' +} - let url = site; +interface MadaraOptions { + useNewChapterEndpoint?: boolean, + path?: MadaraOptionPath, + lang?: string, + orderBy?: string +} - if (filters?.genres) { - url += "novel-genre/" + filters.genres + '/'; - } else { - url += "novel/"; +export interface MadaraMetadata { + id: string, + sourceSite: string, + sourceName: string, + options?: MadaraOptions, + filters?: Filter[], +} +class MadaraPlugin implements Plugin.PluginBase { + id: string; + name: string; + icon: string; + site: string; + version: string; + userAgent: string; + cookieString: string; + options?: MadaraOptions; + filter?: Filter[] | undefined; + + constructor(metadata: MadaraMetadata){ + this.id = metadata.id; + this.name = metadata.sourceName + "[madara]"; + const iconFileName = metadata.sourceName.replace(/\s+/g, "").toLowerCase(); + this.icon = `multisrc/madara/icons/${iconFileName}.png`; + this.site = metadata.sourceSite; + this.version = "1.0.0"; + this.userAgent = ""; + this.cookieString = ""; + this.options = metadata.options; + this.filter = metadata.filters; } + async popularNovels(pageNo: number, {filters, showLatestNovels}: Plugin.PopularNovelsOptions): Promise { + const novels: Plugin.NovelItem[] = []; - url += '/page/' + pageNo + '/' + - '?m_orderby=' + (showLatestNovels ? 'latest' : (filters?.sort || 'rating')); - - const body = await fetchApi(url).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - - loadedCheerio('.manga-title-badges').remove(); - - loadedCheerio('.page-item-detail').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - - let novelUrl = loadedCheerio(this).find('.post-title') - .find('a') - .attr('href') || ''; - const novel: Novel.Item = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - - novels.push(novel); - }); - - return novels; -}; - -export const parseNovelAndChapters: Plugin.parseNovelAndChapters = async ( - novelUrl -) => { - const novel: Novel.instance = { - url: novelUrl, - }; - - const body = await fetchApi(novelUrl).then(res => res.text()); - - let loadedCheerio = parseHTML(body); - - loadedCheerio('.manga-title-badges').remove(); - - novel.name = loadedCheerio('.post-title h1').text().trim(); - - novel.cover = - loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || - loadedCheerio('.summary_image > a > img').attr('data-src') || - loadedCheerio('.summary_image > a > img').attr('src') || - defaultCover; - - loadedCheerio('.post-content_item, .post-content').each(function () { - const detailName = loadedCheerio(this).find('h5').text().trim(); - const detail = loadedCheerio(this).find('.summary-content').text().trim(); - - switch (detailName) { - case 'Genre(s)': - case 'التصنيفات': - novel.genres = detail.replace(/[\t\n]/g, ','); - break; - case 'Author(s)': - case 'المؤلف': - case 'المؤلف (ين)': - novel.author = detail; - break; - case 'Status': - case 'الحالة': - novel.status = - detail.includes('OnGoing') || detail.includes('مستمرة') - ? NovelStatus.Ongoing - : NovelStatus.Completed; - break; - } - }); - - loadedCheerio('div.summary__content .code-block,script').remove(); - novel.summary = loadedCheerio('div.summary__content').text().trim(); - - - let html; - - if (true) { - const novelId = - loadedCheerio('.rating-post-id').attr('value') || - loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; - - const body = { - action: "manga_get_chapters", - manga: novelId, - } - html = await fetchApi( - baseUrl + 'wp-admin/admin-ajax.php', - { - method: 'POST', - body: JSON.stringify(body), - }) - .then(res => res.text()); - } else { - html = await fetchApi( - baseUrl + 'ajax/chapters/', - { method: 'POST' }) - .then(res => res.text()); - } - - if (html !== '0') { - loadedCheerio = parseHTML(html); - } - - const chapters: Chapter.Item[] = []; - loadedCheerio('.wp-manga-chapter').each(function () { - const chapterName = loadedCheerio(this).find('a').text().trim(); - - let releaseDate = null; - releaseDate = loadedCheerio(this) - .find('span.chapter-release-date') - .text() - .trim(); - - if (releaseDate) { - releaseDate = parseMadaraDate(releaseDate); + let url = this.site; + if (filters?.genres && this.options?.path?.genres) { + url += this.options?.path?.genres + filters.genres + '/'; } else { - /** - * Insert current date - */ - - releaseDate = dayjs().format('LL'); + url += this.options?.path?.novels ? this.options.path.novels : MadaraDefaultPath.novels; } + + url += '/page/' + pageNo + '/' + + '?m_orderby=' + (showLatestNovels ? 'latest' : (filters?.sort || 'rating')); + + const body = await fetchApi(url).then(res => res.text()); + + const loadedCheerio = parseHTML(body); + + loadedCheerio('.manga-title-badges').remove(); + + loadedCheerio('.page-item-detail').each(function () { + const novelName = loadedCheerio(this).find('.post-title').text().trim(); + let image = loadedCheerio(this).find('img'); + const novelCover = image.attr('data-src') || image.attr('src'); + + let novelUrl = loadedCheerio(this).find('.post-title') + .find('a') + .attr('href') || ''; + const novel: Plugin.NovelItem = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + + novels.push(novel); + }); + + return novels; + } + async parseNovelAndChapters(novelUrl: string): Promise { + const novel: Plugin.SourceNovel = { + url: novelUrl, + }; + + const body = await fetchApi(novelUrl).then(res => res.text()); + + let loadedCheerio = parseHTML(body); + + loadedCheerio('.manga-title-badges, #manga-title span').remove(); + novel.name = + loadedCheerio('.post-title h1').text().trim() || + loadedCheerio('#manga-title h1').text(); + + novel.cover = + loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || + loadedCheerio('.summary_image > a > img').attr('data-src') || + loadedCheerio('.summary_image > a > img').attr('src') || + defaultCover; + + loadedCheerio('.post-content_item, .post-content').each(function () { + const detailName = loadedCheerio(this).find('h5').text().trim(); + const detail = loadedCheerio(this).find('.summary-content').text().trim(); + + switch (detailName) { + case 'Genre(s)': + case 'التصنيفات': + novel.genres = detail.replace(/[\\t\\n]/g, ','); + break; + case 'Author(s)': + case 'المؤلف': + case 'المؤلف (ين)': + novel.author = detail; + break; + case 'Status': + case 'الحالة': + novel.status = + detail.includes('OnGoing') || detail.includes('مستمرة') + ? NovelStatus.Ongoing + : NovelStatus.Completed; + break; + } + }); + + loadedCheerio('div.summary__content .code-block,script').remove(); + novel.summary = + loadedCheerio('div.summary__content').text().trim() || + loadedCheerio('#tab-manga-about').text().trim() || + loadedCheerio('.post-content_item h5:contains("Summary")').next().text().trim(); + + let html; + + if (this.options?.useNewChapterEndpoint !== true) { + const novelId = + loadedCheerio('.rating-post-id').attr('value') || + loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; + + const formData = new FormData() + formData.append("action", "manga_get_chapters"); + formData.append("manga", novelId); - let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + html = await fetchApi( + this.site + 'wp-admin/admin-ajax.php', + { + method: 'POST', + body: formData, + }) + .then(res => res.text()); + } else { + html = await fetchApi( + novelUrl + 'ajax/chapters/', + { method: 'POST' }) + .then(res => res.text()); + } + + if (html !== '0') { + loadedCheerio = parseHTML(html); + } + + const chapters: Plugin.ChapterItem[] = []; + loadedCheerio('.wp-manga-chapter').each(function () { + const chapterName = loadedCheerio(this).find('a').text().trim(); + + let releaseDate = null; + releaseDate = loadedCheerio(this) + .find('span.chapter-release-date') + .text() + .trim(); + + if (releaseDate) { + releaseDate = parseMadaraDate(releaseDate); + } else { + /** + * Insert current date + */ + + releaseDate = dayjs().format('LL'); + } + + let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + + chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); + }); + + novel.chapters = chapters.reverse(); + return novel; + } + async parseChapter(chapterUrl: string): Promise { + const body = await fetchApi(chapterUrl).then(res => res.text()); - chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); - }); + const loadedCheerio = parseHTML(body); + const chapterText = + loadedCheerio('.text-left').html() || + loadedCheerio('.text-right').html() || + loadedCheerio('.entry-content').html() || ""; - novel.chapters = chapters.reverse(); - return novel; -}; - -export const parseChapter: Plugin.parseChapter = async (chapterUrl) => { - const url = baseUrl + "/" + "novel" + "/" + chapterUrl; - - const body = await fetchApi(chapterUrl).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - const chapterText = - loadedCheerio('.text-left').html() || - loadedCheerio('.text-right').html() || - loadedCheerio('.entry-content').html(); - - return chapterText; -}; - -export const searchNovels: Plugin.searchNovels = async (searchTerm) => { - const novels: Novel.Item[] = []; - const url = baseUrl + "?s=" + searchTerm + "&post_type=wp-manga"; - - const body = await fetchApi(url).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - - - loadedCheerio('.c-tabs-item__content').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - - let novelUrl = loadedCheerio(this) - .find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - - novels.push(novel); - }); - return novels; -}; - -export const fetchImage: Plugin.fetchImage = async (url) => { - return await fetchFile(url); -}; - -export const filters = [{"key":"sort","label":"Order by","values":[{"label":"Rating","value":"rating"},{"label":"A-Z","value":"alphabet"},{"label":"Latest","value":"latest"},{"label":"Most Views","value":"views"},{"label":"New","value":"new-manga"},{"label":"Trending","value":"trending"}],"inputType":FilterInputs.Picker},{"key":"genres","label":"GENRES","values":[{"label":"Action","value":"action"},{"label":"Adult","value":"adult"},{"label":"Adventure","value":"adventure"},{"label":"Anime","value":"anime"},{"label":"Apocalypse","value":"apocalypse"},{"label":"Boy's Love","value":"boys-love"},{"label":"Comedy","value":"comedy"},{"label":"Completed","value":"completed"},{"label":"Cooking","value":"cooking"},{"label":"Demons","value":"demons"},{"label":"Detective","value":"detective"},{"label":"Drama","value":"drama"},{"label":"Ecchi","value":"ecchi"},{"label":"Fan-Fiction","value":"fan-fiction"},{"label":"Fantasy","value":"fantasy"},{"label":"Food","value":"food"},{"label":"Game","value":"game"},{"label":"Gender Bender","value":"gender-bender"},{"label":"Girls Love","value":"girls-love"},{"label":"Harem","value":"harem"},{"label":"Historical","value":"historical"},{"label":"Horror","value":"horror"},{"label":"Humor","value":"humor"},{"label":"Isekai","value":"isekai"},{"label":"Josei","value":"josei"},{"label":"Magic","value":"magic"},{"label":"Magical","value":"magical"},{"label":"Manhua","value":"manhua"},{"label":"Manhwa","value":"manhwa"},{"label":"Martial Arts","value":"martial-arts"},{"label":"Mature","value":"mature"},{"label":"Mecha","value":"mecha"},{"label":"Medical","value":"medical"},{"label":"Military","value":"military"},{"label":"Moder","value":"moder"},{"label":"Modern","value":"modern"},{"label":"Murim","value":"murim"},{"label":"Music","value":"music"},{"label":"Mystery","value":"mystery"},{"label":"Psychological","value":"psychological"},{"label":"Reverse","value":"reverse"},{"label":"Reverse harem","value":"reverse-harem"},{"label":"Romance","value":"romance"},{"label":"School Life","value":"school-life"},{"label":"Sci-fi","value":"sci-fi"},{"label":"Seinen","value":"seinen"},{"label":"Shoujo","value":"shoujo"},{"label":"Shoujo Ai","value":"shoujo-ai"},{"label":"Shounen","value":"shounen"},{"label":"Shounen Ai","value":"shounen-ai"},{"label":"Slice of Life","value":"slice-of-life"},{"label":"Smut","value":"smut"},{"label":"Sports","value":"sports"},{"label":"Super power","value":"super-power"},{"label":"Superhero","value":"superhero"},{"label":"Supernatural","value":"supernatural"},{"label":"Thriller","value":"thriller"},{"label":"Tragedy","value":"tragedy"},{"label":"Urban Life","value":"urban-life"},{"label":"Vampire","value":"vampire"},{"label":"Webtoons","value":"webtoons"},{"label":"Wuxia","value":"wuxia"},{"label":"Xianxia","value":"xianxia"},{"label":"Xuanhuan","value":"xuanhuan"},{"label":"Yaoi","value":"yaoi"},{"label":"Yuri","value":"yuri"}],"inputType":FilterInputs.Picker}]; \ No newline at end of file + return chapterText; + } + async searchNovels(searchTerm: string, pageNo?: number | undefined): Promise { + const novels: Plugin.NovelItem[] = []; + const url = this.site + "?s=" + searchTerm + "&post_type=wp-manga"; + + const body = await fetchApi(url).then(res => res.text()); + + const loadedCheerio = parseHTML(body); + + + loadedCheerio('.c-tabs-item__content').each(function () { + const novelName = loadedCheerio(this).find('.post-title').text().trim(); + + let image = loadedCheerio(this).find('img'); + const novelCover = image.attr('data-src') || image.attr('src'); + + let novelUrl = loadedCheerio(this) + .find('.post-title') + .find('a') + .attr('href') || ''; + const novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + + novels.push(novel); + }); + return novels; + } + async fetchImage(url: string): Promise { + return await fetchFile(url, {}); + } +} +const plugin = new MadaraPlugin({"id":"1stkissnovel","sourceSite":"https://1stkissnovel.org/","sourceName":"FirstKissNovel","filters":[{"key":"sort","label":"Order by","values":[{"label":"Rating","value":"rating"},{"label":"A-Z","value":"alphabet"},{"label":"Latest","value":"latest"},{"label":"Most Views","value":"views"},{"label":"New","value":"new-manga"},{"label":"Trending","value":"trending"}],"inputType":"Picker"},{"key":"genres","label":"GENRES","values":[{"label":"Action","value":"action"},{"label":"Adult","value":"adult"},{"label":"Adventure","value":"adventure"},{"label":"Anime","value":"anime"},{"label":"Apocalypse","value":"apocalypse"},{"label":"Boy's Love","value":"boys-love"},{"label":"Comedy","value":"comedy"},{"label":"Completed","value":"completed"},{"label":"Cooking","value":"cooking"},{"label":"Demons","value":"demons"},{"label":"Detective","value":"detective"},{"label":"Drama","value":"drama"},{"label":"Ecchi","value":"ecchi"},{"label":"Fan-Fiction","value":"fan-fiction"},{"label":"Fantasy","value":"fantasy"},{"label":"Food","value":"food"},{"label":"Game","value":"game"},{"label":"Gender Bender","value":"gender-bender"},{"label":"Girls Love","value":"girls-love"},{"label":"Harem","value":"harem"},{"label":"Historical","value":"historical"},{"label":"Horror","value":"horror"},{"label":"Humor","value":"humor"},{"label":"Isekai","value":"isekai"},{"label":"Josei","value":"josei"},{"label":"Magic","value":"magic"},{"label":"Magical","value":"magical"},{"label":"Manhua","value":"manhua"},{"label":"Manhwa","value":"manhwa"},{"label":"Martial Arts","value":"martial-arts"},{"label":"Mature","value":"mature"},{"label":"Mecha","value":"mecha"},{"label":"Medical","value":"medical"},{"label":"Military","value":"military"},{"label":"Moder","value":"moder"},{"label":"Modern","value":"modern"},{"label":"Murim","value":"murim"},{"label":"Music","value":"music"},{"label":"Mystery","value":"mystery"},{"label":"Psychological","value":"psychological"},{"label":"Reverse","value":"reverse"},{"label":"Reverse harem","value":"reverse-harem"},{"label":"Romance","value":"romance"},{"label":"School Life","value":"school-life"},{"label":"Sci-fi","value":"sci-fi"},{"label":"Seinen","value":"seinen"},{"label":"Shoujo","value":"shoujo"},{"label":"Shoujo Ai","value":"shoujo-ai"},{"label":"Shounen","value":"shounen"},{"label":"Shounen Ai","value":"shounen-ai"},{"label":"Slice of Life","value":"slice-of-life"},{"label":"Smut","value":"smut"},{"label":"Sports","value":"sports"},{"label":"Super power","value":"super-power"},{"label":"Superhero","value":"superhero"},{"label":"Supernatural","value":"supernatural"},{"label":"Thriller","value":"thriller"},{"label":"Tragedy","value":"tragedy"},{"label":"Urban Life","value":"urban-life"},{"label":"Vampire","value":"vampire"},{"label":"Webtoons","value":"webtoons"},{"label":"Wuxia","value":"wuxia"},{"label":"Xianxia","value":"xianxia"},{"label":"Xuanhuan","value":"xuanhuan"},{"label":"Yaoi","value":"yaoi"},{"label":"Yuri","value":"yuri"}],"inputType":"Picker"}],"options":{"useNewChapterEndpoint":true,"lang":"English"}}); +export default plugin; + \ No newline at end of file diff --git a/plugins/english/FreeNovelMe[madara].ts b/plugins/english/FreeNovelMe[madara].ts index 62a0cc5..c3197ff 100644 --- a/plugins/english/FreeNovelMe[madara].ts +++ b/plugins/english/FreeNovelMe[madara].ts @@ -1,213 +1,252 @@ +import { fetchApi, fetchFile } from "@libs/fetch"; +import { Filter } from "@libs/filterInputs"; +import { Plugin } from '@typings/plugin' import { load as parseHTML } from "cheerio"; -import { fetchFile, fetchApi } from "@libs/fetch"; -import { Novel, Plugin, Chapter } from "@typings/plugin"; -import { FilterInputs } from "@libs/filterInputs"; import { defaultCover } from "@libs/defaultCover"; -import { NovelStatus } from "@libs/novelStatus" +import { NovelStatus } from "@libs/novelStatus"; import { parseMadaraDate } from "@libs/parseMadaraDate"; import dayjs from "dayjs"; -export const id = "freenovel.me"; -export const name = "FreeNovelMe [madara]"; -export const icon = "multisrc/madara/icons/freenovelme.png"; -export const version = "1.0.0"; -export const site = "https://freenovel.me/"; -const baseUrl = site; +interface MadaraOptionPath{ + genres?: string, + novels?: string, + novel?: string, + chapter?: string, +} -export const popularNovels: Plugin.popularNovels = async (pageNo, {filters, showLatestNovels}) => { - const novels: Novel.Item[] = []; +const MadaraDefaultPath: MadaraOptionPath = { + novels: 'novel', + novel: 'novel', + chapter: 'novel' +} - let url = site; +interface MadaraOptions { + useNewChapterEndpoint?: boolean, + path?: MadaraOptionPath, + lang?: string, + orderBy?: string +} - if (filters?.genres) { - url += "novel-genre/" + filters.genres + '/'; - } else { - url += "novel/"; +export interface MadaraMetadata { + id: string, + sourceSite: string, + sourceName: string, + options?: MadaraOptions, + filters?: Filter[], +} +class MadaraPlugin implements Plugin.PluginBase { + id: string; + name: string; + icon: string; + site: string; + version: string; + userAgent: string; + cookieString: string; + options?: MadaraOptions; + filter?: Filter[] | undefined; + + constructor(metadata: MadaraMetadata){ + this.id = metadata.id; + this.name = metadata.sourceName + "[madara]"; + const iconFileName = metadata.sourceName.replace(/\s+/g, "").toLowerCase(); + this.icon = `multisrc/madara/icons/${iconFileName}.png`; + this.site = metadata.sourceSite; + this.version = "1.0.0"; + this.userAgent = ""; + this.cookieString = ""; + this.options = metadata.options; + this.filter = metadata.filters; } + async popularNovels(pageNo: number, {filters, showLatestNovels}: Plugin.PopularNovelsOptions): Promise { + const novels: Plugin.NovelItem[] = []; - url += '/page/' + pageNo + '/' + - '?m_orderby=' + (showLatestNovels ? 'latest' : (filters?.sort || 'rating')); - - const body = await fetchApi(url).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - - loadedCheerio('.manga-title-badges').remove(); - - loadedCheerio('.page-item-detail').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - - let novelUrl = loadedCheerio(this).find('.post-title') - .find('a') - .attr('href') || ''; - const novel: Novel.Item = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - - novels.push(novel); - }); - - return novels; -}; - -export const parseNovelAndChapters: Plugin.parseNovelAndChapters = async ( - novelUrl -) => { - const novel: Novel.instance = { - url: novelUrl, - }; - - const body = await fetchApi(novelUrl).then(res => res.text()); - - let loadedCheerio = parseHTML(body); - - loadedCheerio('.manga-title-badges').remove(); - - novel.name = loadedCheerio('.post-title h1').text().trim(); - - novel.cover = - loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || - loadedCheerio('.summary_image > a > img').attr('data-src') || - loadedCheerio('.summary_image > a > img').attr('src') || - defaultCover; - - loadedCheerio('.post-content_item, .post-content').each(function () { - const detailName = loadedCheerio(this).find('h5').text().trim(); - const detail = loadedCheerio(this).find('.summary-content').text().trim(); - - switch (detailName) { - case 'Genre(s)': - case 'التصنيفات': - novel.genres = detail.replace(/[\t\n]/g, ','); - break; - case 'Author(s)': - case 'المؤلف': - case 'المؤلف (ين)': - novel.author = detail; - break; - case 'Status': - case 'الحالة': - novel.status = - detail.includes('OnGoing') || detail.includes('مستمرة') - ? NovelStatus.Ongoing - : NovelStatus.Completed; - break; - } - }); - - loadedCheerio('div.summary__content .code-block,script').remove(); - novel.summary = loadedCheerio('div.summary__content').text().trim(); - - - let html; - - if (false) { - const novelId = - loadedCheerio('.rating-post-id').attr('value') || - loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; - - const body = { - action: "manga_get_chapters", - manga: novelId, - } - html = await fetchApi( - baseUrl + 'wp-admin/admin-ajax.php', - { - method: 'POST', - body: JSON.stringify(body), - }) - .then(res => res.text()); - } else { - html = await fetchApi( - baseUrl + 'ajax/chapters/', - { method: 'POST' }) - .then(res => res.text()); - } - - if (html !== '0') { - loadedCheerio = parseHTML(html); - } - - const chapters: Chapter.Item[] = []; - loadedCheerio('.wp-manga-chapter').each(function () { - const chapterName = loadedCheerio(this).find('a').text().trim(); - - let releaseDate = null; - releaseDate = loadedCheerio(this) - .find('span.chapter-release-date') - .text() - .trim(); - - if (releaseDate) { - releaseDate = parseMadaraDate(releaseDate); + let url = this.site; + if (filters?.genres && this.options?.path?.genres) { + url += this.options?.path?.genres + filters.genres + '/'; } else { - /** - * Insert current date - */ - - releaseDate = dayjs().format('LL'); + url += this.options?.path?.novels ? this.options.path.novels : MadaraDefaultPath.novels; } + + url += '/page/' + pageNo + '/' + + '?m_orderby=' + (showLatestNovels ? 'latest' : (filters?.sort || 'rating')); + + const body = await fetchApi(url).then(res => res.text()); + + const loadedCheerio = parseHTML(body); + + loadedCheerio('.manga-title-badges').remove(); + + loadedCheerio('.page-item-detail').each(function () { + const novelName = loadedCheerio(this).find('.post-title').text().trim(); + let image = loadedCheerio(this).find('img'); + const novelCover = image.attr('data-src') || image.attr('src'); + + let novelUrl = loadedCheerio(this).find('.post-title') + .find('a') + .attr('href') || ''; + const novel: Plugin.NovelItem = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + + novels.push(novel); + }); + + return novels; + } + async parseNovelAndChapters(novelUrl: string): Promise { + const novel: Plugin.SourceNovel = { + url: novelUrl, + }; + + const body = await fetchApi(novelUrl).then(res => res.text()); + + let loadedCheerio = parseHTML(body); + + loadedCheerio('.manga-title-badges, #manga-title span').remove(); + novel.name = + loadedCheerio('.post-title h1').text().trim() || + loadedCheerio('#manga-title h1').text(); + + novel.cover = + loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || + loadedCheerio('.summary_image > a > img').attr('data-src') || + loadedCheerio('.summary_image > a > img').attr('src') || + defaultCover; + + loadedCheerio('.post-content_item, .post-content').each(function () { + const detailName = loadedCheerio(this).find('h5').text().trim(); + const detail = loadedCheerio(this).find('.summary-content').text().trim(); + + switch (detailName) { + case 'Genre(s)': + case 'التصنيفات': + novel.genres = detail.replace(/[\\t\\n]/g, ','); + break; + case 'Author(s)': + case 'المؤلف': + case 'المؤلف (ين)': + novel.author = detail; + break; + case 'Status': + case 'الحالة': + novel.status = + detail.includes('OnGoing') || detail.includes('مستمرة') + ? NovelStatus.Ongoing + : NovelStatus.Completed; + break; + } + }); + + loadedCheerio('div.summary__content .code-block,script').remove(); + novel.summary = + loadedCheerio('div.summary__content').text().trim() || + loadedCheerio('#tab-manga-about').text().trim() || + loadedCheerio('.post-content_item h5:contains("Summary")').next().text().trim(); + + let html; + + if (this.options?.useNewChapterEndpoint !== true) { + const novelId = + loadedCheerio('.rating-post-id').attr('value') || + loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; + + const formData = new FormData() + formData.append("action", "manga_get_chapters"); + formData.append("manga", novelId); - let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + html = await fetchApi( + this.site + 'wp-admin/admin-ajax.php', + { + method: 'POST', + body: formData, + }) + .then(res => res.text()); + } else { + html = await fetchApi( + novelUrl + 'ajax/chapters/', + { method: 'POST' }) + .then(res => res.text()); + } + + if (html !== '0') { + loadedCheerio = parseHTML(html); + } + + const chapters: Plugin.ChapterItem[] = []; + loadedCheerio('.wp-manga-chapter').each(function () { + const chapterName = loadedCheerio(this).find('a').text().trim(); + + let releaseDate = null; + releaseDate = loadedCheerio(this) + .find('span.chapter-release-date') + .text() + .trim(); + + if (releaseDate) { + releaseDate = parseMadaraDate(releaseDate); + } else { + /** + * Insert current date + */ + + releaseDate = dayjs().format('LL'); + } + + let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + + chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); + }); + + novel.chapters = chapters.reverse(); + return novel; + } + async parseChapter(chapterUrl: string): Promise { + const body = await fetchApi(chapterUrl).then(res => res.text()); - chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); - }); + const loadedCheerio = parseHTML(body); + const chapterText = + loadedCheerio('.text-left').html() || + loadedCheerio('.text-right').html() || + loadedCheerio('.entry-content').html() || ""; - novel.chapters = chapters.reverse(); - return novel; -}; - -export const parseChapter: Plugin.parseChapter = async (chapterUrl) => { - const url = baseUrl + "/" + "novel" + "/" + chapterUrl; - - const body = await fetchApi(chapterUrl).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - const chapterText = - loadedCheerio('.text-left').html() || - loadedCheerio('.text-right').html() || - loadedCheerio('.entry-content').html(); - - return chapterText; -}; - -export const searchNovels: Plugin.searchNovels = async (searchTerm) => { - const novels: Novel.Item[] = []; - const url = baseUrl + "?s=" + searchTerm + "&post_type=wp-manga"; - - const body = await fetchApi(url).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - - - loadedCheerio('.c-tabs-item__content').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - - let novelUrl = loadedCheerio(this) - .find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - - novels.push(novel); - }); - return novels; -}; - -export const fetchImage: Plugin.fetchImage = async (url) => { - return await fetchFile(url); -}; - -export const filters = [{"key":"sort","label":"Order by","values":[{"label":"Rating","value":"rating"},{"label":"A-Z","value":"alphabet"},{"label":"Latest","value":"latest"},{"label":"Most Views","value":"views"},{"label":"New","value":"new-manga"},{"label":"Trending","value":"trending"}],"inputType":FilterInputs.Picker},{"key":"genres","label":"GENRES","values":[{"label":"Action","value":"action"},{"label":"Adult","value":"adult"},{"label":"Adventure","value":"adventure"},{"label":"Cartoon","value":"cartoon"},{"label":"Comedy","value":"comedy"},{"label":"Cooking","value":"cooking"},{"label":"Detective","value":"detective"},{"label":"Drama","value":"drama"},{"label":"Fantasy","value":"fantasy"},{"label":"Game","value":"game"},{"label":"Gender Bender","value":"gender-bender"},{"label":"Historical","value":"historical"},{"label":"History","value":"history"},{"label":"Horror","value":"horror"},{"label":"Josei","value":"josei"},{"label":"Live action","value":"live-action"},{"label":"Martial","value":"martial"},{"label":"Martial Arts","value":"martial-arts"},{"label":"Mature","value":"mature"},{"label":"Mecha","value":"mecha"},{"label":"Mystery","value":"mystery"},{"label":"One shot","value":"one-shot"},{"label":"Premium","value":"premium"},{"label":"Psychological","value":"psychological"},{"label":"Reincarnation","value":"reincarnation"},{"label":"Romance","value":"romance"},{"label":"School Life","value":"school-life"},{"label":"Sci-fi","value":"sci-fi"},{"label":"Slice of Life","value":"slice-of-life"},{"label":"Smut","value":"smut"},{"label":"Sports","value":"sports"},{"label":"Supernatural","value":"supernatural"},{"label":"Tragedy","value":"tragedy"},{"label":"Wuxia","value":"wuxia"},{"label":"Xianxia","value":"xianxia"},{"label":"Xuanhuan","value":"xuanhuan"}],"inputType":FilterInputs.Picker}]; \ No newline at end of file + return chapterText; + } + async searchNovels(searchTerm: string, pageNo?: number | undefined): Promise { + const novels: Plugin.NovelItem[] = []; + const url = this.site + "?s=" + searchTerm + "&post_type=wp-manga"; + + const body = await fetchApi(url).then(res => res.text()); + + const loadedCheerio = parseHTML(body); + + + loadedCheerio('.c-tabs-item__content').each(function () { + const novelName = loadedCheerio(this).find('.post-title').text().trim(); + + let image = loadedCheerio(this).find('img'); + const novelCover = image.attr('data-src') || image.attr('src'); + + let novelUrl = loadedCheerio(this) + .find('.post-title') + .find('a') + .attr('href') || ''; + const novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + + novels.push(novel); + }); + return novels; + } + async fetchImage(url: string): Promise { + return await fetchFile(url, {}); + } +} +const plugin = new MadaraPlugin({"id":"freenovel.me","sourceSite":"https://freenovel.me/","sourceName":"FreeNovelMe","filters":[{"key":"sort","label":"Order by","values":[{"label":"Rating","value":"rating"},{"label":"A-Z","value":"alphabet"},{"label":"Latest","value":"latest"},{"label":"Most Views","value":"views"},{"label":"New","value":"new-manga"},{"label":"Trending","value":"trending"}],"inputType":"Picker"},{"key":"genres","label":"GENRES","values":[{"label":"Action","value":"action"},{"label":"Adult","value":"adult"},{"label":"Adventure","value":"adventure"},{"label":"Cartoon","value":"cartoon"},{"label":"Comedy","value":"comedy"},{"label":"Cooking","value":"cooking"},{"label":"Detective","value":"detective"},{"label":"Drama","value":"drama"},{"label":"Fantasy","value":"fantasy"},{"label":"Game","value":"game"},{"label":"Gender Bender","value":"gender-bender"},{"label":"Historical","value":"historical"},{"label":"History","value":"history"},{"label":"Horror","value":"horror"},{"label":"Josei","value":"josei"},{"label":"Live action","value":"live-action"},{"label":"Martial","value":"martial"},{"label":"Martial Arts","value":"martial-arts"},{"label":"Mature","value":"mature"},{"label":"Mecha","value":"mecha"},{"label":"Mystery","value":"mystery"},{"label":"One shot","value":"one-shot"},{"label":"Premium","value":"premium"},{"label":"Psychological","value":"psychological"},{"label":"Reincarnation","value":"reincarnation"},{"label":"Romance","value":"romance"},{"label":"School Life","value":"school-life"},{"label":"Sci-fi","value":"sci-fi"},{"label":"Slice of Life","value":"slice-of-life"},{"label":"Smut","value":"smut"},{"label":"Sports","value":"sports"},{"label":"Supernatural","value":"supernatural"},{"label":"Tragedy","value":"tragedy"},{"label":"Wuxia","value":"wuxia"},{"label":"Xianxia","value":"xianxia"},{"label":"Xuanhuan","value":"xuanhuan"}],"inputType":"Picker"}],"options":{"lang":"English"}}); +export default plugin; + \ No newline at end of file diff --git a/plugins/english/Guavaread[madara].ts b/plugins/english/Guavaread[madara].ts index 9dcafcc..e54ca29 100644 --- a/plugins/english/Guavaread[madara].ts +++ b/plugins/english/Guavaread[madara].ts @@ -1,213 +1,252 @@ +import { fetchApi, fetchFile } from "@libs/fetch"; +import { Filter } from "@libs/filterInputs"; +import { Plugin } from '@typings/plugin' import { load as parseHTML } from "cheerio"; -import { fetchFile, fetchApi } from "@libs/fetch"; -import { Novel, Plugin, Chapter } from "@typings/plugin"; -import { FilterInputs } from "@libs/filterInputs"; import { defaultCover } from "@libs/defaultCover"; -import { NovelStatus } from "@libs/novelStatus" +import { NovelStatus } from "@libs/novelStatus"; import { parseMadaraDate } from "@libs/parseMadaraDate"; import dayjs from "dayjs"; -export const id = "guavaread"; -export const name = "Guavaread [madara]"; -export const icon = "multisrc/madara/icons/guavaread.png"; -export const version = "1.0.0"; -export const site = "https://guavaread.com/"; -const baseUrl = site; +interface MadaraOptionPath{ + genres?: string, + novels?: string, + novel?: string, + chapter?: string, +} -export const popularNovels: Plugin.popularNovels = async (pageNo, {filters, showLatestNovels}) => { - const novels: Novel.Item[] = []; +const MadaraDefaultPath: MadaraOptionPath = { + novels: 'novel', + novel: 'novel', + chapter: 'novel' +} - let url = site; +interface MadaraOptions { + useNewChapterEndpoint?: boolean, + path?: MadaraOptionPath, + lang?: string, + orderBy?: string +} - if (filters?.genres) { - url += "novel-genre/" + filters.genres + '/'; - } else { - url += "novel/"; +export interface MadaraMetadata { + id: string, + sourceSite: string, + sourceName: string, + options?: MadaraOptions, + filters?: Filter[], +} +class MadaraPlugin implements Plugin.PluginBase { + id: string; + name: string; + icon: string; + site: string; + version: string; + userAgent: string; + cookieString: string; + options?: MadaraOptions; + filter?: Filter[] | undefined; + + constructor(metadata: MadaraMetadata){ + this.id = metadata.id; + this.name = metadata.sourceName + "[madara]"; + const iconFileName = metadata.sourceName.replace(/\s+/g, "").toLowerCase(); + this.icon = `multisrc/madara/icons/${iconFileName}.png`; + this.site = metadata.sourceSite; + this.version = "1.0.0"; + this.userAgent = ""; + this.cookieString = ""; + this.options = metadata.options; + this.filter = metadata.filters; } + async popularNovels(pageNo: number, {filters, showLatestNovels}: Plugin.PopularNovelsOptions): Promise { + const novels: Plugin.NovelItem[] = []; - url += '/page/' + pageNo + '/' + - '?m_orderby=' + (showLatestNovels ? 'latest' : (filters?.sort || 'rating')); - - const body = await fetchApi(url).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - - loadedCheerio('.manga-title-badges').remove(); - - loadedCheerio('.page-item-detail').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - - let novelUrl = loadedCheerio(this).find('.post-title') - .find('a') - .attr('href') || ''; - const novel: Novel.Item = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - - novels.push(novel); - }); - - return novels; -}; - -export const parseNovelAndChapters: Plugin.parseNovelAndChapters = async ( - novelUrl -) => { - const novel: Novel.instance = { - url: novelUrl, - }; - - const body = await fetchApi(novelUrl).then(res => res.text()); - - let loadedCheerio = parseHTML(body); - - loadedCheerio('.manga-title-badges').remove(); - - novel.name = loadedCheerio('.post-title h1').text().trim(); - - novel.cover = - loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || - loadedCheerio('.summary_image > a > img').attr('data-src') || - loadedCheerio('.summary_image > a > img').attr('src') || - defaultCover; - - loadedCheerio('.post-content_item, .post-content').each(function () { - const detailName = loadedCheerio(this).find('h5').text().trim(); - const detail = loadedCheerio(this).find('.summary-content').text().trim(); - - switch (detailName) { - case 'Genre(s)': - case 'التصنيفات': - novel.genres = detail.replace(/[\t\n]/g, ','); - break; - case 'Author(s)': - case 'المؤلف': - case 'المؤلف (ين)': - novel.author = detail; - break; - case 'Status': - case 'الحالة': - novel.status = - detail.includes('OnGoing') || detail.includes('مستمرة') - ? NovelStatus.Ongoing - : NovelStatus.Completed; - break; - } - }); - - loadedCheerio('div.summary__content .code-block,script').remove(); - novel.summary = loadedCheerio('div.summary__content').text().trim(); - - - let html; - - if (true) { - const novelId = - loadedCheerio('.rating-post-id').attr('value') || - loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; - - const body = { - action: "manga_get_chapters", - manga: novelId, - } - html = await fetchApi( - baseUrl + 'wp-admin/admin-ajax.php', - { - method: 'POST', - body: JSON.stringify(body), - }) - .then(res => res.text()); - } else { - html = await fetchApi( - baseUrl + 'ajax/chapters/', - { method: 'POST' }) - .then(res => res.text()); - } - - if (html !== '0') { - loadedCheerio = parseHTML(html); - } - - const chapters: Chapter.Item[] = []; - loadedCheerio('.wp-manga-chapter').each(function () { - const chapterName = loadedCheerio(this).find('a').text().trim(); - - let releaseDate = null; - releaseDate = loadedCheerio(this) - .find('span.chapter-release-date') - .text() - .trim(); - - if (releaseDate) { - releaseDate = parseMadaraDate(releaseDate); + let url = this.site; + if (filters?.genres && this.options?.path?.genres) { + url += this.options?.path?.genres + filters.genres + '/'; } else { - /** - * Insert current date - */ - - releaseDate = dayjs().format('LL'); + url += this.options?.path?.novels ? this.options.path.novels : MadaraDefaultPath.novels; } + + url += '/page/' + pageNo + '/' + + '?m_orderby=' + (showLatestNovels ? 'latest' : (filters?.sort || 'rating')); + + const body = await fetchApi(url).then(res => res.text()); + + const loadedCheerio = parseHTML(body); + + loadedCheerio('.manga-title-badges').remove(); + + loadedCheerio('.page-item-detail').each(function () { + const novelName = loadedCheerio(this).find('.post-title').text().trim(); + let image = loadedCheerio(this).find('img'); + const novelCover = image.attr('data-src') || image.attr('src'); + + let novelUrl = loadedCheerio(this).find('.post-title') + .find('a') + .attr('href') || ''; + const novel: Plugin.NovelItem = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + + novels.push(novel); + }); + + return novels; + } + async parseNovelAndChapters(novelUrl: string): Promise { + const novel: Plugin.SourceNovel = { + url: novelUrl, + }; + + const body = await fetchApi(novelUrl).then(res => res.text()); + + let loadedCheerio = parseHTML(body); + + loadedCheerio('.manga-title-badges, #manga-title span').remove(); + novel.name = + loadedCheerio('.post-title h1').text().trim() || + loadedCheerio('#manga-title h1').text(); + + novel.cover = + loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || + loadedCheerio('.summary_image > a > img').attr('data-src') || + loadedCheerio('.summary_image > a > img').attr('src') || + defaultCover; + + loadedCheerio('.post-content_item, .post-content').each(function () { + const detailName = loadedCheerio(this).find('h5').text().trim(); + const detail = loadedCheerio(this).find('.summary-content').text().trim(); + + switch (detailName) { + case 'Genre(s)': + case 'التصنيفات': + novel.genres = detail.replace(/[\\t\\n]/g, ','); + break; + case 'Author(s)': + case 'المؤلف': + case 'المؤلف (ين)': + novel.author = detail; + break; + case 'Status': + case 'الحالة': + novel.status = + detail.includes('OnGoing') || detail.includes('مستمرة') + ? NovelStatus.Ongoing + : NovelStatus.Completed; + break; + } + }); + + loadedCheerio('div.summary__content .code-block,script').remove(); + novel.summary = + loadedCheerio('div.summary__content').text().trim() || + loadedCheerio('#tab-manga-about').text().trim() || + loadedCheerio('.post-content_item h5:contains("Summary")').next().text().trim(); + + let html; + + if (this.options?.useNewChapterEndpoint !== true) { + const novelId = + loadedCheerio('.rating-post-id').attr('value') || + loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; + + const formData = new FormData() + formData.append("action", "manga_get_chapters"); + formData.append("manga", novelId); - let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + html = await fetchApi( + this.site + 'wp-admin/admin-ajax.php', + { + method: 'POST', + body: formData, + }) + .then(res => res.text()); + } else { + html = await fetchApi( + novelUrl + 'ajax/chapters/', + { method: 'POST' }) + .then(res => res.text()); + } + + if (html !== '0') { + loadedCheerio = parseHTML(html); + } + + const chapters: Plugin.ChapterItem[] = []; + loadedCheerio('.wp-manga-chapter').each(function () { + const chapterName = loadedCheerio(this).find('a').text().trim(); + + let releaseDate = null; + releaseDate = loadedCheerio(this) + .find('span.chapter-release-date') + .text() + .trim(); + + if (releaseDate) { + releaseDate = parseMadaraDate(releaseDate); + } else { + /** + * Insert current date + */ + + releaseDate = dayjs().format('LL'); + } + + let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + + chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); + }); + + novel.chapters = chapters.reverse(); + return novel; + } + async parseChapter(chapterUrl: string): Promise { + const body = await fetchApi(chapterUrl).then(res => res.text()); - chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); - }); + const loadedCheerio = parseHTML(body); + const chapterText = + loadedCheerio('.text-left').html() || + loadedCheerio('.text-right').html() || + loadedCheerio('.entry-content').html() || ""; - novel.chapters = chapters.reverse(); - return novel; -}; - -export const parseChapter: Plugin.parseChapter = async (chapterUrl) => { - const url = baseUrl + "/" + "novel" + "/" + chapterUrl; - - const body = await fetchApi(chapterUrl).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - const chapterText = - loadedCheerio('.text-left').html() || - loadedCheerio('.text-right').html() || - loadedCheerio('.entry-content').html(); - - return chapterText; -}; - -export const searchNovels: Plugin.searchNovels = async (searchTerm) => { - const novels: Novel.Item[] = []; - const url = baseUrl + "?s=" + searchTerm + "&post_type=wp-manga"; - - const body = await fetchApi(url).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - - - loadedCheerio('.c-tabs-item__content').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - - let novelUrl = loadedCheerio(this) - .find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - - novels.push(novel); - }); - return novels; -}; - -export const fetchImage: Plugin.fetchImage = async (url) => { - return await fetchFile(url); -}; - -export const filters = [{"key":"sort","label":"Order by","values":[{"label":"Rating","value":"rating"},{"label":"A-Z","value":"alphabet"},{"label":"Latest","value":"latest"},{"label":"Most Views","value":"views"},{"label":"New","value":"new-manga"},{"label":"Trending","value":"trending"}],"inputType":FilterInputs.Picker},{"key":"genres","label":"GENRES","values":[{"label":"Action","value":"action"},{"label":"Adult","value":"adult"},{"label":"Adventure","value":"adventure"},{"label":"Comedy","value":"comedy"},{"label":"Complete","value":"complete"},{"label":"Cooking","value":"cooking"},{"label":"Detective","value":"detective"},{"label":"Drama","value":"drama"},{"label":"Dropped","value":"dropped"},{"label":"Ecchi","value":"ecchi"},{"label":"Fantasy","value":"fantasy"},{"label":"Gender Bender","value":"gender-bender"},{"label":"Historical","value":"historical"},{"label":"Horror","value":"horror"},{"label":"Josei","value":"josei"},{"label":"Mature","value":"mature"},{"label":"Mystery","value":"mystery"},{"label":"Original Story","value":"original-story"},{"label":"Pilot","value":"pilot"},{"label":"Psychological","value":"psychological"},{"label":"R-15","value":"r-15"},{"label":"R-19","value":"r-19"},{"label":"Reverse Harem","value":"reverse-harem"},{"label":"Romance","value":"romance"},{"label":"School Life","value":"school-life"},{"label":"Sci-fi","value":"sci-fi"},{"label":"Shoujo","value":"shoujo"},{"label":"Slice of Life","value":"slice-of-life"},{"label":"Smut","value":"smut"},{"label":"Supernatural","value":"supernatural"},{"label":"Tragedy","value":"tragedy"}],"inputType":FilterInputs.Picker}]; \ No newline at end of file + return chapterText; + } + async searchNovels(searchTerm: string, pageNo?: number | undefined): Promise { + const novels: Plugin.NovelItem[] = []; + const url = this.site + "?s=" + searchTerm + "&post_type=wp-manga"; + + const body = await fetchApi(url).then(res => res.text()); + + const loadedCheerio = parseHTML(body); + + + loadedCheerio('.c-tabs-item__content').each(function () { + const novelName = loadedCheerio(this).find('.post-title').text().trim(); + + let image = loadedCheerio(this).find('img'); + const novelCover = image.attr('data-src') || image.attr('src'); + + let novelUrl = loadedCheerio(this) + .find('.post-title') + .find('a') + .attr('href') || ''; + const novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + + novels.push(novel); + }); + return novels; + } + async fetchImage(url: string): Promise { + return await fetchFile(url, {}); + } +} +const plugin = new MadaraPlugin({"id":"guavaread","sourceSite":"https://guavaread.com/","sourceName":"Guavaread","filters":[{"key":"sort","label":"Order by","values":[{"label":"Rating","value":"rating"},{"label":"A-Z","value":"alphabet"},{"label":"Latest","value":"latest"},{"label":"Most Views","value":"views"},{"label":"New","value":"new-manga"},{"label":"Trending","value":"trending"}],"inputType":"Picker"},{"key":"genres","label":"GENRES","values":[{"label":"Action","value":"action"},{"label":"Adult","value":"adult"},{"label":"Adventure","value":"adventure"},{"label":"Comedy","value":"comedy"},{"label":"Complete","value":"complete"},{"label":"Cooking","value":"cooking"},{"label":"Detective","value":"detective"},{"label":"Drama","value":"drama"},{"label":"Dropped","value":"dropped"},{"label":"Ecchi","value":"ecchi"},{"label":"Fantasy","value":"fantasy"},{"label":"Gender Bender","value":"gender-bender"},{"label":"Historical","value":"historical"},{"label":"Horror","value":"horror"},{"label":"Josei","value":"josei"},{"label":"Mature","value":"mature"},{"label":"Mystery","value":"mystery"},{"label":"Original Story","value":"original-story"},{"label":"Pilot","value":"pilot"},{"label":"Psychological","value":"psychological"},{"label":"R-15","value":"r-15"},{"label":"R-19","value":"r-19"},{"label":"Reverse Harem","value":"reverse-harem"},{"label":"Romance","value":"romance"},{"label":"School Life","value":"school-life"},{"label":"Sci-fi","value":"sci-fi"},{"label":"Shoujo","value":"shoujo"},{"label":"Slice of Life","value":"slice-of-life"},{"label":"Smut","value":"smut"},{"label":"Supernatural","value":"supernatural"},{"label":"Tragedy","value":"tragedy"}],"inputType":"Picker"}],"options":{"useNewChapterEndpoint":true,"lang":"English"}}); +export default plugin; + \ No newline at end of file diff --git a/plugins/english/LightNovelHeaven[madara].ts b/plugins/english/LightNovelHeaven[madara].ts index fb44646..eeaa04d 100644 --- a/plugins/english/LightNovelHeaven[madara].ts +++ b/plugins/english/LightNovelHeaven[madara].ts @@ -1,213 +1,252 @@ +import { fetchApi, fetchFile } from "@libs/fetch"; +import { Filter } from "@libs/filterInputs"; +import { Plugin } from '@typings/plugin' import { load as parseHTML } from "cheerio"; -import { fetchFile, fetchApi } from "@libs/fetch"; -import { Novel, Plugin, Chapter } from "@typings/plugin"; -import { FilterInputs } from "@libs/filterInputs"; import { defaultCover } from "@libs/defaultCover"; -import { NovelStatus } from "@libs/novelStatus" +import { NovelStatus } from "@libs/novelStatus"; import { parseMadaraDate } from "@libs/parseMadaraDate"; import dayjs from "dayjs"; -export const id = "lnheaven"; -export const name = "LightNovelHeaven [madara]"; -export const icon = "multisrc/madara/icons/lightnovelheaven.png"; -export const version = "1.0.0"; -export const site = "https://lightnovelheaven.com/"; -const baseUrl = site; +interface MadaraOptionPath{ + genres?: string, + novels?: string, + novel?: string, + chapter?: string, +} -export const popularNovels: Plugin.popularNovels = async (pageNo, {filters, showLatestNovels}) => { - const novels: Novel.Item[] = []; +const MadaraDefaultPath: MadaraOptionPath = { + novels: 'novel', + novel: 'novel', + chapter: 'novel' +} - let url = site; +interface MadaraOptions { + useNewChapterEndpoint?: boolean, + path?: MadaraOptionPath, + lang?: string, + orderBy?: string +} - if (filters?.genres) { - url += "novel-genre/" + filters.genres + '/'; - } else { - url += "series/"; +export interface MadaraMetadata { + id: string, + sourceSite: string, + sourceName: string, + options?: MadaraOptions, + filters?: Filter[], +} +class MadaraPlugin implements Plugin.PluginBase { + id: string; + name: string; + icon: string; + site: string; + version: string; + userAgent: string; + cookieString: string; + options?: MadaraOptions; + filter?: Filter[] | undefined; + + constructor(metadata: MadaraMetadata){ + this.id = metadata.id; + this.name = metadata.sourceName + "[madara]"; + const iconFileName = metadata.sourceName.replace(/\s+/g, "").toLowerCase(); + this.icon = `multisrc/madara/icons/${iconFileName}.png`; + this.site = metadata.sourceSite; + this.version = "1.0.0"; + this.userAgent = ""; + this.cookieString = ""; + this.options = metadata.options; + this.filter = metadata.filters; } + async popularNovels(pageNo: number, {filters, showLatestNovels}: Plugin.PopularNovelsOptions): Promise { + const novels: Plugin.NovelItem[] = []; - url += '/page/' + pageNo + '/' + - '?m_orderby=' + (showLatestNovels ? 'latest' : (filters?.sort || 'rating')); - - const body = await fetchApi(url).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - - loadedCheerio('.manga-title-badges').remove(); - - loadedCheerio('.page-item-detail').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - - let novelUrl = loadedCheerio(this).find('.post-title') - .find('a') - .attr('href') || ''; - const novel: Novel.Item = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - - novels.push(novel); - }); - - return novels; -}; - -export const parseNovelAndChapters: Plugin.parseNovelAndChapters = async ( - novelUrl -) => { - const novel: Novel.instance = { - url: novelUrl, - }; - - const body = await fetchApi(novelUrl).then(res => res.text()); - - let loadedCheerio = parseHTML(body); - - loadedCheerio('.manga-title-badges').remove(); - - novel.name = loadedCheerio('.post-title h1').text().trim(); - - novel.cover = - loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || - loadedCheerio('.summary_image > a > img').attr('data-src') || - loadedCheerio('.summary_image > a > img').attr('src') || - defaultCover; - - loadedCheerio('.post-content_item, .post-content').each(function () { - const detailName = loadedCheerio(this).find('h5').text().trim(); - const detail = loadedCheerio(this).find('.summary-content').text().trim(); - - switch (detailName) { - case 'Genre(s)': - case 'التصنيفات': - novel.genres = detail.replace(/[\t\n]/g, ','); - break; - case 'Author(s)': - case 'المؤلف': - case 'المؤلف (ين)': - novel.author = detail; - break; - case 'Status': - case 'الحالة': - novel.status = - detail.includes('OnGoing') || detail.includes('مستمرة') - ? NovelStatus.Ongoing - : NovelStatus.Completed; - break; - } - }); - - loadedCheerio('div.summary__content .code-block,script').remove(); - novel.summary = loadedCheerio('div.summary__content').text().trim(); - - - let html; - - if (true) { - const novelId = - loadedCheerio('.rating-post-id').attr('value') || - loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; - - const body = { - action: "manga_get_chapters", - manga: novelId, - } - html = await fetchApi( - baseUrl + 'wp-admin/admin-ajax.php', - { - method: 'POST', - body: JSON.stringify(body), - }) - .then(res => res.text()); - } else { - html = await fetchApi( - baseUrl + 'ajax/chapters/', - { method: 'POST' }) - .then(res => res.text()); - } - - if (html !== '0') { - loadedCheerio = parseHTML(html); - } - - const chapters: Chapter.Item[] = []; - loadedCheerio('.wp-manga-chapter').each(function () { - const chapterName = loadedCheerio(this).find('a').text().trim(); - - let releaseDate = null; - releaseDate = loadedCheerio(this) - .find('span.chapter-release-date') - .text() - .trim(); - - if (releaseDate) { - releaseDate = parseMadaraDate(releaseDate); + let url = this.site; + if (filters?.genres && this.options?.path?.genres) { + url += this.options?.path?.genres + filters.genres + '/'; } else { - /** - * Insert current date - */ - - releaseDate = dayjs().format('LL'); + url += this.options?.path?.novels ? this.options.path.novels : MadaraDefaultPath.novels; } + + url += '/page/' + pageNo + '/' + + '?m_orderby=' + (showLatestNovels ? 'latest' : (filters?.sort || 'rating')); + + const body = await fetchApi(url).then(res => res.text()); + + const loadedCheerio = parseHTML(body); + + loadedCheerio('.manga-title-badges').remove(); + + loadedCheerio('.page-item-detail').each(function () { + const novelName = loadedCheerio(this).find('.post-title').text().trim(); + let image = loadedCheerio(this).find('img'); + const novelCover = image.attr('data-src') || image.attr('src'); + + let novelUrl = loadedCheerio(this).find('.post-title') + .find('a') + .attr('href') || ''; + const novel: Plugin.NovelItem = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + + novels.push(novel); + }); + + return novels; + } + async parseNovelAndChapters(novelUrl: string): Promise { + const novel: Plugin.SourceNovel = { + url: novelUrl, + }; + + const body = await fetchApi(novelUrl).then(res => res.text()); + + let loadedCheerio = parseHTML(body); + + loadedCheerio('.manga-title-badges, #manga-title span').remove(); + novel.name = + loadedCheerio('.post-title h1').text().trim() || + loadedCheerio('#manga-title h1').text(); + + novel.cover = + loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || + loadedCheerio('.summary_image > a > img').attr('data-src') || + loadedCheerio('.summary_image > a > img').attr('src') || + defaultCover; + + loadedCheerio('.post-content_item, .post-content').each(function () { + const detailName = loadedCheerio(this).find('h5').text().trim(); + const detail = loadedCheerio(this).find('.summary-content').text().trim(); + + switch (detailName) { + case 'Genre(s)': + case 'التصنيفات': + novel.genres = detail.replace(/[\\t\\n]/g, ','); + break; + case 'Author(s)': + case 'المؤلف': + case 'المؤلف (ين)': + novel.author = detail; + break; + case 'Status': + case 'الحالة': + novel.status = + detail.includes('OnGoing') || detail.includes('مستمرة') + ? NovelStatus.Ongoing + : NovelStatus.Completed; + break; + } + }); + + loadedCheerio('div.summary__content .code-block,script').remove(); + novel.summary = + loadedCheerio('div.summary__content').text().trim() || + loadedCheerio('#tab-manga-about').text().trim() || + loadedCheerio('.post-content_item h5:contains("Summary")').next().text().trim(); + + let html; + + if (this.options?.useNewChapterEndpoint !== true) { + const novelId = + loadedCheerio('.rating-post-id').attr('value') || + loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; + + const formData = new FormData() + formData.append("action", "manga_get_chapters"); + formData.append("manga", novelId); - let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + html = await fetchApi( + this.site + 'wp-admin/admin-ajax.php', + { + method: 'POST', + body: formData, + }) + .then(res => res.text()); + } else { + html = await fetchApi( + novelUrl + 'ajax/chapters/', + { method: 'POST' }) + .then(res => res.text()); + } + + if (html !== '0') { + loadedCheerio = parseHTML(html); + } + + const chapters: Plugin.ChapterItem[] = []; + loadedCheerio('.wp-manga-chapter').each(function () { + const chapterName = loadedCheerio(this).find('a').text().trim(); + + let releaseDate = null; + releaseDate = loadedCheerio(this) + .find('span.chapter-release-date') + .text() + .trim(); + + if (releaseDate) { + releaseDate = parseMadaraDate(releaseDate); + } else { + /** + * Insert current date + */ + + releaseDate = dayjs().format('LL'); + } + + let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + + chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); + }); + + novel.chapters = chapters.reverse(); + return novel; + } + async parseChapter(chapterUrl: string): Promise { + const body = await fetchApi(chapterUrl).then(res => res.text()); - chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); - }); + const loadedCheerio = parseHTML(body); + const chapterText = + loadedCheerio('.text-left').html() || + loadedCheerio('.text-right').html() || + loadedCheerio('.entry-content').html() || ""; - novel.chapters = chapters.reverse(); - return novel; -}; - -export const parseChapter: Plugin.parseChapter = async (chapterUrl) => { - const url = baseUrl + "/" + "series" + "/" + chapterUrl; - - const body = await fetchApi(chapterUrl).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - const chapterText = - loadedCheerio('.text-left').html() || - loadedCheerio('.text-right').html() || - loadedCheerio('.entry-content').html(); - - return chapterText; -}; - -export const searchNovels: Plugin.searchNovels = async (searchTerm) => { - const novels: Novel.Item[] = []; - const url = baseUrl + "?s=" + searchTerm + "&post_type=wp-manga"; - - const body = await fetchApi(url).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - - - loadedCheerio('.c-tabs-item__content').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - - let novelUrl = loadedCheerio(this) - .find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - - novels.push(novel); - }); - return novels; -}; - -export const fetchImage: Plugin.fetchImage = async (url) => { - return await fetchFile(url); -}; - -export const filters = [{"key":"sort","label":"Order by","values":[{"label":"Rating","value":"rating"},{"label":"A-Z","value":"alphabet"},{"label":"Latest","value":"latest"},{"label":"Most Views","value":"views"},{"label":"New","value":"new-manga"},{"label":"Trending","value":"trending"}],"inputType":FilterInputs.Picker}]; \ No newline at end of file + return chapterText; + } + async searchNovels(searchTerm: string, pageNo?: number | undefined): Promise { + const novels: Plugin.NovelItem[] = []; + const url = this.site + "?s=" + searchTerm + "&post_type=wp-manga"; + + const body = await fetchApi(url).then(res => res.text()); + + const loadedCheerio = parseHTML(body); + + + loadedCheerio('.c-tabs-item__content').each(function () { + const novelName = loadedCheerio(this).find('.post-title').text().trim(); + + let image = loadedCheerio(this).find('img'); + const novelCover = image.attr('data-src') || image.attr('src'); + + let novelUrl = loadedCheerio(this) + .find('.post-title') + .find('a') + .attr('href') || ''; + const novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + + novels.push(novel); + }); + return novels; + } + async fetchImage(url: string): Promise { + return await fetchFile(url, {}); + } +} +const plugin = new MadaraPlugin({"id":"lnheaven","sourceSite":"https://lightnovelheaven.com/","sourceName":"LightNovelHeaven","filters":[{"key":"sort","label":"Order by","values":[{"label":"Rating","value":"rating"},{"label":"A-Z","value":"alphabet"},{"label":"Latest","value":"latest"},{"label":"Most Views","value":"views"},{"label":"New","value":"new-manga"},{"label":"Trending","value":"trending"}],"inputType":"Picker"}],"options":{"path":{"novels":"series","novel":"series","chapter":"series"},"useNewChapterEndpoint":true,"lang":"English"}}); +export default plugin; + \ No newline at end of file diff --git a/plugins/english/LightNovelReader.ts b/plugins/english/LightNovelReader.broken.ts similarity index 100% rename from plugins/english/LightNovelReader.ts rename to plugins/english/LightNovelReader.broken.ts diff --git a/plugins/english/Ltnovelcom[readwn].ts b/plugins/english/Ltnovelcom[readwn].ts deleted file mode 100644 index dcc57e1..0000000 --- a/plugins/english/Ltnovelcom[readwn].ts +++ /dev/null @@ -1,195 +0,0 @@ - -import { load as parseHTML } from "cheerio"; -// import dayjs from 'dayjs'; -import { fetchFile, fetchApi } from "@libs/fetch"; -import { Novel, Plugin, Chapter } from "@typings/plugin"; -import { parseMadaraDate } from "@libs/parseMadaraDate"; -// import { isUrlAbsolute } from '@libs/isAbsoluteUrl'; -// import { showToast } from "@libs/showToast"; -import { FilterInputs } from "@libs/filterInputs"; -// import { NovelStatus } from '@libs/novelStatus'; -// import { defaultCover } from "@libs/defaultCover"; - -export const id = "Ltnovel.com"; -export const name = "Ltnovel.com"; -export const icon = "multisrc/readwn/icons/ltnovel.png"; -export const version = "1.0.0"; -export const site = "https://www.ltnovel.com/"; - -export const popularNovels: Plugin.popularNovels = async function ( - page, - { filters, showLatestNovels } -) { - const novels: Novel.Item[] = []; - const pageNo = page - 1; - - let url = site + 'list/'; - url += (filters?.genres || 'all') + '/'; - url += (filters?.status || 'all') + '-'; - url += (showLatestNovels ? 'lastdotime' : filters?.sort || 'newstime') + '-'; - url += pageNo + '.html'; - - const result = await fetchApi(url); - const body = await result.text(); - - const loadedCheerio = parseHTML(body); - - - loadedCheerio('li.novel-item').each(function () { - const novelName = loadedCheerio(this).find('h4').text(); - const novelUrl = site + loadedCheerio(this).find('a').attr('href'); - - const coverUri = loadedCheerio(this) - .find('.novel-cover > img') - .attr('data-src'); - - const novelCover = site + coverUri; - - const novel = { name: novelName, cover: novelCover, url: novelUrl }; - - novels.push(novel); - }); - - return novels; -}; - - -export const parseNovelAndChapters: Plugin.parseNovelAndChapters = - async function (novelUrl) { - const result = await fetchApi(novelUrl); - const body = await result.text(); - - let loadedCheerio = parseHTML(body); - - const novel: Novel.instance = { - url: novelUrl, - chapters: [], - }; - - novel.name = loadedCheerio('h1.novel-title').text(); - - const coverUri = loadedCheerio('figure.cover > img').attr('data-src'); - novel.cover = site + coverUri; - - novel.summary = loadedCheerio('.summary') - .text() - .replace('Summary', '') - .trim(); - - novel.genres = ''; - - loadedCheerio('div.categories > ul > li').each(function () { - novel.genres += loadedCheerio(this).text().trim() + ','; - }); - - loadedCheerio('div.header-stats > span').each(function () { - if (loadedCheerio(this).find('small').text() === 'Status') { - novel.status = loadedCheerio(this).find('strong').text(); - } - }); - - novel.genres = novel.genres.slice(0, -1); - - novel.author = loadedCheerio('span[itemprop=author]').text(); - - let novelChapters: Chapter.Item[] = []; - - const novelId = novelUrl.replace('.html', '').replace(site, ''); - - const latestChapterNo = parseInt(loadedCheerio('.header-stats') - .find('span > strong') - .first() - .text() - .trim()); - - let lastChapterNo = 1; - loadedCheerio('.chapter-list li').each(function () { - const chapterName = loadedCheerio(this) - .find('a .chapter-title') - .text() - .trim(); - - const chapterUrl = site + loadedCheerio(this).find('a').attr('href')?.trim(); - - const releaseDate = loadedCheerio(this) - .find('a .chapter-update') - .text() - .trim(); - - lastChapterNo = parseInt(loadedCheerio(this).find('a .chapter-no').text().trim()); - - const chapter = { name: chapterName, releaseTime: parseMadaraDate(releaseDate), url: chapterUrl }; - - novelChapters.push(chapter); - }); - - // Itterate once more before loop to finish off - lastChapterNo++; - for (let i = lastChapterNo; i <= latestChapterNo; i++) { - const chapterName = 'Chapter ' + i; - const chapterUrl = site + novelId+'_'+ i +'.html'; - const releaseDate = null; - - const chapter = { name: chapterName, releaseTime: releaseDate,url: chapterUrl }; - - novelChapters.push(chapter); - } - - novel.chapters = novelChapters; - return novel; - }; - -export const parseChapter: Plugin.parseChapter = async function (chapterUrl) { - const result = await fetchApi(chapterUrl); - const body = await result.text(); - - const loadedCheerio = parseHTML(body); - - const chapterText = loadedCheerio('.chapter-content').html(); - return chapterText; -}; - -export const searchNovels: Plugin.searchNovels = async (searchTerm) => { - const novels: Novel.Item[] = []; - const searchUrl = site + 'e/search/index.php'; - - const result = await fetchApi(searchUrl, { - headers: { - 'Content-Type': 'application/x-www-form-urlencoded', - Referer: site + 'search.html', - Origin: site, - 'user-agent': - 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36', - }, - method: 'POST', - body: JSON.stringify({ - show: 'title', - tempid: 1, - tbname: 'news', - keyboard: searchTerm, - }), - }); - const body = await result.text(); - - const loadedCheerio = parseHTML(body); - - loadedCheerio('li.novel-item').each(function () { - const novelName = loadedCheerio(this).find('h4').text(); - const novelUrl = site + loadedCheerio(this).find('a').attr('href'); - - const coverUri = site + loadedCheerio(this).find('img').attr('data-src'); - const novelCover = site + coverUri; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - - novels.push(novel); - }); - return novels; -}; - -export const fetchImage: Plugin.fetchImage = fetchFile; - -export const filters = [{"key":"sort","label":"Sort By","values":[{"label":"New","value":"newstime"},{"label":"Popular","value":"onclick"},{"label":"Updates","value":"lastdotime"}], "inputType":FilterInputs.Picker},{"key":"status","label":"Status","values":[{"label":"All","value":"all"},{"label":"Completed","value":"Completed"},{"label":"Ongoing","value":"Ongoing"}], "inputType":FilterInputs.Picker},{"key":"genres","label":"Genre / Category","values":[{"label":"All","value":"all"},{"label":"Action","value":"action"},{"label":"Adult","value":"adult"},{"label":"Adventure","value":"adventure"},{"label":"Comedy","value":"comedy"},{"label":"Contemporary Romance","value":"contemporary-romance"},{"label":"Drama","value":"drama"},{"label":"Eastern Fantasy","value":"eastern-fantasy"},{"label":"Ecchi","value":"ecchi"},{"label":"Fantasy","value":"fantasy"},{"label":"Fantasy Romance","value":"fantasy-romance"},{"label":"Game","value":"game"},{"label":"Gender Bender","value":"gender-bender"},{"label":"Harem","value":"harem"},{"label":"Historical","value":"historical"},{"label":"Horror","value":"horror"},{"label":"Josei","value":"josei"},{"label":"Lolicon","value":"lolicon"},{"label":"Magical Realism","value":"magical-realism"},{"label":"Martial Arts","value":"martial-arts"},{"label":"Mature","value":"mature"},{"label":"Mecha","value":"mecha"},{"label":"Mystery","value":"mystery"},{"label":"Psychological","value":"psychological"},{"label":"Romance","value":"romance"},{"label":"School Life","value":"school-life"},{"label":"Sci-fi","value":"sci-fi"},{"label":"Seinen","value":"seinen"},{"label":"Shoujo","value":"shoujo"},{"label":"Shounen","value":"shounen"},{"label":"Shounen Ai","value":"shounen-ai"},{"label":"Slice of Life","value":"slice-of-life"},{"label":"Smut","value":"smut"},{"label":"Sports","value":"sports"},{"label":"Supernatural","value":"supernatural"},{"label":"Tragedy","value":"tragedy"},{"label":"Video Games","value":"video-games"},{"label":"Wuxia","value":"wuxia"},{"label":"Xianxia","value":"xianxia"},{"label":"Xuanhuan","value":"xuanhuan"},{"label":"Yaoi","value":"yaoi"}], "inputType":FilterInputs.Picker}]; \ No newline at end of file diff --git a/plugins/english/LunarLetters[madara].ts b/plugins/english/LunarLetters[madara].ts index cb6ba59..c259387 100644 --- a/plugins/english/LunarLetters[madara].ts +++ b/plugins/english/LunarLetters[madara].ts @@ -1,213 +1,252 @@ +import { fetchApi, fetchFile } from "@libs/fetch"; +import { Filter } from "@libs/filterInputs"; +import { Plugin } from '@typings/plugin' import { load as parseHTML } from "cheerio"; -import { fetchFile, fetchApi } from "@libs/fetch"; -import { Novel, Plugin, Chapter } from "@typings/plugin"; -import { FilterInputs } from "@libs/filterInputs"; import { defaultCover } from "@libs/defaultCover"; -import { NovelStatus } from "@libs/novelStatus" +import { NovelStatus } from "@libs/novelStatus"; import { parseMadaraDate } from "@libs/parseMadaraDate"; import dayjs from "dayjs"; -export const id = "lunarletters"; -export const name = "LunarLetters [madara]"; -export const icon = "multisrc/madara/icons/lunarletters.png"; -export const version = "1.0.0"; -export const site = "https://www.lunarletters.com/"; -const baseUrl = site; +interface MadaraOptionPath{ + genres?: string, + novels?: string, + novel?: string, + chapter?: string, +} -export const popularNovels: Plugin.popularNovels = async (pageNo, {filters, showLatestNovels}) => { - const novels: Novel.Item[] = []; +const MadaraDefaultPath: MadaraOptionPath = { + novels: 'novel', + novel: 'novel', + chapter: 'novel' +} - let url = site; +interface MadaraOptions { + useNewChapterEndpoint?: boolean, + path?: MadaraOptionPath, + lang?: string, + orderBy?: string +} - if (filters?.genres) { - url += "novel-genre/" + filters.genres + '/'; - } else { - url += "series/"; +export interface MadaraMetadata { + id: string, + sourceSite: string, + sourceName: string, + options?: MadaraOptions, + filters?: Filter[], +} +class MadaraPlugin implements Plugin.PluginBase { + id: string; + name: string; + icon: string; + site: string; + version: string; + userAgent: string; + cookieString: string; + options?: MadaraOptions; + filter?: Filter[] | undefined; + + constructor(metadata: MadaraMetadata){ + this.id = metadata.id; + this.name = metadata.sourceName + "[madara]"; + const iconFileName = metadata.sourceName.replace(/\s+/g, "").toLowerCase(); + this.icon = `multisrc/madara/icons/${iconFileName}.png`; + this.site = metadata.sourceSite; + this.version = "1.0.0"; + this.userAgent = ""; + this.cookieString = ""; + this.options = metadata.options; + this.filter = metadata.filters; } + async popularNovels(pageNo: number, {filters, showLatestNovels}: Plugin.PopularNovelsOptions): Promise { + const novels: Plugin.NovelItem[] = []; - url += '/page/' + pageNo + '/' + - '?m_orderby=' + (showLatestNovels ? 'latest' : (filters?.sort || 'rating')); - - const body = await fetchApi(url).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - - loadedCheerio('.manga-title-badges').remove(); - - loadedCheerio('.page-item-detail').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - - let novelUrl = loadedCheerio(this).find('.post-title') - .find('a') - .attr('href') || ''; - const novel: Novel.Item = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - - novels.push(novel); - }); - - return novels; -}; - -export const parseNovelAndChapters: Plugin.parseNovelAndChapters = async ( - novelUrl -) => { - const novel: Novel.instance = { - url: novelUrl, - }; - - const body = await fetchApi(novelUrl).then(res => res.text()); - - let loadedCheerio = parseHTML(body); - - loadedCheerio('.manga-title-badges').remove(); - - novel.name = loadedCheerio('.post-title h1').text().trim(); - - novel.cover = - loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || - loadedCheerio('.summary_image > a > img').attr('data-src') || - loadedCheerio('.summary_image > a > img').attr('src') || - defaultCover; - - loadedCheerio('.post-content_item, .post-content').each(function () { - const detailName = loadedCheerio(this).find('h5').text().trim(); - const detail = loadedCheerio(this).find('.summary-content').text().trim(); - - switch (detailName) { - case 'Genre(s)': - case 'التصنيفات': - novel.genres = detail.replace(/[\t\n]/g, ','); - break; - case 'Author(s)': - case 'المؤلف': - case 'المؤلف (ين)': - novel.author = detail; - break; - case 'Status': - case 'الحالة': - novel.status = - detail.includes('OnGoing') || detail.includes('مستمرة') - ? NovelStatus.Ongoing - : NovelStatus.Completed; - break; - } - }); - - loadedCheerio('div.summary__content .code-block,script').remove(); - novel.summary = loadedCheerio('div.summary__content').text().trim(); - - - let html; - - if (true) { - const novelId = - loadedCheerio('.rating-post-id').attr('value') || - loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; - - const body = { - action: "manga_get_chapters", - manga: novelId, - } - html = await fetchApi( - baseUrl + 'wp-admin/admin-ajax.php', - { - method: 'POST', - body: JSON.stringify(body), - }) - .then(res => res.text()); - } else { - html = await fetchApi( - baseUrl + 'ajax/chapters/', - { method: 'POST' }) - .then(res => res.text()); - } - - if (html !== '0') { - loadedCheerio = parseHTML(html); - } - - const chapters: Chapter.Item[] = []; - loadedCheerio('.wp-manga-chapter').each(function () { - const chapterName = loadedCheerio(this).find('a').text().trim(); - - let releaseDate = null; - releaseDate = loadedCheerio(this) - .find('span.chapter-release-date') - .text() - .trim(); - - if (releaseDate) { - releaseDate = parseMadaraDate(releaseDate); + let url = this.site; + if (filters?.genres && this.options?.path?.genres) { + url += this.options?.path?.genres + filters.genres + '/'; } else { - /** - * Insert current date - */ - - releaseDate = dayjs().format('LL'); + url += this.options?.path?.novels ? this.options.path.novels : MadaraDefaultPath.novels; } + + url += '/page/' + pageNo + '/' + + '?m_orderby=' + (showLatestNovels ? 'latest' : (filters?.sort || 'rating')); + + const body = await fetchApi(url).then(res => res.text()); + + const loadedCheerio = parseHTML(body); + + loadedCheerio('.manga-title-badges').remove(); + + loadedCheerio('.page-item-detail').each(function () { + const novelName = loadedCheerio(this).find('.post-title').text().trim(); + let image = loadedCheerio(this).find('img'); + const novelCover = image.attr('data-src') || image.attr('src'); + + let novelUrl = loadedCheerio(this).find('.post-title') + .find('a') + .attr('href') || ''; + const novel: Plugin.NovelItem = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + + novels.push(novel); + }); + + return novels; + } + async parseNovelAndChapters(novelUrl: string): Promise { + const novel: Plugin.SourceNovel = { + url: novelUrl, + }; + + const body = await fetchApi(novelUrl).then(res => res.text()); + + let loadedCheerio = parseHTML(body); + + loadedCheerio('.manga-title-badges, #manga-title span').remove(); + novel.name = + loadedCheerio('.post-title h1').text().trim() || + loadedCheerio('#manga-title h1').text(); + + novel.cover = + loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || + loadedCheerio('.summary_image > a > img').attr('data-src') || + loadedCheerio('.summary_image > a > img').attr('src') || + defaultCover; + + loadedCheerio('.post-content_item, .post-content').each(function () { + const detailName = loadedCheerio(this).find('h5').text().trim(); + const detail = loadedCheerio(this).find('.summary-content').text().trim(); + + switch (detailName) { + case 'Genre(s)': + case 'التصنيفات': + novel.genres = detail.replace(/[\\t\\n]/g, ','); + break; + case 'Author(s)': + case 'المؤلف': + case 'المؤلف (ين)': + novel.author = detail; + break; + case 'Status': + case 'الحالة': + novel.status = + detail.includes('OnGoing') || detail.includes('مستمرة') + ? NovelStatus.Ongoing + : NovelStatus.Completed; + break; + } + }); + + loadedCheerio('div.summary__content .code-block,script').remove(); + novel.summary = + loadedCheerio('div.summary__content').text().trim() || + loadedCheerio('#tab-manga-about').text().trim() || + loadedCheerio('.post-content_item h5:contains("Summary")').next().text().trim(); + + let html; + + if (this.options?.useNewChapterEndpoint !== true) { + const novelId = + loadedCheerio('.rating-post-id').attr('value') || + loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; + + const formData = new FormData() + formData.append("action", "manga_get_chapters"); + formData.append("manga", novelId); - let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + html = await fetchApi( + this.site + 'wp-admin/admin-ajax.php', + { + method: 'POST', + body: formData, + }) + .then(res => res.text()); + } else { + html = await fetchApi( + novelUrl + 'ajax/chapters/', + { method: 'POST' }) + .then(res => res.text()); + } + + if (html !== '0') { + loadedCheerio = parseHTML(html); + } + + const chapters: Plugin.ChapterItem[] = []; + loadedCheerio('.wp-manga-chapter').each(function () { + const chapterName = loadedCheerio(this).find('a').text().trim(); + + let releaseDate = null; + releaseDate = loadedCheerio(this) + .find('span.chapter-release-date') + .text() + .trim(); + + if (releaseDate) { + releaseDate = parseMadaraDate(releaseDate); + } else { + /** + * Insert current date + */ + + releaseDate = dayjs().format('LL'); + } + + let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + + chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); + }); + + novel.chapters = chapters.reverse(); + return novel; + } + async parseChapter(chapterUrl: string): Promise { + const body = await fetchApi(chapterUrl).then(res => res.text()); - chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); - }); + const loadedCheerio = parseHTML(body); + const chapterText = + loadedCheerio('.text-left').html() || + loadedCheerio('.text-right').html() || + loadedCheerio('.entry-content').html() || ""; - novel.chapters = chapters.reverse(); - return novel; -}; - -export const parseChapter: Plugin.parseChapter = async (chapterUrl) => { - const url = baseUrl + "/" + "series" + "/" + chapterUrl; - - const body = await fetchApi(chapterUrl).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - const chapterText = - loadedCheerio('.text-left').html() || - loadedCheerio('.text-right').html() || - loadedCheerio('.entry-content').html(); - - return chapterText; -}; - -export const searchNovels: Plugin.searchNovels = async (searchTerm) => { - const novels: Novel.Item[] = []; - const url = baseUrl + "?s=" + searchTerm + "&post_type=wp-manga"; - - const body = await fetchApi(url).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - - - loadedCheerio('.c-tabs-item__content').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - - let novelUrl = loadedCheerio(this) - .find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - - novels.push(novel); - }); - return novels; -}; - -export const fetchImage: Plugin.fetchImage = async (url) => { - return await fetchFile(url); -}; - -export const filters = [{"key":"sort","label":"Order by","values":[{"label":"Rating","value":"rating"},{"label":"A-Z","value":"alphabet"},{"label":"Latest","value":"latest"},{"label":"Most Views","value":"views"},{"label":"New","value":"new-manga"},{"label":"Trending","value":"trending"}],"inputType":FilterInputs.Picker}]; \ No newline at end of file + return chapterText; + } + async searchNovels(searchTerm: string, pageNo?: number | undefined): Promise { + const novels: Plugin.NovelItem[] = []; + const url = this.site + "?s=" + searchTerm + "&post_type=wp-manga"; + + const body = await fetchApi(url).then(res => res.text()); + + const loadedCheerio = parseHTML(body); + + + loadedCheerio('.c-tabs-item__content').each(function () { + const novelName = loadedCheerio(this).find('.post-title').text().trim(); + + let image = loadedCheerio(this).find('img'); + const novelCover = image.attr('data-src') || image.attr('src'); + + let novelUrl = loadedCheerio(this) + .find('.post-title') + .find('a') + .attr('href') || ''; + const novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + + novels.push(novel); + }); + return novels; + } + async fetchImage(url: string): Promise { + return await fetchFile(url, {}); + } +} +const plugin = new MadaraPlugin({"id":"lunarletters","sourceSite":"https://www.lunarletters.com/","sourceName":"LunarLetters","filters":[{"key":"sort","label":"Order by","values":[{"label":"Rating","value":"rating"},{"label":"A-Z","value":"alphabet"},{"label":"Latest","value":"latest"},{"label":"Most Views","value":"views"},{"label":"New","value":"new-manga"},{"label":"Trending","value":"trending"}],"inputType":"Picker"}],"options":{"path":{"novels":"series","novel":"series","chapter":"series"},"useNewChapterEndpoint":true,"lang":"English"}}); +export default plugin; + \ No newline at end of file diff --git a/plugins/english/MTLNovelClub[madara].ts b/plugins/english/MTLNovelClub[madara].ts index d9baa1e..e09cada 100644 --- a/plugins/english/MTLNovelClub[madara].ts +++ b/plugins/english/MTLNovelClub[madara].ts @@ -1,213 +1,252 @@ +import { fetchApi, fetchFile } from "@libs/fetch"; +import { Filter } from "@libs/filterInputs"; +import { Plugin } from '@typings/plugin' import { load as parseHTML } from "cheerio"; -import { fetchFile, fetchApi } from "@libs/fetch"; -import { Novel, Plugin, Chapter } from "@typings/plugin"; -import { FilterInputs } from "@libs/filterInputs"; import { defaultCover } from "@libs/defaultCover"; -import { NovelStatus } from "@libs/novelStatus" +import { NovelStatus } from "@libs/novelStatus"; import { parseMadaraDate } from "@libs/parseMadaraDate"; import dayjs from "dayjs"; -export const id = "mtlnovel.club"; -export const name = "MTLNovel.Club [madara]"; -export const icon = "multisrc/madara/icons/mtlnovel.club.png"; -export const version = "1.0.0"; -export const site = "https://mtlnovel.club/"; -const baseUrl = site; +interface MadaraOptionPath{ + genres?: string, + novels?: string, + novel?: string, + chapter?: string, +} -export const popularNovels: Plugin.popularNovels = async (pageNo, {filters, showLatestNovels}) => { - const novels: Novel.Item[] = []; +const MadaraDefaultPath: MadaraOptionPath = { + novels: 'novel', + novel: 'novel', + chapter: 'novel' +} - let url = site; +interface MadaraOptions { + useNewChapterEndpoint?: boolean, + path?: MadaraOptionPath, + lang?: string, + orderBy?: string +} - if (filters?.genres) { - url += "novel-genre/" + filters.genres + '/'; - } else { - url += "novel/"; +export interface MadaraMetadata { + id: string, + sourceSite: string, + sourceName: string, + options?: MadaraOptions, + filters?: Filter[], +} +class MadaraPlugin implements Plugin.PluginBase { + id: string; + name: string; + icon: string; + site: string; + version: string; + userAgent: string; + cookieString: string; + options?: MadaraOptions; + filter?: Filter[] | undefined; + + constructor(metadata: MadaraMetadata){ + this.id = metadata.id; + this.name = metadata.sourceName + "[madara]"; + const iconFileName = metadata.sourceName.replace(/\s+/g, "").toLowerCase(); + this.icon = `multisrc/madara/icons/${iconFileName}.png`; + this.site = metadata.sourceSite; + this.version = "1.0.0"; + this.userAgent = ""; + this.cookieString = ""; + this.options = metadata.options; + this.filter = metadata.filters; } + async popularNovels(pageNo: number, {filters, showLatestNovels}: Plugin.PopularNovelsOptions): Promise { + const novels: Plugin.NovelItem[] = []; - url += '/page/' + pageNo + '/' + - '?m_orderby=' + (showLatestNovels ? 'latest' : (filters?.sort || 'rating')); - - const body = await fetchApi(url).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - - loadedCheerio('.manga-title-badges').remove(); - - loadedCheerio('.page-item-detail').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - - let novelUrl = loadedCheerio(this).find('.post-title') - .find('a') - .attr('href') || ''; - const novel: Novel.Item = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - - novels.push(novel); - }); - - return novels; -}; - -export const parseNovelAndChapters: Plugin.parseNovelAndChapters = async ( - novelUrl -) => { - const novel: Novel.instance = { - url: novelUrl, - }; - - const body = await fetchApi(novelUrl).then(res => res.text()); - - let loadedCheerio = parseHTML(body); - - loadedCheerio('.manga-title-badges').remove(); - - novel.name = loadedCheerio('.post-title h1').text().trim(); - - novel.cover = - loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || - loadedCheerio('.summary_image > a > img').attr('data-src') || - loadedCheerio('.summary_image > a > img').attr('src') || - defaultCover; - - loadedCheerio('.post-content_item, .post-content').each(function () { - const detailName = loadedCheerio(this).find('h5').text().trim(); - const detail = loadedCheerio(this).find('.summary-content').text().trim(); - - switch (detailName) { - case 'Genre(s)': - case 'التصنيفات': - novel.genres = detail.replace(/[\t\n]/g, ','); - break; - case 'Author(s)': - case 'المؤلف': - case 'المؤلف (ين)': - novel.author = detail; - break; - case 'Status': - case 'الحالة': - novel.status = - detail.includes('OnGoing') || detail.includes('مستمرة') - ? NovelStatus.Ongoing - : NovelStatus.Completed; - break; - } - }); - - loadedCheerio('div.summary__content .code-block,script').remove(); - novel.summary = loadedCheerio('div.summary__content').text().trim(); - - - let html; - - if (true) { - const novelId = - loadedCheerio('.rating-post-id').attr('value') || - loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; - - const body = { - action: "manga_get_chapters", - manga: novelId, - } - html = await fetchApi( - baseUrl + 'wp-admin/admin-ajax.php', - { - method: 'POST', - body: JSON.stringify(body), - }) - .then(res => res.text()); - } else { - html = await fetchApi( - baseUrl + 'ajax/chapters/', - { method: 'POST' }) - .then(res => res.text()); - } - - if (html !== '0') { - loadedCheerio = parseHTML(html); - } - - const chapters: Chapter.Item[] = []; - loadedCheerio('.wp-manga-chapter').each(function () { - const chapterName = loadedCheerio(this).find('a').text().trim(); - - let releaseDate = null; - releaseDate = loadedCheerio(this) - .find('span.chapter-release-date') - .text() - .trim(); - - if (releaseDate) { - releaseDate = parseMadaraDate(releaseDate); + let url = this.site; + if (filters?.genres && this.options?.path?.genres) { + url += this.options?.path?.genres + filters.genres + '/'; } else { - /** - * Insert current date - */ - - releaseDate = dayjs().format('LL'); + url += this.options?.path?.novels ? this.options.path.novels : MadaraDefaultPath.novels; } + + url += '/page/' + pageNo + '/' + + '?m_orderby=' + (showLatestNovels ? 'latest' : (filters?.sort || 'rating')); + + const body = await fetchApi(url).then(res => res.text()); + + const loadedCheerio = parseHTML(body); + + loadedCheerio('.manga-title-badges').remove(); + + loadedCheerio('.page-item-detail').each(function () { + const novelName = loadedCheerio(this).find('.post-title').text().trim(); + let image = loadedCheerio(this).find('img'); + const novelCover = image.attr('data-src') || image.attr('src'); + + let novelUrl = loadedCheerio(this).find('.post-title') + .find('a') + .attr('href') || ''; + const novel: Plugin.NovelItem = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + + novels.push(novel); + }); + + return novels; + } + async parseNovelAndChapters(novelUrl: string): Promise { + const novel: Plugin.SourceNovel = { + url: novelUrl, + }; + + const body = await fetchApi(novelUrl).then(res => res.text()); + + let loadedCheerio = parseHTML(body); + + loadedCheerio('.manga-title-badges, #manga-title span').remove(); + novel.name = + loadedCheerio('.post-title h1').text().trim() || + loadedCheerio('#manga-title h1').text(); + + novel.cover = + loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || + loadedCheerio('.summary_image > a > img').attr('data-src') || + loadedCheerio('.summary_image > a > img').attr('src') || + defaultCover; + + loadedCheerio('.post-content_item, .post-content').each(function () { + const detailName = loadedCheerio(this).find('h5').text().trim(); + const detail = loadedCheerio(this).find('.summary-content').text().trim(); + + switch (detailName) { + case 'Genre(s)': + case 'التصنيفات': + novel.genres = detail.replace(/[\\t\\n]/g, ','); + break; + case 'Author(s)': + case 'المؤلف': + case 'المؤلف (ين)': + novel.author = detail; + break; + case 'Status': + case 'الحالة': + novel.status = + detail.includes('OnGoing') || detail.includes('مستمرة') + ? NovelStatus.Ongoing + : NovelStatus.Completed; + break; + } + }); + + loadedCheerio('div.summary__content .code-block,script').remove(); + novel.summary = + loadedCheerio('div.summary__content').text().trim() || + loadedCheerio('#tab-manga-about').text().trim() || + loadedCheerio('.post-content_item h5:contains("Summary")').next().text().trim(); + + let html; + + if (this.options?.useNewChapterEndpoint !== true) { + const novelId = + loadedCheerio('.rating-post-id').attr('value') || + loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; + + const formData = new FormData() + formData.append("action", "manga_get_chapters"); + formData.append("manga", novelId); - let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + html = await fetchApi( + this.site + 'wp-admin/admin-ajax.php', + { + method: 'POST', + body: formData, + }) + .then(res => res.text()); + } else { + html = await fetchApi( + novelUrl + 'ajax/chapters/', + { method: 'POST' }) + .then(res => res.text()); + } + + if (html !== '0') { + loadedCheerio = parseHTML(html); + } + + const chapters: Plugin.ChapterItem[] = []; + loadedCheerio('.wp-manga-chapter').each(function () { + const chapterName = loadedCheerio(this).find('a').text().trim(); + + let releaseDate = null; + releaseDate = loadedCheerio(this) + .find('span.chapter-release-date') + .text() + .trim(); + + if (releaseDate) { + releaseDate = parseMadaraDate(releaseDate); + } else { + /** + * Insert current date + */ + + releaseDate = dayjs().format('LL'); + } + + let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + + chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); + }); + + novel.chapters = chapters.reverse(); + return novel; + } + async parseChapter(chapterUrl: string): Promise { + const body = await fetchApi(chapterUrl).then(res => res.text()); - chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); - }); + const loadedCheerio = parseHTML(body); + const chapterText = + loadedCheerio('.text-left').html() || + loadedCheerio('.text-right').html() || + loadedCheerio('.entry-content').html() || ""; - novel.chapters = chapters.reverse(); - return novel; -}; - -export const parseChapter: Plugin.parseChapter = async (chapterUrl) => { - const url = baseUrl + "/" + "novel" + "/" + chapterUrl; - - const body = await fetchApi(chapterUrl).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - const chapterText = - loadedCheerio('.text-left').html() || - loadedCheerio('.text-right').html() || - loadedCheerio('.entry-content').html(); - - return chapterText; -}; - -export const searchNovels: Plugin.searchNovels = async (searchTerm) => { - const novels: Novel.Item[] = []; - const url = baseUrl + "?s=" + searchTerm + "&post_type=wp-manga"; - - const body = await fetchApi(url).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - - - loadedCheerio('.c-tabs-item__content').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - - let novelUrl = loadedCheerio(this) - .find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - - novels.push(novel); - }); - return novels; -}; - -export const fetchImage: Plugin.fetchImage = async (url) => { - return await fetchFile(url); -}; - -export const filters = []; \ No newline at end of file + return chapterText; + } + async searchNovels(searchTerm: string, pageNo?: number | undefined): Promise { + const novels: Plugin.NovelItem[] = []; + const url = this.site + "?s=" + searchTerm + "&post_type=wp-manga"; + + const body = await fetchApi(url).then(res => res.text()); + + const loadedCheerio = parseHTML(body); + + + loadedCheerio('.c-tabs-item__content').each(function () { + const novelName = loadedCheerio(this).find('.post-title').text().trim(); + + let image = loadedCheerio(this).find('img'); + const novelCover = image.attr('data-src') || image.attr('src'); + + let novelUrl = loadedCheerio(this) + .find('.post-title') + .find('a') + .attr('href') || ''; + const novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + + novels.push(novel); + }); + return novels; + } + async fetchImage(url: string): Promise { + return await fetchFile(url, {}); + } +} +const plugin = new MadaraPlugin({"id":"mtlnovel.club","sourceSite":"https://mtlnovel.club/","sourceName":"MTLNovel.Club","filters":[],"options":{"useNewChapterEndpoint":true,"lang":"English"}}); +export default plugin; + \ No newline at end of file diff --git a/plugins/english/MTLNovel[madara].ts b/plugins/english/MTLNovel[madara].ts index ca80952..a914264 100644 --- a/plugins/english/MTLNovel[madara].ts +++ b/plugins/english/MTLNovel[madara].ts @@ -1,213 +1,252 @@ +import { fetchApi, fetchFile } from "@libs/fetch"; +import { Filter } from "@libs/filterInputs"; +import { Plugin } from '@typings/plugin' import { load as parseHTML } from "cheerio"; -import { fetchFile, fetchApi } from "@libs/fetch"; -import { Novel, Plugin, Chapter } from "@typings/plugin"; -import { FilterInputs } from "@libs/filterInputs"; import { defaultCover } from "@libs/defaultCover"; -import { NovelStatus } from "@libs/novelStatus" +import { NovelStatus } from "@libs/novelStatus"; import { parseMadaraDate } from "@libs/parseMadaraDate"; import dayjs from "dayjs"; -export const id = "mtl-novel"; -export const name = "MTL-Novel [madara]"; -export const icon = "multisrc/madara/icons/mtl-novel.png"; -export const version = "1.0.0"; -export const site = "https://mtl-novel.com/"; -const baseUrl = site; +interface MadaraOptionPath{ + genres?: string, + novels?: string, + novel?: string, + chapter?: string, +} -export const popularNovels: Plugin.popularNovels = async (pageNo, {filters, showLatestNovels}) => { - const novels: Novel.Item[] = []; +const MadaraDefaultPath: MadaraOptionPath = { + novels: 'novel', + novel: 'novel', + chapter: 'novel' +} - let url = site; +interface MadaraOptions { + useNewChapterEndpoint?: boolean, + path?: MadaraOptionPath, + lang?: string, + orderBy?: string +} - if (filters?.genres) { - url += "manga-genre/" + filters.genres + '/'; - } else { - url += "novel/"; +export interface MadaraMetadata { + id: string, + sourceSite: string, + sourceName: string, + options?: MadaraOptions, + filters?: Filter[], +} +class MadaraPlugin implements Plugin.PluginBase { + id: string; + name: string; + icon: string; + site: string; + version: string; + userAgent: string; + cookieString: string; + options?: MadaraOptions; + filter?: Filter[] | undefined; + + constructor(metadata: MadaraMetadata){ + this.id = metadata.id; + this.name = metadata.sourceName + "[madara]"; + const iconFileName = metadata.sourceName.replace(/\s+/g, "").toLowerCase(); + this.icon = `multisrc/madara/icons/${iconFileName}.png`; + this.site = metadata.sourceSite; + this.version = "1.0.0"; + this.userAgent = ""; + this.cookieString = ""; + this.options = metadata.options; + this.filter = metadata.filters; } + async popularNovels(pageNo: number, {filters, showLatestNovels}: Plugin.PopularNovelsOptions): Promise { + const novels: Plugin.NovelItem[] = []; - url += '/page/' + pageNo + '/' + - '?m_orderby=' + (showLatestNovels ? 'latest' : (filters?.sort || 'rating')); - - const body = await fetchApi(url).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - - loadedCheerio('.manga-title-badges').remove(); - - loadedCheerio('.page-item-detail').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - - let novelUrl = loadedCheerio(this).find('.post-title') - .find('a') - .attr('href') || ''; - const novel: Novel.Item = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - - novels.push(novel); - }); - - return novels; -}; - -export const parseNovelAndChapters: Plugin.parseNovelAndChapters = async ( - novelUrl -) => { - const novel: Novel.instance = { - url: novelUrl, - }; - - const body = await fetchApi(novelUrl).then(res => res.text()); - - let loadedCheerio = parseHTML(body); - - loadedCheerio('.manga-title-badges').remove(); - - novel.name = loadedCheerio('.post-title h1').text().trim(); - - novel.cover = - loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || - loadedCheerio('.summary_image > a > img').attr('data-src') || - loadedCheerio('.summary_image > a > img').attr('src') || - defaultCover; - - loadedCheerio('.post-content_item, .post-content').each(function () { - const detailName = loadedCheerio(this).find('h5').text().trim(); - const detail = loadedCheerio(this).find('.summary-content').text().trim(); - - switch (detailName) { - case 'Genre(s)': - case 'التصنيفات': - novel.genres = detail.replace(/[\t\n]/g, ','); - break; - case 'Author(s)': - case 'المؤلف': - case 'المؤلف (ين)': - novel.author = detail; - break; - case 'Status': - case 'الحالة': - novel.status = - detail.includes('OnGoing') || detail.includes('مستمرة') - ? NovelStatus.Ongoing - : NovelStatus.Completed; - break; - } - }); - - loadedCheerio('div.summary__content .code-block,script').remove(); - novel.summary = loadedCheerio('div.summary__content').text().trim(); - - - let html; - - if (true) { - const novelId = - loadedCheerio('.rating-post-id').attr('value') || - loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; - - const body = { - action: "manga_get_chapters", - manga: novelId, - } - html = await fetchApi( - baseUrl + 'wp-admin/admin-ajax.php', - { - method: 'POST', - body: JSON.stringify(body), - }) - .then(res => res.text()); - } else { - html = await fetchApi( - baseUrl + 'ajax/chapters/', - { method: 'POST' }) - .then(res => res.text()); - } - - if (html !== '0') { - loadedCheerio = parseHTML(html); - } - - const chapters: Chapter.Item[] = []; - loadedCheerio('.wp-manga-chapter').each(function () { - const chapterName = loadedCheerio(this).find('a').text().trim(); - - let releaseDate = null; - releaseDate = loadedCheerio(this) - .find('span.chapter-release-date') - .text() - .trim(); - - if (releaseDate) { - releaseDate = parseMadaraDate(releaseDate); + let url = this.site; + if (filters?.genres && this.options?.path?.genres) { + url += this.options?.path?.genres + filters.genres + '/'; } else { - /** - * Insert current date - */ - - releaseDate = dayjs().format('LL'); + url += this.options?.path?.novels ? this.options.path.novels : MadaraDefaultPath.novels; } + + url += '/page/' + pageNo + '/' + + '?m_orderby=' + (showLatestNovels ? 'latest' : (filters?.sort || 'rating')); + + const body = await fetchApi(url).then(res => res.text()); + + const loadedCheerio = parseHTML(body); + + loadedCheerio('.manga-title-badges').remove(); + + loadedCheerio('.page-item-detail').each(function () { + const novelName = loadedCheerio(this).find('.post-title').text().trim(); + let image = loadedCheerio(this).find('img'); + const novelCover = image.attr('data-src') || image.attr('src'); + + let novelUrl = loadedCheerio(this).find('.post-title') + .find('a') + .attr('href') || ''; + const novel: Plugin.NovelItem = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + + novels.push(novel); + }); + + return novels; + } + async parseNovelAndChapters(novelUrl: string): Promise { + const novel: Plugin.SourceNovel = { + url: novelUrl, + }; + + const body = await fetchApi(novelUrl).then(res => res.text()); + + let loadedCheerio = parseHTML(body); + + loadedCheerio('.manga-title-badges, #manga-title span').remove(); + novel.name = + loadedCheerio('.post-title h1').text().trim() || + loadedCheerio('#manga-title h1').text(); + + novel.cover = + loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || + loadedCheerio('.summary_image > a > img').attr('data-src') || + loadedCheerio('.summary_image > a > img').attr('src') || + defaultCover; + + loadedCheerio('.post-content_item, .post-content').each(function () { + const detailName = loadedCheerio(this).find('h5').text().trim(); + const detail = loadedCheerio(this).find('.summary-content').text().trim(); + + switch (detailName) { + case 'Genre(s)': + case 'التصنيفات': + novel.genres = detail.replace(/[\\t\\n]/g, ','); + break; + case 'Author(s)': + case 'المؤلف': + case 'المؤلف (ين)': + novel.author = detail; + break; + case 'Status': + case 'الحالة': + novel.status = + detail.includes('OnGoing') || detail.includes('مستمرة') + ? NovelStatus.Ongoing + : NovelStatus.Completed; + break; + } + }); + + loadedCheerio('div.summary__content .code-block,script').remove(); + novel.summary = + loadedCheerio('div.summary__content').text().trim() || + loadedCheerio('#tab-manga-about').text().trim() || + loadedCheerio('.post-content_item h5:contains("Summary")').next().text().trim(); + + let html; + + if (this.options?.useNewChapterEndpoint !== true) { + const novelId = + loadedCheerio('.rating-post-id').attr('value') || + loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; + + const formData = new FormData() + formData.append("action", "manga_get_chapters"); + formData.append("manga", novelId); - let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + html = await fetchApi( + this.site + 'wp-admin/admin-ajax.php', + { + method: 'POST', + body: formData, + }) + .then(res => res.text()); + } else { + html = await fetchApi( + novelUrl + 'ajax/chapters/', + { method: 'POST' }) + .then(res => res.text()); + } + + if (html !== '0') { + loadedCheerio = parseHTML(html); + } + + const chapters: Plugin.ChapterItem[] = []; + loadedCheerio('.wp-manga-chapter').each(function () { + const chapterName = loadedCheerio(this).find('a').text().trim(); + + let releaseDate = null; + releaseDate = loadedCheerio(this) + .find('span.chapter-release-date') + .text() + .trim(); + + if (releaseDate) { + releaseDate = parseMadaraDate(releaseDate); + } else { + /** + * Insert current date + */ + + releaseDate = dayjs().format('LL'); + } + + let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + + chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); + }); + + novel.chapters = chapters.reverse(); + return novel; + } + async parseChapter(chapterUrl: string): Promise { + const body = await fetchApi(chapterUrl).then(res => res.text()); - chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); - }); + const loadedCheerio = parseHTML(body); + const chapterText = + loadedCheerio('.text-left').html() || + loadedCheerio('.text-right').html() || + loadedCheerio('.entry-content').html() || ""; - novel.chapters = chapters.reverse(); - return novel; -}; - -export const parseChapter: Plugin.parseChapter = async (chapterUrl) => { - const url = baseUrl + "/" + "novel" + "/" + chapterUrl; - - const body = await fetchApi(chapterUrl).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - const chapterText = - loadedCheerio('.text-left').html() || - loadedCheerio('.text-right').html() || - loadedCheerio('.entry-content').html(); - - return chapterText; -}; - -export const searchNovels: Plugin.searchNovels = async (searchTerm) => { - const novels: Novel.Item[] = []; - const url = baseUrl + "?s=" + searchTerm + "&post_type=wp-manga"; - - const body = await fetchApi(url).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - - - loadedCheerio('.c-tabs-item__content').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - - let novelUrl = loadedCheerio(this) - .find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - - novels.push(novel); - }); - return novels; -}; - -export const fetchImage: Plugin.fetchImage = async (url) => { - return await fetchFile(url); -}; - -export const filters = [{"key":"sort","label":"Order by","values":[{"label":"Rating","value":"rating"},{"label":"A-Z","value":"alphabet"},{"label":"Latest","value":"latest"},{"label":"Most Views","value":"views"},{"label":"New","value":"new-manga"},{"label":"Trending","value":"trending"}],"inputType":FilterInputs.Picker},{"key":"genres","label":"GENRES","values":[{"label":"Action","value":"action"},{"label":"Adult","value":"adult"},{"label":"Adventure","value":"adventure"},{"label":"Chinese","value":"chinese"},{"label":"Comedy","value":"comedy"},{"label":"Conan","value":"conan"},{"label":"Drama","value":"drama"},{"label":"Erciyuan","value":"erciyuan"},{"label":"Fairy Tail","value":"fairy-tail"},{"label":"Faloo","value":"faloo"},{"label":"Fan-Fiction","value":"fan-fiction"},{"label":"Fantasy","value":"fantasy"},{"label":"FoodWars!","value":"foodwars"},{"label":"Game","value":"game"},{"label":"Gender Bender","value":"gender-bender"},{"label":"Harem","value":"harem"},{"label":"Historical","value":"historical"},{"label":"Horror","value":"horror"},{"label":"Hunter x Hunter","value":"hunter-x-hunter"},{"label":"Japanese","value":"japanese"},{"label":"Jojo","value":"jojo"},{"label":"Josei","value":"josei"},{"label":"Korean","value":"korean"},{"label":"Martial Arts","value":"martial-arts"},{"label":"Marvel","value":"marvel"},{"label":"Mature","value":"mature"},{"label":"Mecha","value":"mecha"},{"label":"Military","value":"military"},{"label":"Mystery","value":"mystery"},{"label":"Naruto","value":"naruto"},{"label":"One piece","value":"one-piece"},{"label":"Pokemon","value":"pokemon"},{"label":"Psychological","value":"psychological"},{"label":"Romance","value":"romance"},{"label":"School Life","value":"school-life"},{"label":"Sci-fi","value":"sci-fi"},{"label":"Seinen","value":"seinen"},{"label":"Shoujo","value":"shoujo"},{"label":"Shoujo Ai","value":"shoujo-ai"},{"label":"Shounen Ai","value":"shounen-ai"},{"label":"Slice of Life","value":"slice-of-life"},{"label":"Smut","value":"smut"},{"label":"Sport","value":"sport"},{"label":"Sports","value":"sports"},{"label":"Supernatural","value":"supernatural"},{"label":"System","value":"system"},{"label":"Tragedy","value":"tragedy"},{"label":"Urban","value":"urban"},{"label":"Urban Life","value":"urban-life"},{"label":"Wuxia","value":"wuxia"},{"label":"Xianxia","value":"xianxia"},{"label":"Xuanhuan","value":"xuanhuan"},{"label":"Yaoi","value":"yaoi"},{"label":"Yuri","value":"yuri"}],"inputType":FilterInputs.Picker}]; \ No newline at end of file + return chapterText; + } + async searchNovels(searchTerm: string, pageNo?: number | undefined): Promise { + const novels: Plugin.NovelItem[] = []; + const url = this.site + "?s=" + searchTerm + "&post_type=wp-manga"; + + const body = await fetchApi(url).then(res => res.text()); + + const loadedCheerio = parseHTML(body); + + + loadedCheerio('.c-tabs-item__content').each(function () { + const novelName = loadedCheerio(this).find('.post-title').text().trim(); + + let image = loadedCheerio(this).find('img'); + const novelCover = image.attr('data-src') || image.attr('src'); + + let novelUrl = loadedCheerio(this) + .find('.post-title') + .find('a') + .attr('href') || ''; + const novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + + novels.push(novel); + }); + return novels; + } + async fetchImage(url: string): Promise { + return await fetchFile(url, {}); + } +} +const plugin = new MadaraPlugin({"id":"mtl-novel","sourceSite":"https://mtl-novel.com/","sourceName":"MTL-Novel","filters":[{"key":"sort","label":"Order by","values":[{"label":"Rating","value":"rating"},{"label":"A-Z","value":"alphabet"},{"label":"Latest","value":"latest"},{"label":"Most Views","value":"views"},{"label":"New","value":"new-manga"},{"label":"Trending","value":"trending"}],"inputType":"Picker"},{"key":"genres","label":"GENRES","values":[{"label":"Action","value":"action"},{"label":"Adult","value":"adult"},{"label":"Adventure","value":"adventure"},{"label":"Chinese","value":"chinese"},{"label":"Comedy","value":"comedy"},{"label":"Conan","value":"conan"},{"label":"Drama","value":"drama"},{"label":"Erciyuan","value":"erciyuan"},{"label":"Fairy Tail","value":"fairy-tail"},{"label":"Faloo","value":"faloo"},{"label":"Fan-Fiction","value":"fan-fiction"},{"label":"Fantasy","value":"fantasy"},{"label":"FoodWars!","value":"foodwars"},{"label":"Game","value":"game"},{"label":"Gender Bender","value":"gender-bender"},{"label":"Harem","value":"harem"},{"label":"Historical","value":"historical"},{"label":"Horror","value":"horror"},{"label":"Hunter x Hunter","value":"hunter-x-hunter"},{"label":"Japanese","value":"japanese"},{"label":"Jojo","value":"jojo"},{"label":"Josei","value":"josei"},{"label":"Korean","value":"korean"},{"label":"Martial Arts","value":"martial-arts"},{"label":"Marvel","value":"marvel"},{"label":"Mature","value":"mature"},{"label":"Mecha","value":"mecha"},{"label":"Military","value":"military"},{"label":"Mystery","value":"mystery"},{"label":"Naruto","value":"naruto"},{"label":"One piece","value":"one-piece"},{"label":"Pokemon","value":"pokemon"},{"label":"Psychological","value":"psychological"},{"label":"Romance","value":"romance"},{"label":"School Life","value":"school-life"},{"label":"Sci-fi","value":"sci-fi"},{"label":"Seinen","value":"seinen"},{"label":"Shoujo","value":"shoujo"},{"label":"Shoujo Ai","value":"shoujo-ai"},{"label":"Shounen Ai","value":"shounen-ai"},{"label":"Slice of Life","value":"slice-of-life"},{"label":"Smut","value":"smut"},{"label":"Sport","value":"sport"},{"label":"Sports","value":"sports"},{"label":"Supernatural","value":"supernatural"},{"label":"System","value":"system"},{"label":"Tragedy","value":"tragedy"},{"label":"Urban","value":"urban"},{"label":"Urban Life","value":"urban-life"},{"label":"Wuxia","value":"wuxia"},{"label":"Xianxia","value":"xianxia"},{"label":"Xuanhuan","value":"xuanhuan"},{"label":"Yaoi","value":"yaoi"},{"label":"Yuri","value":"yuri"}],"inputType":"Picker"}],"options":{"path":{"genres":"manga-genre"},"useNewChapterEndpoint":true,"lang":"English"}}); +export default plugin; + \ No newline at end of file diff --git a/plugins/english/MostNovel[madara].ts b/plugins/english/MostNovel[madara].ts index e556082..7e2559d 100644 --- a/plugins/english/MostNovel[madara].ts +++ b/plugins/english/MostNovel[madara].ts @@ -1,213 +1,252 @@ +import { fetchApi, fetchFile } from "@libs/fetch"; +import { Filter } from "@libs/filterInputs"; +import { Plugin } from '@typings/plugin' import { load as parseHTML } from "cheerio"; -import { fetchFile, fetchApi } from "@libs/fetch"; -import { Novel, Plugin, Chapter } from "@typings/plugin"; -import { FilterInputs } from "@libs/filterInputs"; import { defaultCover } from "@libs/defaultCover"; -import { NovelStatus } from "@libs/novelStatus" +import { NovelStatus } from "@libs/novelStatus"; import { parseMadaraDate } from "@libs/parseMadaraDate"; import dayjs from "dayjs"; -export const id = "mostnovel"; -export const name = "MostNovel [madara]"; -export const icon = "multisrc/madara/icons/mostnovel.png"; -export const version = "1.0.0"; -export const site = "https://mostnovel.com/"; -const baseUrl = site; +interface MadaraOptionPath{ + genres?: string, + novels?: string, + novel?: string, + chapter?: string, +} -export const popularNovels: Plugin.popularNovels = async (pageNo, {filters, showLatestNovels}) => { - const novels: Novel.Item[] = []; +const MadaraDefaultPath: MadaraOptionPath = { + novels: 'novel', + novel: 'novel', + chapter: 'novel' +} - let url = site; +interface MadaraOptions { + useNewChapterEndpoint?: boolean, + path?: MadaraOptionPath, + lang?: string, + orderBy?: string +} - if (filters?.genres) { - url += "manga-genre/" + filters.genres + '/'; - } else { - url += "manga/"; +export interface MadaraMetadata { + id: string, + sourceSite: string, + sourceName: string, + options?: MadaraOptions, + filters?: Filter[], +} +class MadaraPlugin implements Plugin.PluginBase { + id: string; + name: string; + icon: string; + site: string; + version: string; + userAgent: string; + cookieString: string; + options?: MadaraOptions; + filter?: Filter[] | undefined; + + constructor(metadata: MadaraMetadata){ + this.id = metadata.id; + this.name = metadata.sourceName + "[madara]"; + const iconFileName = metadata.sourceName.replace(/\s+/g, "").toLowerCase(); + this.icon = `multisrc/madara/icons/${iconFileName}.png`; + this.site = metadata.sourceSite; + this.version = "1.0.0"; + this.userAgent = ""; + this.cookieString = ""; + this.options = metadata.options; + this.filter = metadata.filters; } + async popularNovels(pageNo: number, {filters, showLatestNovels}: Plugin.PopularNovelsOptions): Promise { + const novels: Plugin.NovelItem[] = []; - url += '/page/' + pageNo + '/' + - '?m_orderby=' + (showLatestNovels ? 'latest' : (filters?.sort || 'rating')); - - const body = await fetchApi(url).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - - loadedCheerio('.manga-title-badges').remove(); - - loadedCheerio('.page-item-detail').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - - let novelUrl = loadedCheerio(this).find('.post-title') - .find('a') - .attr('href') || ''; - const novel: Novel.Item = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - - novels.push(novel); - }); - - return novels; -}; - -export const parseNovelAndChapters: Plugin.parseNovelAndChapters = async ( - novelUrl -) => { - const novel: Novel.instance = { - url: novelUrl, - }; - - const body = await fetchApi(novelUrl).then(res => res.text()); - - let loadedCheerio = parseHTML(body); - - loadedCheerio('.manga-title-badges').remove(); - - novel.name = loadedCheerio('.post-title h1').text().trim(); - - novel.cover = - loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || - loadedCheerio('.summary_image > a > img').attr('data-src') || - loadedCheerio('.summary_image > a > img').attr('src') || - defaultCover; - - loadedCheerio('.post-content_item, .post-content').each(function () { - const detailName = loadedCheerio(this).find('h5').text().trim(); - const detail = loadedCheerio(this).find('.summary-content').text().trim(); - - switch (detailName) { - case 'Genre(s)': - case 'التصنيفات': - novel.genres = detail.replace(/[\t\n]/g, ','); - break; - case 'Author(s)': - case 'المؤلف': - case 'المؤلف (ين)': - novel.author = detail; - break; - case 'Status': - case 'الحالة': - novel.status = - detail.includes('OnGoing') || detail.includes('مستمرة') - ? NovelStatus.Ongoing - : NovelStatus.Completed; - break; - } - }); - - loadedCheerio('div.summary__content .code-block,script').remove(); - novel.summary = loadedCheerio('div.summary__content').text().trim(); - - - let html; - - if (false) { - const novelId = - loadedCheerio('.rating-post-id').attr('value') || - loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; - - const body = { - action: "manga_get_chapters", - manga: novelId, - } - html = await fetchApi( - baseUrl + 'wp-admin/admin-ajax.php', - { - method: 'POST', - body: JSON.stringify(body), - }) - .then(res => res.text()); - } else { - html = await fetchApi( - baseUrl + 'ajax/chapters/', - { method: 'POST' }) - .then(res => res.text()); - } - - if (html !== '0') { - loadedCheerio = parseHTML(html); - } - - const chapters: Chapter.Item[] = []; - loadedCheerio('.wp-manga-chapter').each(function () { - const chapterName = loadedCheerio(this).find('a').text().trim(); - - let releaseDate = null; - releaseDate = loadedCheerio(this) - .find('span.chapter-release-date') - .text() - .trim(); - - if (releaseDate) { - releaseDate = parseMadaraDate(releaseDate); + let url = this.site; + if (filters?.genres && this.options?.path?.genres) { + url += this.options?.path?.genres + filters.genres + '/'; } else { - /** - * Insert current date - */ - - releaseDate = dayjs().format('LL'); + url += this.options?.path?.novels ? this.options.path.novels : MadaraDefaultPath.novels; } + + url += '/page/' + pageNo + '/' + + '?m_orderby=' + (showLatestNovels ? 'latest' : (filters?.sort || 'rating')); + + const body = await fetchApi(url).then(res => res.text()); + + const loadedCheerio = parseHTML(body); + + loadedCheerio('.manga-title-badges').remove(); + + loadedCheerio('.page-item-detail').each(function () { + const novelName = loadedCheerio(this).find('.post-title').text().trim(); + let image = loadedCheerio(this).find('img'); + const novelCover = image.attr('data-src') || image.attr('src'); + + let novelUrl = loadedCheerio(this).find('.post-title') + .find('a') + .attr('href') || ''; + const novel: Plugin.NovelItem = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + + novels.push(novel); + }); + + return novels; + } + async parseNovelAndChapters(novelUrl: string): Promise { + const novel: Plugin.SourceNovel = { + url: novelUrl, + }; + + const body = await fetchApi(novelUrl).then(res => res.text()); + + let loadedCheerio = parseHTML(body); + + loadedCheerio('.manga-title-badges, #manga-title span').remove(); + novel.name = + loadedCheerio('.post-title h1').text().trim() || + loadedCheerio('#manga-title h1').text(); + + novel.cover = + loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || + loadedCheerio('.summary_image > a > img').attr('data-src') || + loadedCheerio('.summary_image > a > img').attr('src') || + defaultCover; + + loadedCheerio('.post-content_item, .post-content').each(function () { + const detailName = loadedCheerio(this).find('h5').text().trim(); + const detail = loadedCheerio(this).find('.summary-content').text().trim(); + + switch (detailName) { + case 'Genre(s)': + case 'التصنيفات': + novel.genres = detail.replace(/[\\t\\n]/g, ','); + break; + case 'Author(s)': + case 'المؤلف': + case 'المؤلف (ين)': + novel.author = detail; + break; + case 'Status': + case 'الحالة': + novel.status = + detail.includes('OnGoing') || detail.includes('مستمرة') + ? NovelStatus.Ongoing + : NovelStatus.Completed; + break; + } + }); + + loadedCheerio('div.summary__content .code-block,script').remove(); + novel.summary = + loadedCheerio('div.summary__content').text().trim() || + loadedCheerio('#tab-manga-about').text().trim() || + loadedCheerio('.post-content_item h5:contains("Summary")').next().text().trim(); + + let html; + + if (this.options?.useNewChapterEndpoint !== true) { + const novelId = + loadedCheerio('.rating-post-id').attr('value') || + loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; + + const formData = new FormData() + formData.append("action", "manga_get_chapters"); + formData.append("manga", novelId); - let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + html = await fetchApi( + this.site + 'wp-admin/admin-ajax.php', + { + method: 'POST', + body: formData, + }) + .then(res => res.text()); + } else { + html = await fetchApi( + novelUrl + 'ajax/chapters/', + { method: 'POST' }) + .then(res => res.text()); + } + + if (html !== '0') { + loadedCheerio = parseHTML(html); + } + + const chapters: Plugin.ChapterItem[] = []; + loadedCheerio('.wp-manga-chapter').each(function () { + const chapterName = loadedCheerio(this).find('a').text().trim(); + + let releaseDate = null; + releaseDate = loadedCheerio(this) + .find('span.chapter-release-date') + .text() + .trim(); + + if (releaseDate) { + releaseDate = parseMadaraDate(releaseDate); + } else { + /** + * Insert current date + */ + + releaseDate = dayjs().format('LL'); + } + + let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + + chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); + }); + + novel.chapters = chapters.reverse(); + return novel; + } + async parseChapter(chapterUrl: string): Promise { + const body = await fetchApi(chapterUrl).then(res => res.text()); - chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); - }); + const loadedCheerio = parseHTML(body); + const chapterText = + loadedCheerio('.text-left').html() || + loadedCheerio('.text-right').html() || + loadedCheerio('.entry-content').html() || ""; - novel.chapters = chapters.reverse(); - return novel; -}; - -export const parseChapter: Plugin.parseChapter = async (chapterUrl) => { - const url = baseUrl + "/" + "manga" + "/" + chapterUrl; - - const body = await fetchApi(chapterUrl).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - const chapterText = - loadedCheerio('.text-left').html() || - loadedCheerio('.text-right').html() || - loadedCheerio('.entry-content').html(); - - return chapterText; -}; - -export const searchNovels: Plugin.searchNovels = async (searchTerm) => { - const novels: Novel.Item[] = []; - const url = baseUrl + "?s=" + searchTerm + "&post_type=wp-manga"; - - const body = await fetchApi(url).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - - - loadedCheerio('.c-tabs-item__content').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - - let novelUrl = loadedCheerio(this) - .find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - - novels.push(novel); - }); - return novels; -}; - -export const fetchImage: Plugin.fetchImage = async (url) => { - return await fetchFile(url); -}; - -export const filters = [{"key":"sort","label":"Order by","values":[{"label":"Rating","value":"rating"},{"label":"A-Z","value":"alphabet"},{"label":"Latest","value":"latest"},{"label":"Most Views","value":"views"},{"label":"New","value":"new-manga"},{"label":"Trending","value":"trending"}],"inputType":FilterInputs.Picker},{"key":"genres","label":"GENRES","values":[{"label":"ACG","value":"acg"},{"label":"Action","value":"action"},{"label":"Adult","value":"adult"},{"label":"Adventure","value":"adventure"},{"label":"AGA","value":"aga"},{"label":"Anime","value":"anime"},{"label":"Anime & Comics","value":"anime-comics"},{"label":"Bender","value":"bender"},{"label":"BL","value":"bl"},{"label":"Cartoon","value":"cartoon"},{"label":"Comedy","value":"comedy"},{"label":"Comic","value":"comic"},{"label":"Contemporary Romance","value":"contemporary-romance"},{"label":"Cooking","value":"cooking"},{"label":"Cultivation","value":"cultivation"},{"label":"Detective","value":"detective"},{"label":"Doujinshi","value":"doujinshi"},{"label":"Drama","value":"drama"},{"label":"Eastern Fantasy","value":"eastern-fantasy"},{"label":"Ecchi","value":"ecchi"},{"label":"Fantasy","value":"fantasy"},{"label":"Gender Bender","value":"gender-bender"},{"label":"Harem","value":"harem"},{"label":"Historical","value":"historical"},{"label":"Horror","value":"horror"},{"label":"Horror&Thriller","value":"horrorthriller"},{"label":"Josei","value":"josei"},{"label":"Live action","value":"live-action"},{"label":"Magical Realism","value":"magical-realism"},{"label":"Manga","value":"manga"},{"label":"Manhua","value":"manhua"},{"label":"Manhwa","value":"manhwa"},{"label":"Martial Arts","value":"martial-arts"},{"label":"Mature","value":"mature"},{"label":"Mecha","value":"mecha"},{"label":"Modern","value":"modern"},{"label":"Movies","value":"movies"},{"label":"Mystery","value":"mystery"},{"label":"One shot","value":"one-shot"},{"label":"Psychological","value":"psychological"},{"label":"Romance","value":"romance"},{"label":"School Life","value":"school-life"},{"label":"Sci-fi","value":"sci-fi"},{"label":"Seinen","value":"seinen"},{"label":"Shoujo","value":"shoujo"},{"label":"Shoujo Ai","value":"shoujo-ai"},{"label":"Shounen","value":"shounen"},{"label":"Shounen Ai","value":"shounen-ai"},{"label":"Slice of Life","value":"slice-of-life"},{"label":"Smart MC","value":"smart-mc"},{"label":"Smut","value":"smut"},{"label":"Soft Yaoi","value":"soft-yaoi"},{"label":"Soft Yuri","value":"soft-yuri"},{"label":"Sports","value":"sports"},{"label":"Supernatural","value":"supernatural"},{"label":"Tragedy","value":"tragedy"},{"label":"Urban Life","value":"urban-life"},{"label":"Video Games","value":"video-games"},{"label":"Webtoon","value":"webtoon"},{"label":"Wuxia","value":"wuxia"},{"label":"Xianxia","value":"xianxia"},{"label":"Xuanhuan","value":"xuanhuan"},{"label":"Yaoi","value":"yaoi"},{"label":"Yuri","value":"yuri"}],"inputType":FilterInputs.Picker}]; \ No newline at end of file + return chapterText; + } + async searchNovels(searchTerm: string, pageNo?: number | undefined): Promise { + const novels: Plugin.NovelItem[] = []; + const url = this.site + "?s=" + searchTerm + "&post_type=wp-manga"; + + const body = await fetchApi(url).then(res => res.text()); + + const loadedCheerio = parseHTML(body); + + + loadedCheerio('.c-tabs-item__content').each(function () { + const novelName = loadedCheerio(this).find('.post-title').text().trim(); + + let image = loadedCheerio(this).find('img'); + const novelCover = image.attr('data-src') || image.attr('src'); + + let novelUrl = loadedCheerio(this) + .find('.post-title') + .find('a') + .attr('href') || ''; + const novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + + novels.push(novel); + }); + return novels; + } + async fetchImage(url: string): Promise { + return await fetchFile(url, {}); + } +} +const plugin = new MadaraPlugin({"id":"mostnovel","sourceSite":"https://mostnovel.com/","sourceName":"MostNovel","filters":[{"key":"sort","label":"Order by","values":[{"label":"Rating","value":"rating"},{"label":"A-Z","value":"alphabet"},{"label":"Latest","value":"latest"},{"label":"Most Views","value":"views"},{"label":"New","value":"new-manga"},{"label":"Trending","value":"trending"}],"inputType":"Picker"},{"key":"genres","label":"GENRES","values":[{"label":"ACG","value":"acg"},{"label":"Action","value":"action"},{"label":"Adult","value":"adult"},{"label":"Adventure","value":"adventure"},{"label":"AGA","value":"aga"},{"label":"Anime","value":"anime"},{"label":"Anime & Comics","value":"anime-comics"},{"label":"Bender","value":"bender"},{"label":"BL","value":"bl"},{"label":"Cartoon","value":"cartoon"},{"label":"Comedy","value":"comedy"},{"label":"Comic","value":"comic"},{"label":"Contemporary Romance","value":"contemporary-romance"},{"label":"Cooking","value":"cooking"},{"label":"Cultivation","value":"cultivation"},{"label":"Detective","value":"detective"},{"label":"Doujinshi","value":"doujinshi"},{"label":"Drama","value":"drama"},{"label":"Eastern Fantasy","value":"eastern-fantasy"},{"label":"Ecchi","value":"ecchi"},{"label":"Fantasy","value":"fantasy"},{"label":"Gender Bender","value":"gender-bender"},{"label":"Harem","value":"harem"},{"label":"Historical","value":"historical"},{"label":"Horror","value":"horror"},{"label":"Horror&Thriller","value":"horrorthriller"},{"label":"Josei","value":"josei"},{"label":"Live action","value":"live-action"},{"label":"Magical Realism","value":"magical-realism"},{"label":"Manga","value":"manga"},{"label":"Manhua","value":"manhua"},{"label":"Manhwa","value":"manhwa"},{"label":"Martial Arts","value":"martial-arts"},{"label":"Mature","value":"mature"},{"label":"Mecha","value":"mecha"},{"label":"Modern","value":"modern"},{"label":"Movies","value":"movies"},{"label":"Mystery","value":"mystery"},{"label":"One shot","value":"one-shot"},{"label":"Psychological","value":"psychological"},{"label":"Romance","value":"romance"},{"label":"School Life","value":"school-life"},{"label":"Sci-fi","value":"sci-fi"},{"label":"Seinen","value":"seinen"},{"label":"Shoujo","value":"shoujo"},{"label":"Shoujo Ai","value":"shoujo-ai"},{"label":"Shounen","value":"shounen"},{"label":"Shounen Ai","value":"shounen-ai"},{"label":"Slice of Life","value":"slice-of-life"},{"label":"Smart MC","value":"smart-mc"},{"label":"Smut","value":"smut"},{"label":"Soft Yaoi","value":"soft-yaoi"},{"label":"Soft Yuri","value":"soft-yuri"},{"label":"Sports","value":"sports"},{"label":"Supernatural","value":"supernatural"},{"label":"Tragedy","value":"tragedy"},{"label":"Urban Life","value":"urban-life"},{"label":"Video Games","value":"video-games"},{"label":"Webtoon","value":"webtoon"},{"label":"Wuxia","value":"wuxia"},{"label":"Xianxia","value":"xianxia"},{"label":"Xuanhuan","value":"xuanhuan"},{"label":"Yaoi","value":"yaoi"},{"label":"Yuri","value":"yuri"}],"inputType":"Picker"}],"options":{"path":{"novels":"manga","novel":"manga","chapter":"manga","genres":"manga-genre"},"lang":"English"}}); +export default plugin; + \ No newline at end of file diff --git a/plugins/english/MysticalSeries[madara].ts b/plugins/english/MysticalSeries[madara].ts index 2f25d22..0cda7aa 100644 --- a/plugins/english/MysticalSeries[madara].ts +++ b/plugins/english/MysticalSeries[madara].ts @@ -1,213 +1,252 @@ +import { fetchApi, fetchFile } from "@libs/fetch"; +import { Filter } from "@libs/filterInputs"; +import { Plugin } from '@typings/plugin' import { load as parseHTML } from "cheerio"; -import { fetchFile, fetchApi } from "@libs/fetch"; -import { Novel, Plugin, Chapter } from "@typings/plugin"; -import { FilterInputs } from "@libs/filterInputs"; import { defaultCover } from "@libs/defaultCover"; -import { NovelStatus } from "@libs/novelStatus" +import { NovelStatus } from "@libs/novelStatus"; import { parseMadaraDate } from "@libs/parseMadaraDate"; import dayjs from "dayjs"; -export const id = "mysticalmerries"; -export const name = "MysticalSeries [madara]"; -export const icon = "multisrc/madara/icons/mysticalseries.png"; -export const version = "1.0.0"; -export const site = "https://mysticalmerries.com/"; -const baseUrl = site; +interface MadaraOptionPath{ + genres?: string, + novels?: string, + novel?: string, + chapter?: string, +} -export const popularNovels: Plugin.popularNovels = async (pageNo, {filters, showLatestNovels}) => { - const novels: Novel.Item[] = []; +const MadaraDefaultPath: MadaraOptionPath = { + novels: 'novel', + novel: 'novel', + chapter: 'novel' +} - let url = site; +interface MadaraOptions { + useNewChapterEndpoint?: boolean, + path?: MadaraOptionPath, + lang?: string, + orderBy?: string +} - if (filters?.genres) { - url += "genre/" + filters.genres + '/'; - } else { - url += "series/"; +export interface MadaraMetadata { + id: string, + sourceSite: string, + sourceName: string, + options?: MadaraOptions, + filters?: Filter[], +} +class MadaraPlugin implements Plugin.PluginBase { + id: string; + name: string; + icon: string; + site: string; + version: string; + userAgent: string; + cookieString: string; + options?: MadaraOptions; + filter?: Filter[] | undefined; + + constructor(metadata: MadaraMetadata){ + this.id = metadata.id; + this.name = metadata.sourceName + "[madara]"; + const iconFileName = metadata.sourceName.replace(/\s+/g, "").toLowerCase(); + this.icon = `multisrc/madara/icons/${iconFileName}.png`; + this.site = metadata.sourceSite; + this.version = "1.0.0"; + this.userAgent = ""; + this.cookieString = ""; + this.options = metadata.options; + this.filter = metadata.filters; } + async popularNovels(pageNo: number, {filters, showLatestNovels}: Plugin.PopularNovelsOptions): Promise { + const novels: Plugin.NovelItem[] = []; - url += '/page/' + pageNo + '/' + - '?m_orderby=' + (showLatestNovels ? 'latest' : (filters?.sort || 'rating')); - - const body = await fetchApi(url).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - - loadedCheerio('.manga-title-badges').remove(); - - loadedCheerio('.page-item-detail').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - - let novelUrl = loadedCheerio(this).find('.post-title') - .find('a') - .attr('href') || ''; - const novel: Novel.Item = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - - novels.push(novel); - }); - - return novels; -}; - -export const parseNovelAndChapters: Plugin.parseNovelAndChapters = async ( - novelUrl -) => { - const novel: Novel.instance = { - url: novelUrl, - }; - - const body = await fetchApi(novelUrl).then(res => res.text()); - - let loadedCheerio = parseHTML(body); - - loadedCheerio('.manga-title-badges').remove(); - - novel.name = loadedCheerio('.post-title h1').text().trim(); - - novel.cover = - loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || - loadedCheerio('.summary_image > a > img').attr('data-src') || - loadedCheerio('.summary_image > a > img').attr('src') || - defaultCover; - - loadedCheerio('.post-content_item, .post-content').each(function () { - const detailName = loadedCheerio(this).find('h5').text().trim(); - const detail = loadedCheerio(this).find('.summary-content').text().trim(); - - switch (detailName) { - case 'Genre(s)': - case 'التصنيفات': - novel.genres = detail.replace(/[\t\n]/g, ','); - break; - case 'Author(s)': - case 'المؤلف': - case 'المؤلف (ين)': - novel.author = detail; - break; - case 'Status': - case 'الحالة': - novel.status = - detail.includes('OnGoing') || detail.includes('مستمرة') - ? NovelStatus.Ongoing - : NovelStatus.Completed; - break; - } - }); - - loadedCheerio('div.summary__content .code-block,script').remove(); - novel.summary = loadedCheerio('div.summary__content').text().trim(); - - - let html; - - if (true) { - const novelId = - loadedCheerio('.rating-post-id').attr('value') || - loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; - - const body = { - action: "manga_get_chapters", - manga: novelId, - } - html = await fetchApi( - baseUrl + 'wp-admin/admin-ajax.php', - { - method: 'POST', - body: JSON.stringify(body), - }) - .then(res => res.text()); - } else { - html = await fetchApi( - baseUrl + 'ajax/chapters/', - { method: 'POST' }) - .then(res => res.text()); - } - - if (html !== '0') { - loadedCheerio = parseHTML(html); - } - - const chapters: Chapter.Item[] = []; - loadedCheerio('.wp-manga-chapter').each(function () { - const chapterName = loadedCheerio(this).find('a').text().trim(); - - let releaseDate = null; - releaseDate = loadedCheerio(this) - .find('span.chapter-release-date') - .text() - .trim(); - - if (releaseDate) { - releaseDate = parseMadaraDate(releaseDate); + let url = this.site; + if (filters?.genres && this.options?.path?.genres) { + url += this.options?.path?.genres + filters.genres + '/'; } else { - /** - * Insert current date - */ - - releaseDate = dayjs().format('LL'); + url += this.options?.path?.novels ? this.options.path.novels : MadaraDefaultPath.novels; } + + url += '/page/' + pageNo + '/' + + '?m_orderby=' + (showLatestNovels ? 'latest' : (filters?.sort || 'rating')); + + const body = await fetchApi(url).then(res => res.text()); + + const loadedCheerio = parseHTML(body); + + loadedCheerio('.manga-title-badges').remove(); + + loadedCheerio('.page-item-detail').each(function () { + const novelName = loadedCheerio(this).find('.post-title').text().trim(); + let image = loadedCheerio(this).find('img'); + const novelCover = image.attr('data-src') || image.attr('src'); + + let novelUrl = loadedCheerio(this).find('.post-title') + .find('a') + .attr('href') || ''; + const novel: Plugin.NovelItem = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + + novels.push(novel); + }); + + return novels; + } + async parseNovelAndChapters(novelUrl: string): Promise { + const novel: Plugin.SourceNovel = { + url: novelUrl, + }; + + const body = await fetchApi(novelUrl).then(res => res.text()); + + let loadedCheerio = parseHTML(body); + + loadedCheerio('.manga-title-badges, #manga-title span').remove(); + novel.name = + loadedCheerio('.post-title h1').text().trim() || + loadedCheerio('#manga-title h1').text(); + + novel.cover = + loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || + loadedCheerio('.summary_image > a > img').attr('data-src') || + loadedCheerio('.summary_image > a > img').attr('src') || + defaultCover; + + loadedCheerio('.post-content_item, .post-content').each(function () { + const detailName = loadedCheerio(this).find('h5').text().trim(); + const detail = loadedCheerio(this).find('.summary-content').text().trim(); + + switch (detailName) { + case 'Genre(s)': + case 'التصنيفات': + novel.genres = detail.replace(/[\\t\\n]/g, ','); + break; + case 'Author(s)': + case 'المؤلف': + case 'المؤلف (ين)': + novel.author = detail; + break; + case 'Status': + case 'الحالة': + novel.status = + detail.includes('OnGoing') || detail.includes('مستمرة') + ? NovelStatus.Ongoing + : NovelStatus.Completed; + break; + } + }); + + loadedCheerio('div.summary__content .code-block,script').remove(); + novel.summary = + loadedCheerio('div.summary__content').text().trim() || + loadedCheerio('#tab-manga-about').text().trim() || + loadedCheerio('.post-content_item h5:contains("Summary")').next().text().trim(); + + let html; + + if (this.options?.useNewChapterEndpoint !== true) { + const novelId = + loadedCheerio('.rating-post-id').attr('value') || + loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; + + const formData = new FormData() + formData.append("action", "manga_get_chapters"); + formData.append("manga", novelId); - let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + html = await fetchApi( + this.site + 'wp-admin/admin-ajax.php', + { + method: 'POST', + body: formData, + }) + .then(res => res.text()); + } else { + html = await fetchApi( + novelUrl + 'ajax/chapters/', + { method: 'POST' }) + .then(res => res.text()); + } + + if (html !== '0') { + loadedCheerio = parseHTML(html); + } + + const chapters: Plugin.ChapterItem[] = []; + loadedCheerio('.wp-manga-chapter').each(function () { + const chapterName = loadedCheerio(this).find('a').text().trim(); + + let releaseDate = null; + releaseDate = loadedCheerio(this) + .find('span.chapter-release-date') + .text() + .trim(); + + if (releaseDate) { + releaseDate = parseMadaraDate(releaseDate); + } else { + /** + * Insert current date + */ + + releaseDate = dayjs().format('LL'); + } + + let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + + chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); + }); + + novel.chapters = chapters.reverse(); + return novel; + } + async parseChapter(chapterUrl: string): Promise { + const body = await fetchApi(chapterUrl).then(res => res.text()); - chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); - }); + const loadedCheerio = parseHTML(body); + const chapterText = + loadedCheerio('.text-left').html() || + loadedCheerio('.text-right').html() || + loadedCheerio('.entry-content').html() || ""; - novel.chapters = chapters.reverse(); - return novel; -}; - -export const parseChapter: Plugin.parseChapter = async (chapterUrl) => { - const url = baseUrl + "/" + "series" + "/" + chapterUrl; - - const body = await fetchApi(chapterUrl).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - const chapterText = - loadedCheerio('.text-left').html() || - loadedCheerio('.text-right').html() || - loadedCheerio('.entry-content').html(); - - return chapterText; -}; - -export const searchNovels: Plugin.searchNovels = async (searchTerm) => { - const novels: Novel.Item[] = []; - const url = baseUrl + "?s=" + searchTerm + "&post_type=wp-manga"; - - const body = await fetchApi(url).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - - - loadedCheerio('.c-tabs-item__content').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - - let novelUrl = loadedCheerio(this) - .find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - - novels.push(novel); - }); - return novels; -}; - -export const fetchImage: Plugin.fetchImage = async (url) => { - return await fetchFile(url); -}; - -export const filters = [{"key":"sort","label":"Order by","values":[{"label":"Rating","value":"rating"},{"label":"A-Z","value":"alphabet"},{"label":"Latest","value":"latest"},{"label":"Most Views","value":"views"},{"label":"New","value":"new-manga"},{"label":"Trending","value":"trending"}],"inputType":FilterInputs.Picker},{"key":"genres","label":"GENRES","values":[{"label":"Action","value":"action"},{"label":"Adaptation","value":"adaptation"},{"label":"Adventure","value":"adventure"},{"label":"bilibili","value":"bilibili"},{"label":"Chinese Novel","value":"chinese-novel"},{"label":"Comedy","value":"comedy"},{"label":"Crossdressing","value":"crossdressing"},{"label":"Drama","value":"drama"},{"label":"Dropped","value":"dropped"},{"label":"Family","value":"family"},{"label":"Fantasy","value":"fantasy"},{"label":"Gender Bender","value":"gender-bender"},{"label":"Historical","value":"historical"},{"label":"Horror","value":"horror"},{"label":"Isekai","value":"isekai"},{"label":"Korean Novel","value":"korean-novell"},{"label":"Manga","value":"manga"},{"label":"Manhua","value":"manhua"},{"label":"Manhwa","value":"manhwa"},{"label":"Modern Romance","value":"modern-romance"},{"label":"Mystery","value":"mystery"},{"label":"Office Workers","value":"office-workers"},{"label":"One shot","value":"one-shot"},{"label":"Pilot Novel","value":"pilot-novel"},{"label":"R15","value":"r15"},{"label":"R19","value":"r19"},{"label":"Regression","value":"regression"},{"label":"Reincarnation","value":"reincarnation"},{"label":"Reverse Harem","value":"reverse-harem"},{"label":"Romance Fantasy","value":"romance-fantasy"},{"label":"School Life","value":"school-life"},{"label":"Sci-fi","value":"sci-fi"},{"label":"Slice of Life","value":"slice-of-life"},{"label":"Smut","value":"smut"},{"label":"Supernatural","value":"supernatural"},{"label":"Violence","value":"violence"}],"inputType":FilterInputs.Picker}]; \ No newline at end of file + return chapterText; + } + async searchNovels(searchTerm: string, pageNo?: number | undefined): Promise { + const novels: Plugin.NovelItem[] = []; + const url = this.site + "?s=" + searchTerm + "&post_type=wp-manga"; + + const body = await fetchApi(url).then(res => res.text()); + + const loadedCheerio = parseHTML(body); + + + loadedCheerio('.c-tabs-item__content').each(function () { + const novelName = loadedCheerio(this).find('.post-title').text().trim(); + + let image = loadedCheerio(this).find('img'); + const novelCover = image.attr('data-src') || image.attr('src'); + + let novelUrl = loadedCheerio(this) + .find('.post-title') + .find('a') + .attr('href') || ''; + const novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + + novels.push(novel); + }); + return novels; + } + async fetchImage(url: string): Promise { + return await fetchFile(url, {}); + } +} +const plugin = new MadaraPlugin({"id":"mysticalmerries","sourceSite":"https://mysticalmerries.com/","sourceName":"MysticalSeries","filters":[{"key":"sort","label":"Order by","values":[{"label":"Rating","value":"rating"},{"label":"A-Z","value":"alphabet"},{"label":"Latest","value":"latest"},{"label":"Most Views","value":"views"},{"label":"New","value":"new-manga"},{"label":"Trending","value":"trending"}],"inputType":"Picker"},{"key":"genres","label":"GENRES","values":[{"label":"Action","value":"action"},{"label":"Adaptation","value":"adaptation"},{"label":"Adventure","value":"adventure"},{"label":"bilibili","value":"bilibili"},{"label":"Chinese Novel","value":"chinese-novel"},{"label":"Comedy","value":"comedy"},{"label":"Crossdressing","value":"crossdressing"},{"label":"Drama","value":"drama"},{"label":"Dropped","value":"dropped"},{"label":"Family","value":"family"},{"label":"Fantasy","value":"fantasy"},{"label":"Gender Bender","value":"gender-bender"},{"label":"Historical","value":"historical"},{"label":"Horror","value":"horror"},{"label":"Isekai","value":"isekai"},{"label":"Korean Novel","value":"korean-novell"},{"label":"Manga","value":"manga"},{"label":"Manhua","value":"manhua"},{"label":"Manhwa","value":"manhwa"},{"label":"Modern Romance","value":"modern-romance"},{"label":"Mystery","value":"mystery"},{"label":"Office Workers","value":"office-workers"},{"label":"One shot","value":"one-shot"},{"label":"Pilot Novel","value":"pilot-novel"},{"label":"R15","value":"r15"},{"label":"R19","value":"r19"},{"label":"Regression","value":"regression"},{"label":"Reincarnation","value":"reincarnation"},{"label":"Reverse Harem","value":"reverse-harem"},{"label":"Romance Fantasy","value":"romance-fantasy"},{"label":"School Life","value":"school-life"},{"label":"Sci-fi","value":"sci-fi"},{"label":"Slice of Life","value":"slice-of-life"},{"label":"Smut","value":"smut"},{"label":"Supernatural","value":"supernatural"},{"label":"Violence","value":"violence"}],"inputType":"Picker"}],"options":{"path":{"novels":"series","novel":"series","chapter":"series","genres":"genre"},"useNewChapterEndpoint":true,"lang":"English"}}); +export default plugin; + \ No newline at end of file diff --git a/plugins/english/NeoSekaiTranslations[madara].ts b/plugins/english/NeoSekaiTranslations[madara].ts index ddbc72e..647bfd0 100644 --- a/plugins/english/NeoSekaiTranslations[madara].ts +++ b/plugins/english/NeoSekaiTranslations[madara].ts @@ -1,213 +1,252 @@ +import { fetchApi, fetchFile } from "@libs/fetch"; +import { Filter } from "@libs/filterInputs"; +import { Plugin } from '@typings/plugin' import { load as parseHTML } from "cheerio"; -import { fetchFile, fetchApi } from "@libs/fetch"; -import { Novel, Plugin, Chapter } from "@typings/plugin"; -import { FilterInputs } from "@libs/filterInputs"; import { defaultCover } from "@libs/defaultCover"; -import { NovelStatus } from "@libs/novelStatus" +import { NovelStatus } from "@libs/novelStatus"; import { parseMadaraDate } from "@libs/parseMadaraDate"; import dayjs from "dayjs"; -export const id = "neosekaiTLS"; -export const name = "NeoSekai Translations [madara]"; -export const icon = "multisrc/madara/icons/neosekaitranslations.png"; -export const version = "1.0.0"; -export const site = "https://www.neosekaitranslations.com/"; -const baseUrl = site; +interface MadaraOptionPath{ + genres?: string, + novels?: string, + novel?: string, + chapter?: string, +} -export const popularNovels: Plugin.popularNovels = async (pageNo, {filters, showLatestNovels}) => { - const novels: Novel.Item[] = []; +const MadaraDefaultPath: MadaraOptionPath = { + novels: 'novel', + novel: 'novel', + chapter: 'novel' +} - let url = site; +interface MadaraOptions { + useNewChapterEndpoint?: boolean, + path?: MadaraOptionPath, + lang?: string, + orderBy?: string +} - if (filters?.genres) { - url += "novel-genre/" + filters.genres + '/'; - } else { - url += "novel/"; +export interface MadaraMetadata { + id: string, + sourceSite: string, + sourceName: string, + options?: MadaraOptions, + filters?: Filter[], +} +class MadaraPlugin implements Plugin.PluginBase { + id: string; + name: string; + icon: string; + site: string; + version: string; + userAgent: string; + cookieString: string; + options?: MadaraOptions; + filter?: Filter[] | undefined; + + constructor(metadata: MadaraMetadata){ + this.id = metadata.id; + this.name = metadata.sourceName + "[madara]"; + const iconFileName = metadata.sourceName.replace(/\s+/g, "").toLowerCase(); + this.icon = `multisrc/madara/icons/${iconFileName}.png`; + this.site = metadata.sourceSite; + this.version = "1.0.0"; + this.userAgent = ""; + this.cookieString = ""; + this.options = metadata.options; + this.filter = metadata.filters; } + async popularNovels(pageNo: number, {filters, showLatestNovels}: Plugin.PopularNovelsOptions): Promise { + const novels: Plugin.NovelItem[] = []; - url += '/page/' + pageNo + '/' + - '?m_orderby=' + (showLatestNovels ? 'latest' : (filters?.sort || 'rating')); - - const body = await fetchApi(url).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - - loadedCheerio('.manga-title-badges').remove(); - - loadedCheerio('.page-item-detail').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - - let novelUrl = loadedCheerio(this).find('.post-title') - .find('a') - .attr('href') || ''; - const novel: Novel.Item = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - - novels.push(novel); - }); - - return novels; -}; - -export const parseNovelAndChapters: Plugin.parseNovelAndChapters = async ( - novelUrl -) => { - const novel: Novel.instance = { - url: novelUrl, - }; - - const body = await fetchApi(novelUrl).then(res => res.text()); - - let loadedCheerio = parseHTML(body); - - loadedCheerio('.manga-title-badges').remove(); - - novel.name = loadedCheerio('.post-title h1').text().trim(); - - novel.cover = - loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || - loadedCheerio('.summary_image > a > img').attr('data-src') || - loadedCheerio('.summary_image > a > img').attr('src') || - defaultCover; - - loadedCheerio('.post-content_item, .post-content').each(function () { - const detailName = loadedCheerio(this).find('h5').text().trim(); - const detail = loadedCheerio(this).find('.summary-content').text().trim(); - - switch (detailName) { - case 'Genre(s)': - case 'التصنيفات': - novel.genres = detail.replace(/[\t\n]/g, ','); - break; - case 'Author(s)': - case 'المؤلف': - case 'المؤلف (ين)': - novel.author = detail; - break; - case 'Status': - case 'الحالة': - novel.status = - detail.includes('OnGoing') || detail.includes('مستمرة') - ? NovelStatus.Ongoing - : NovelStatus.Completed; - break; - } - }); - - loadedCheerio('div.summary__content .code-block,script').remove(); - novel.summary = loadedCheerio('div.summary__content').text().trim(); - - - let html; - - if (false) { - const novelId = - loadedCheerio('.rating-post-id').attr('value') || - loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; - - const body = { - action: "manga_get_chapters", - manga: novelId, - } - html = await fetchApi( - baseUrl + 'wp-admin/admin-ajax.php', - { - method: 'POST', - body: JSON.stringify(body), - }) - .then(res => res.text()); - } else { - html = await fetchApi( - baseUrl + 'ajax/chapters/', - { method: 'POST' }) - .then(res => res.text()); - } - - if (html !== '0') { - loadedCheerio = parseHTML(html); - } - - const chapters: Chapter.Item[] = []; - loadedCheerio('.wp-manga-chapter').each(function () { - const chapterName = loadedCheerio(this).find('a').text().trim(); - - let releaseDate = null; - releaseDate = loadedCheerio(this) - .find('span.chapter-release-date') - .text() - .trim(); - - if (releaseDate) { - releaseDate = parseMadaraDate(releaseDate); + let url = this.site; + if (filters?.genres && this.options?.path?.genres) { + url += this.options?.path?.genres + filters.genres + '/'; } else { - /** - * Insert current date - */ - - releaseDate = dayjs().format('LL'); + url += this.options?.path?.novels ? this.options.path.novels : MadaraDefaultPath.novels; } + + url += '/page/' + pageNo + '/' + + '?m_orderby=' + (showLatestNovels ? 'latest' : (filters?.sort || 'rating')); + + const body = await fetchApi(url).then(res => res.text()); + + const loadedCheerio = parseHTML(body); + + loadedCheerio('.manga-title-badges').remove(); + + loadedCheerio('.page-item-detail').each(function () { + const novelName = loadedCheerio(this).find('.post-title').text().trim(); + let image = loadedCheerio(this).find('img'); + const novelCover = image.attr('data-src') || image.attr('src'); + + let novelUrl = loadedCheerio(this).find('.post-title') + .find('a') + .attr('href') || ''; + const novel: Plugin.NovelItem = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + + novels.push(novel); + }); + + return novels; + } + async parseNovelAndChapters(novelUrl: string): Promise { + const novel: Plugin.SourceNovel = { + url: novelUrl, + }; + + const body = await fetchApi(novelUrl).then(res => res.text()); + + let loadedCheerio = parseHTML(body); + + loadedCheerio('.manga-title-badges, #manga-title span').remove(); + novel.name = + loadedCheerio('.post-title h1').text().trim() || + loadedCheerio('#manga-title h1').text(); + + novel.cover = + loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || + loadedCheerio('.summary_image > a > img').attr('data-src') || + loadedCheerio('.summary_image > a > img').attr('src') || + defaultCover; + + loadedCheerio('.post-content_item, .post-content').each(function () { + const detailName = loadedCheerio(this).find('h5').text().trim(); + const detail = loadedCheerio(this).find('.summary-content').text().trim(); + + switch (detailName) { + case 'Genre(s)': + case 'التصنيفات': + novel.genres = detail.replace(/[\\t\\n]/g, ','); + break; + case 'Author(s)': + case 'المؤلف': + case 'المؤلف (ين)': + novel.author = detail; + break; + case 'Status': + case 'الحالة': + novel.status = + detail.includes('OnGoing') || detail.includes('مستمرة') + ? NovelStatus.Ongoing + : NovelStatus.Completed; + break; + } + }); + + loadedCheerio('div.summary__content .code-block,script').remove(); + novel.summary = + loadedCheerio('div.summary__content').text().trim() || + loadedCheerio('#tab-manga-about').text().trim() || + loadedCheerio('.post-content_item h5:contains("Summary")').next().text().trim(); + + let html; + + if (this.options?.useNewChapterEndpoint !== true) { + const novelId = + loadedCheerio('.rating-post-id').attr('value') || + loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; + + const formData = new FormData() + formData.append("action", "manga_get_chapters"); + formData.append("manga", novelId); - let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + html = await fetchApi( + this.site + 'wp-admin/admin-ajax.php', + { + method: 'POST', + body: formData, + }) + .then(res => res.text()); + } else { + html = await fetchApi( + novelUrl + 'ajax/chapters/', + { method: 'POST' }) + .then(res => res.text()); + } + + if (html !== '0') { + loadedCheerio = parseHTML(html); + } + + const chapters: Plugin.ChapterItem[] = []; + loadedCheerio('.wp-manga-chapter').each(function () { + const chapterName = loadedCheerio(this).find('a').text().trim(); + + let releaseDate = null; + releaseDate = loadedCheerio(this) + .find('span.chapter-release-date') + .text() + .trim(); + + if (releaseDate) { + releaseDate = parseMadaraDate(releaseDate); + } else { + /** + * Insert current date + */ + + releaseDate = dayjs().format('LL'); + } + + let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + + chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); + }); + + novel.chapters = chapters.reverse(); + return novel; + } + async parseChapter(chapterUrl: string): Promise { + const body = await fetchApi(chapterUrl).then(res => res.text()); - chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); - }); + const loadedCheerio = parseHTML(body); + const chapterText = + loadedCheerio('.text-left').html() || + loadedCheerio('.text-right').html() || + loadedCheerio('.entry-content').html() || ""; - novel.chapters = chapters.reverse(); - return novel; -}; - -export const parseChapter: Plugin.parseChapter = async (chapterUrl) => { - const url = baseUrl + "/" + "novel" + "/" + chapterUrl; - - const body = await fetchApi(chapterUrl).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - const chapterText = - loadedCheerio('.text-left').html() || - loadedCheerio('.text-right').html() || - loadedCheerio('.entry-content').html(); - - return chapterText; -}; - -export const searchNovels: Plugin.searchNovels = async (searchTerm) => { - const novels: Novel.Item[] = []; - const url = baseUrl + "?s=" + searchTerm + "&post_type=wp-manga"; - - const body = await fetchApi(url).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - - - loadedCheerio('.c-tabs-item__content').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - - let novelUrl = loadedCheerio(this) - .find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - - novels.push(novel); - }); - return novels; -}; - -export const fetchImage: Plugin.fetchImage = async (url) => { - return await fetchFile(url); -}; - -export const filters = [{"key":"sort","label":"Order by","values":[{"label":"Rating","value":"rating"},{"label":"A-Z","value":"alphabet"},{"label":"Latest","value":"latest"},{"label":"Most Views","value":"views"},{"label":"New","value":"new-manga"},{"label":"Trending","value":"trending"}],"inputType":FilterInputs.Picker},{"key":"genres","label":"GENRES","values":[{"label":"Action","value":"action"},{"label":"Adventure","value":"adventure"},{"label":"Comedy","value":"comedy"},{"label":"Drama","value":"drama"},{"label":"Fantasy","value":"fantasy"},{"label":"Harem","value":"harem"},{"label":"Horror","value":"horror"},{"label":"Mature","value":"mature"},{"label":"Mecha","value":"mecha"},{"label":"Mystery","value":"mystery"},{"label":"Psychological","value":"psychological"},{"label":"Romance","value":"romance"},{"label":"School Life","value":"school-life"},{"label":"Sci-Fi","value":"sci-fi"},{"label":"Slice of Life","value":"slice-of-life"}],"inputType":FilterInputs.Picker}]; \ No newline at end of file + return chapterText; + } + async searchNovels(searchTerm: string, pageNo?: number | undefined): Promise { + const novels: Plugin.NovelItem[] = []; + const url = this.site + "?s=" + searchTerm + "&post_type=wp-manga"; + + const body = await fetchApi(url).then(res => res.text()); + + const loadedCheerio = parseHTML(body); + + + loadedCheerio('.c-tabs-item__content').each(function () { + const novelName = loadedCheerio(this).find('.post-title').text().trim(); + + let image = loadedCheerio(this).find('img'); + const novelCover = image.attr('data-src') || image.attr('src'); + + let novelUrl = loadedCheerio(this) + .find('.post-title') + .find('a') + .attr('href') || ''; + const novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + + novels.push(novel); + }); + return novels; + } + async fetchImage(url: string): Promise { + return await fetchFile(url, {}); + } +} +const plugin = new MadaraPlugin({"id":"neosekaiTLS","sourceSite":"https://www.neosekaitranslations.com/","sourceName":"NeoSekai Translations","filters":[{"key":"sort","label":"Order by","values":[{"label":"Rating","value":"rating"},{"label":"A-Z","value":"alphabet"},{"label":"Latest","value":"latest"},{"label":"Most Views","value":"views"},{"label":"New","value":"new-manga"},{"label":"Trending","value":"trending"}],"inputType":"Picker"},{"key":"genres","label":"GENRES","values":[{"label":"Action","value":"action"},{"label":"Adventure","value":"adventure"},{"label":"Comedy","value":"comedy"},{"label":"Drama","value":"drama"},{"label":"Fantasy","value":"fantasy"},{"label":"Harem","value":"harem"},{"label":"Horror","value":"horror"},{"label":"Mature","value":"mature"},{"label":"Mecha","value":"mecha"},{"label":"Mystery","value":"mystery"},{"label":"Psychological","value":"psychological"},{"label":"Romance","value":"romance"},{"label":"School Life","value":"school-life"},{"label":"Sci-Fi","value":"sci-fi"},{"label":"Slice of Life","value":"slice-of-life"}],"inputType":"Picker"}],"options":{"lang":"English"}}); +export default plugin; + \ No newline at end of file diff --git a/plugins/english/NocturneTranslations[madara].ts b/plugins/english/NocturneTranslations[madara].ts index 8adf67b..f3b2b46 100644 --- a/plugins/english/NocturneTranslations[madara].ts +++ b/plugins/english/NocturneTranslations[madara].ts @@ -1,213 +1,252 @@ +import { fetchApi, fetchFile } from "@libs/fetch"; +import { Filter } from "@libs/filterInputs"; +import { Plugin } from '@typings/plugin' import { load as parseHTML } from "cheerio"; -import { fetchFile, fetchApi } from "@libs/fetch"; -import { Novel, Plugin, Chapter } from "@typings/plugin"; -import { FilterInputs } from "@libs/filterInputs"; import { defaultCover } from "@libs/defaultCover"; -import { NovelStatus } from "@libs/novelStatus" +import { NovelStatus } from "@libs/novelStatus"; import { parseMadaraDate } from "@libs/parseMadaraDate"; import dayjs from "dayjs"; -export const id = "nocturneTLS"; -export const name = "Nocturne Translations [madara]"; -export const icon = "multisrc/madara/icons/nocturnetranslations.png"; -export const version = "1.0.0"; -export const site = "https://nocturnetls.net/"; -const baseUrl = site; +interface MadaraOptionPath{ + genres?: string, + novels?: string, + novel?: string, + chapter?: string, +} -export const popularNovels: Plugin.popularNovels = async (pageNo, {filters, showLatestNovels}) => { - const novels: Novel.Item[] = []; +const MadaraDefaultPath: MadaraOptionPath = { + novels: 'novel', + novel: 'novel', + chapter: 'novel' +} - let url = site; +interface MadaraOptions { + useNewChapterEndpoint?: boolean, + path?: MadaraOptionPath, + lang?: string, + orderBy?: string +} - if (filters?.genres) { - url += "manga-genre/" + filters.genres + '/'; - } else { - url += "novels/"; +export interface MadaraMetadata { + id: string, + sourceSite: string, + sourceName: string, + options?: MadaraOptions, + filters?: Filter[], +} +class MadaraPlugin implements Plugin.PluginBase { + id: string; + name: string; + icon: string; + site: string; + version: string; + userAgent: string; + cookieString: string; + options?: MadaraOptions; + filter?: Filter[] | undefined; + + constructor(metadata: MadaraMetadata){ + this.id = metadata.id; + this.name = metadata.sourceName + "[madara]"; + const iconFileName = metadata.sourceName.replace(/\s+/g, "").toLowerCase(); + this.icon = `multisrc/madara/icons/${iconFileName}.png`; + this.site = metadata.sourceSite; + this.version = "1.0.0"; + this.userAgent = ""; + this.cookieString = ""; + this.options = metadata.options; + this.filter = metadata.filters; } + async popularNovels(pageNo: number, {filters, showLatestNovels}: Plugin.PopularNovelsOptions): Promise { + const novels: Plugin.NovelItem[] = []; - url += '/page/' + pageNo + '/' + - '?m_orderby=' + (showLatestNovels ? 'latest' : (filters?.sort || 'rating')); - - const body = await fetchApi(url).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - - loadedCheerio('.manga-title-badges').remove(); - - loadedCheerio('.page-item-detail').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - - let novelUrl = loadedCheerio(this).find('.post-title') - .find('a') - .attr('href') || ''; - const novel: Novel.Item = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - - novels.push(novel); - }); - - return novels; -}; - -export const parseNovelAndChapters: Plugin.parseNovelAndChapters = async ( - novelUrl -) => { - const novel: Novel.instance = { - url: novelUrl, - }; - - const body = await fetchApi(novelUrl).then(res => res.text()); - - let loadedCheerio = parseHTML(body); - - loadedCheerio('.manga-title-badges').remove(); - - novel.name = loadedCheerio('.post-title h1').text().trim(); - - novel.cover = - loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || - loadedCheerio('.summary_image > a > img').attr('data-src') || - loadedCheerio('.summary_image > a > img').attr('src') || - defaultCover; - - loadedCheerio('.post-content_item, .post-content').each(function () { - const detailName = loadedCheerio(this).find('h5').text().trim(); - const detail = loadedCheerio(this).find('.summary-content').text().trim(); - - switch (detailName) { - case 'Genre(s)': - case 'التصنيفات': - novel.genres = detail.replace(/[\t\n]/g, ','); - break; - case 'Author(s)': - case 'المؤلف': - case 'المؤلف (ين)': - novel.author = detail; - break; - case 'Status': - case 'الحالة': - novel.status = - detail.includes('OnGoing') || detail.includes('مستمرة') - ? NovelStatus.Ongoing - : NovelStatus.Completed; - break; - } - }); - - loadedCheerio('div.summary__content .code-block,script').remove(); - novel.summary = loadedCheerio('div.summary__content').text().trim(); - - - let html; - - if (false) { - const novelId = - loadedCheerio('.rating-post-id').attr('value') || - loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; - - const body = { - action: "manga_get_chapters", - manga: novelId, - } - html = await fetchApi( - baseUrl + 'wp-admin/admin-ajax.php', - { - method: 'POST', - body: JSON.stringify(body), - }) - .then(res => res.text()); - } else { - html = await fetchApi( - baseUrl + 'ajax/chapters/', - { method: 'POST' }) - .then(res => res.text()); - } - - if (html !== '0') { - loadedCheerio = parseHTML(html); - } - - const chapters: Chapter.Item[] = []; - loadedCheerio('.wp-manga-chapter').each(function () { - const chapterName = loadedCheerio(this).find('a').text().trim(); - - let releaseDate = null; - releaseDate = loadedCheerio(this) - .find('span.chapter-release-date') - .text() - .trim(); - - if (releaseDate) { - releaseDate = parseMadaraDate(releaseDate); + let url = this.site; + if (filters?.genres && this.options?.path?.genres) { + url += this.options?.path?.genres + filters.genres + '/'; } else { - /** - * Insert current date - */ - - releaseDate = dayjs().format('LL'); + url += this.options?.path?.novels ? this.options.path.novels : MadaraDefaultPath.novels; } + + url += '/page/' + pageNo + '/' + + '?m_orderby=' + (showLatestNovels ? 'latest' : (filters?.sort || 'rating')); + + const body = await fetchApi(url).then(res => res.text()); + + const loadedCheerio = parseHTML(body); + + loadedCheerio('.manga-title-badges').remove(); + + loadedCheerio('.page-item-detail').each(function () { + const novelName = loadedCheerio(this).find('.post-title').text().trim(); + let image = loadedCheerio(this).find('img'); + const novelCover = image.attr('data-src') || image.attr('src'); + + let novelUrl = loadedCheerio(this).find('.post-title') + .find('a') + .attr('href') || ''; + const novel: Plugin.NovelItem = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + + novels.push(novel); + }); + + return novels; + } + async parseNovelAndChapters(novelUrl: string): Promise { + const novel: Plugin.SourceNovel = { + url: novelUrl, + }; + + const body = await fetchApi(novelUrl).then(res => res.text()); + + let loadedCheerio = parseHTML(body); + + loadedCheerio('.manga-title-badges, #manga-title span').remove(); + novel.name = + loadedCheerio('.post-title h1').text().trim() || + loadedCheerio('#manga-title h1').text(); + + novel.cover = + loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || + loadedCheerio('.summary_image > a > img').attr('data-src') || + loadedCheerio('.summary_image > a > img').attr('src') || + defaultCover; + + loadedCheerio('.post-content_item, .post-content').each(function () { + const detailName = loadedCheerio(this).find('h5').text().trim(); + const detail = loadedCheerio(this).find('.summary-content').text().trim(); + + switch (detailName) { + case 'Genre(s)': + case 'التصنيفات': + novel.genres = detail.replace(/[\\t\\n]/g, ','); + break; + case 'Author(s)': + case 'المؤلف': + case 'المؤلف (ين)': + novel.author = detail; + break; + case 'Status': + case 'الحالة': + novel.status = + detail.includes('OnGoing') || detail.includes('مستمرة') + ? NovelStatus.Ongoing + : NovelStatus.Completed; + break; + } + }); + + loadedCheerio('div.summary__content .code-block,script').remove(); + novel.summary = + loadedCheerio('div.summary__content').text().trim() || + loadedCheerio('#tab-manga-about').text().trim() || + loadedCheerio('.post-content_item h5:contains("Summary")').next().text().trim(); + + let html; + + if (this.options?.useNewChapterEndpoint !== true) { + const novelId = + loadedCheerio('.rating-post-id').attr('value') || + loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; + + const formData = new FormData() + formData.append("action", "manga_get_chapters"); + formData.append("manga", novelId); - let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + html = await fetchApi( + this.site + 'wp-admin/admin-ajax.php', + { + method: 'POST', + body: formData, + }) + .then(res => res.text()); + } else { + html = await fetchApi( + novelUrl + 'ajax/chapters/', + { method: 'POST' }) + .then(res => res.text()); + } + + if (html !== '0') { + loadedCheerio = parseHTML(html); + } + + const chapters: Plugin.ChapterItem[] = []; + loadedCheerio('.wp-manga-chapter').each(function () { + const chapterName = loadedCheerio(this).find('a').text().trim(); + + let releaseDate = null; + releaseDate = loadedCheerio(this) + .find('span.chapter-release-date') + .text() + .trim(); + + if (releaseDate) { + releaseDate = parseMadaraDate(releaseDate); + } else { + /** + * Insert current date + */ + + releaseDate = dayjs().format('LL'); + } + + let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + + chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); + }); + + novel.chapters = chapters.reverse(); + return novel; + } + async parseChapter(chapterUrl: string): Promise { + const body = await fetchApi(chapterUrl).then(res => res.text()); - chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); - }); + const loadedCheerio = parseHTML(body); + const chapterText = + loadedCheerio('.text-left').html() || + loadedCheerio('.text-right').html() || + loadedCheerio('.entry-content').html() || ""; - novel.chapters = chapters.reverse(); - return novel; -}; - -export const parseChapter: Plugin.parseChapter = async (chapterUrl) => { - const url = baseUrl + "/" + "novels" + "/" + chapterUrl; - - const body = await fetchApi(chapterUrl).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - const chapterText = - loadedCheerio('.text-left').html() || - loadedCheerio('.text-right').html() || - loadedCheerio('.entry-content').html(); - - return chapterText; -}; - -export const searchNovels: Plugin.searchNovels = async (searchTerm) => { - const novels: Novel.Item[] = []; - const url = baseUrl + "?s=" + searchTerm + "&post_type=wp-manga"; - - const body = await fetchApi(url).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - - - loadedCheerio('.c-tabs-item__content').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - - let novelUrl = loadedCheerio(this) - .find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - - novels.push(novel); - }); - return novels; -}; - -export const fetchImage: Plugin.fetchImage = async (url) => { - return await fetchFile(url); -}; - -export const filters = [{"key":"sort","label":"Order by","values":[{"label":"Rating","value":"rating"},{"label":"A-Z","value":"alphabet"},{"label":"Latest","value":"latest"},{"label":"Most Views","value":"views"},{"label":"New","value":"new-manga"},{"label":"Trending","value":"trending"}],"inputType":FilterInputs.Picker},{"key":"genres","label":"GENRES","values":[{"label":"Action","value":"action"},{"label":"Adult","value":"adult"},{"label":"Adventure","value":"adventure"},{"label":"Anime","value":"anime"},{"label":"Cartoon","value":"cartoon"},{"label":"Comedy","value":"comedy"},{"label":"Comic","value":"comic"},{"label":"Cooking","value":"cooking"},{"label":"Detective","value":"detective"},{"label":"Doujinshi","value":"doujinshi"},{"label":"Drama","value":"drama"},{"label":"Ecchi","value":"ecchi"},{"label":"Fantasy","value":"fantasy"},{"label":"Gender Bender","value":"gender-bender"},{"label":"Harem","value":"harem"},{"label":"Historical","value":"historical"},{"label":"Horror","value":"horror"},{"label":"Josei","value":"josei"},{"label":"Live action","value":"live-action"},{"label":"Manga","value":"manga"},{"label":"Manhua","value":"manhua"},{"label":"Manhwa","value":"manhwa"},{"label":"Martial Arts","value":"martial-arts"},{"label":"Mature","value":"mature"},{"label":"Mecha","value":"mecha"},{"label":"Mystery","value":"mystery"},{"label":"One shot","value":"one-shot"},{"label":"Psychological","value":"psychological"},{"label":"Romance","value":"romance"},{"label":"School Life","value":"school-life"},{"label":"Sci-fi","value":"sci-fi"},{"label":"Seinen","value":"seinen"},{"label":"Shoujo","value":"shoujo"},{"label":"Shoujo Ai","value":"shoujo-ai"},{"label":"Shounen","value":"shounen"},{"label":"Shounen Ai","value":"shounen-ai"},{"label":"Slice of Life","value":"slice-of-life"},{"label":"Smut","value":"smut"},{"label":"Soft Yaoi","value":"soft-yaoi"},{"label":"Soft Yuri","value":"soft-yuri"},{"label":"Sports","value":"sports"},{"label":"Supernatural","value":"supernatural"},{"label":"Tragedy","value":"tragedy"},{"label":"Webtoon","value":"webtoon"},{"label":"Yaoi","value":"yaoi"},{"label":"Yuri","value":"yuri"}],"inputType":FilterInputs.Picker}]; \ No newline at end of file + return chapterText; + } + async searchNovels(searchTerm: string, pageNo?: number | undefined): Promise { + const novels: Plugin.NovelItem[] = []; + const url = this.site + "?s=" + searchTerm + "&post_type=wp-manga"; + + const body = await fetchApi(url).then(res => res.text()); + + const loadedCheerio = parseHTML(body); + + + loadedCheerio('.c-tabs-item__content').each(function () { + const novelName = loadedCheerio(this).find('.post-title').text().trim(); + + let image = loadedCheerio(this).find('img'); + const novelCover = image.attr('data-src') || image.attr('src'); + + let novelUrl = loadedCheerio(this) + .find('.post-title') + .find('a') + .attr('href') || ''; + const novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + + novels.push(novel); + }); + return novels; + } + async fetchImage(url: string): Promise { + return await fetchFile(url, {}); + } +} +const plugin = new MadaraPlugin({"id":"nocturneTLS","sourceSite":"https://nocturnetls.net/","sourceName":"Nocturne Translations","filters":[{"key":"sort","label":"Order by","values":[{"label":"Rating","value":"rating"},{"label":"A-Z","value":"alphabet"},{"label":"Latest","value":"latest"},{"label":"Most Views","value":"views"},{"label":"New","value":"new-manga"},{"label":"Trending","value":"trending"}],"inputType":"Picker"},{"key":"genres","label":"GENRES","values":[{"label":"Action","value":"action"},{"label":"Adult","value":"adult"},{"label":"Adventure","value":"adventure"},{"label":"Anime","value":"anime"},{"label":"Cartoon","value":"cartoon"},{"label":"Comedy","value":"comedy"},{"label":"Comic","value":"comic"},{"label":"Cooking","value":"cooking"},{"label":"Detective","value":"detective"},{"label":"Doujinshi","value":"doujinshi"},{"label":"Drama","value":"drama"},{"label":"Ecchi","value":"ecchi"},{"label":"Fantasy","value":"fantasy"},{"label":"Gender Bender","value":"gender-bender"},{"label":"Harem","value":"harem"},{"label":"Historical","value":"historical"},{"label":"Horror","value":"horror"},{"label":"Josei","value":"josei"},{"label":"Live action","value":"live-action"},{"label":"Manga","value":"manga"},{"label":"Manhua","value":"manhua"},{"label":"Manhwa","value":"manhwa"},{"label":"Martial Arts","value":"martial-arts"},{"label":"Mature","value":"mature"},{"label":"Mecha","value":"mecha"},{"label":"Mystery","value":"mystery"},{"label":"One shot","value":"one-shot"},{"label":"Psychological","value":"psychological"},{"label":"Romance","value":"romance"},{"label":"School Life","value":"school-life"},{"label":"Sci-fi","value":"sci-fi"},{"label":"Seinen","value":"seinen"},{"label":"Shoujo","value":"shoujo"},{"label":"Shoujo Ai","value":"shoujo-ai"},{"label":"Shounen","value":"shounen"},{"label":"Shounen Ai","value":"shounen-ai"},{"label":"Slice of Life","value":"slice-of-life"},{"label":"Smut","value":"smut"},{"label":"Soft Yaoi","value":"soft-yaoi"},{"label":"Soft Yuri","value":"soft-yuri"},{"label":"Sports","value":"sports"},{"label":"Supernatural","value":"supernatural"},{"label":"Tragedy","value":"tragedy"},{"label":"Webtoon","value":"webtoon"},{"label":"Yaoi","value":"yaoi"},{"label":"Yuri","value":"yuri"}],"inputType":"Picker"}],"options":{"path":{"novels":"novels","novel":"novels","chapter":"novels","genres":"manga-genre"},"lang":"English"}}); +export default plugin; + \ No newline at end of file diff --git a/plugins/english/NoobchanTranslation[madara].ts b/plugins/english/NoobchanTranslation[madara].ts index 0bb737e..710c49c 100644 --- a/plugins/english/NoobchanTranslation[madara].ts +++ b/plugins/english/NoobchanTranslation[madara].ts @@ -1,213 +1,252 @@ +import { fetchApi, fetchFile } from "@libs/fetch"; +import { Filter } from "@libs/filterInputs"; +import { Plugin } from '@typings/plugin' import { load as parseHTML } from "cheerio"; -import { fetchFile, fetchApi } from "@libs/fetch"; -import { Novel, Plugin, Chapter } from "@typings/plugin"; -import { FilterInputs } from "@libs/filterInputs"; import { defaultCover } from "@libs/defaultCover"; -import { NovelStatus } from "@libs/novelStatus" +import { NovelStatus } from "@libs/novelStatus"; import { parseMadaraDate } from "@libs/parseMadaraDate"; import dayjs from "dayjs"; -export const id = "noobchanTL"; -export const name = "Noobchan Translation [madara]"; -export const icon = "multisrc/madara/icons/noobchantranslation.png"; -export const version = "1.0.0"; -export const site = "https://noobchan.xyz/"; -const baseUrl = site; +interface MadaraOptionPath{ + genres?: string, + novels?: string, + novel?: string, + chapter?: string, +} -export const popularNovels: Plugin.popularNovels = async (pageNo, {filters, showLatestNovels}) => { - const novels: Novel.Item[] = []; +const MadaraDefaultPath: MadaraOptionPath = { + novels: 'novel', + novel: 'novel', + chapter: 'novel' +} - let url = site; +interface MadaraOptions { + useNewChapterEndpoint?: boolean, + path?: MadaraOptionPath, + lang?: string, + orderBy?: string +} - if (filters?.genres) { - url += "novel-genre/" + filters.genres + '/'; - } else { - url += "novel/"; +export interface MadaraMetadata { + id: string, + sourceSite: string, + sourceName: string, + options?: MadaraOptions, + filters?: Filter[], +} +class MadaraPlugin implements Plugin.PluginBase { + id: string; + name: string; + icon: string; + site: string; + version: string; + userAgent: string; + cookieString: string; + options?: MadaraOptions; + filter?: Filter[] | undefined; + + constructor(metadata: MadaraMetadata){ + this.id = metadata.id; + this.name = metadata.sourceName + "[madara]"; + const iconFileName = metadata.sourceName.replace(/\s+/g, "").toLowerCase(); + this.icon = `multisrc/madara/icons/${iconFileName}.png`; + this.site = metadata.sourceSite; + this.version = "1.0.0"; + this.userAgent = ""; + this.cookieString = ""; + this.options = metadata.options; + this.filter = metadata.filters; } + async popularNovels(pageNo: number, {filters, showLatestNovels}: Plugin.PopularNovelsOptions): Promise { + const novels: Plugin.NovelItem[] = []; - url += '/page/' + pageNo + '/' + - '?m_orderby=' + (showLatestNovels ? 'latest' : (filters?.sort || 'rating')); - - const body = await fetchApi(url).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - - loadedCheerio('.manga-title-badges').remove(); - - loadedCheerio('.page-item-detail').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - - let novelUrl = loadedCheerio(this).find('.post-title') - .find('a') - .attr('href') || ''; - const novel: Novel.Item = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - - novels.push(novel); - }); - - return novels; -}; - -export const parseNovelAndChapters: Plugin.parseNovelAndChapters = async ( - novelUrl -) => { - const novel: Novel.instance = { - url: novelUrl, - }; - - const body = await fetchApi(novelUrl).then(res => res.text()); - - let loadedCheerio = parseHTML(body); - - loadedCheerio('.manga-title-badges').remove(); - - novel.name = loadedCheerio('.post-title h1').text().trim(); - - novel.cover = - loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || - loadedCheerio('.summary_image > a > img').attr('data-src') || - loadedCheerio('.summary_image > a > img').attr('src') || - defaultCover; - - loadedCheerio('.post-content_item, .post-content').each(function () { - const detailName = loadedCheerio(this).find('h5').text().trim(); - const detail = loadedCheerio(this).find('.summary-content').text().trim(); - - switch (detailName) { - case 'Genre(s)': - case 'التصنيفات': - novel.genres = detail.replace(/[\t\n]/g, ','); - break; - case 'Author(s)': - case 'المؤلف': - case 'المؤلف (ين)': - novel.author = detail; - break; - case 'Status': - case 'الحالة': - novel.status = - detail.includes('OnGoing') || detail.includes('مستمرة') - ? NovelStatus.Ongoing - : NovelStatus.Completed; - break; - } - }); - - loadedCheerio('div.summary__content .code-block,script').remove(); - novel.summary = loadedCheerio('div.summary__content').text().trim(); - - - let html; - - if (true) { - const novelId = - loadedCheerio('.rating-post-id').attr('value') || - loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; - - const body = { - action: "manga_get_chapters", - manga: novelId, - } - html = await fetchApi( - baseUrl + 'wp-admin/admin-ajax.php', - { - method: 'POST', - body: JSON.stringify(body), - }) - .then(res => res.text()); - } else { - html = await fetchApi( - baseUrl + 'ajax/chapters/', - { method: 'POST' }) - .then(res => res.text()); - } - - if (html !== '0') { - loadedCheerio = parseHTML(html); - } - - const chapters: Chapter.Item[] = []; - loadedCheerio('.wp-manga-chapter').each(function () { - const chapterName = loadedCheerio(this).find('a').text().trim(); - - let releaseDate = null; - releaseDate = loadedCheerio(this) - .find('span.chapter-release-date') - .text() - .trim(); - - if (releaseDate) { - releaseDate = parseMadaraDate(releaseDate); + let url = this.site; + if (filters?.genres && this.options?.path?.genres) { + url += this.options?.path?.genres + filters.genres + '/'; } else { - /** - * Insert current date - */ - - releaseDate = dayjs().format('LL'); + url += this.options?.path?.novels ? this.options.path.novels : MadaraDefaultPath.novels; } + + url += '/page/' + pageNo + '/' + + '?m_orderby=' + (showLatestNovels ? 'latest' : (filters?.sort || 'rating')); + + const body = await fetchApi(url).then(res => res.text()); + + const loadedCheerio = parseHTML(body); + + loadedCheerio('.manga-title-badges').remove(); + + loadedCheerio('.page-item-detail').each(function () { + const novelName = loadedCheerio(this).find('.post-title').text().trim(); + let image = loadedCheerio(this).find('img'); + const novelCover = image.attr('data-src') || image.attr('src'); + + let novelUrl = loadedCheerio(this).find('.post-title') + .find('a') + .attr('href') || ''; + const novel: Plugin.NovelItem = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + + novels.push(novel); + }); + + return novels; + } + async parseNovelAndChapters(novelUrl: string): Promise { + const novel: Plugin.SourceNovel = { + url: novelUrl, + }; + + const body = await fetchApi(novelUrl).then(res => res.text()); + + let loadedCheerio = parseHTML(body); + + loadedCheerio('.manga-title-badges, #manga-title span').remove(); + novel.name = + loadedCheerio('.post-title h1').text().trim() || + loadedCheerio('#manga-title h1').text(); + + novel.cover = + loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || + loadedCheerio('.summary_image > a > img').attr('data-src') || + loadedCheerio('.summary_image > a > img').attr('src') || + defaultCover; + + loadedCheerio('.post-content_item, .post-content').each(function () { + const detailName = loadedCheerio(this).find('h5').text().trim(); + const detail = loadedCheerio(this).find('.summary-content').text().trim(); + + switch (detailName) { + case 'Genre(s)': + case 'التصنيفات': + novel.genres = detail.replace(/[\\t\\n]/g, ','); + break; + case 'Author(s)': + case 'المؤلف': + case 'المؤلف (ين)': + novel.author = detail; + break; + case 'Status': + case 'الحالة': + novel.status = + detail.includes('OnGoing') || detail.includes('مستمرة') + ? NovelStatus.Ongoing + : NovelStatus.Completed; + break; + } + }); + + loadedCheerio('div.summary__content .code-block,script').remove(); + novel.summary = + loadedCheerio('div.summary__content').text().trim() || + loadedCheerio('#tab-manga-about').text().trim() || + loadedCheerio('.post-content_item h5:contains("Summary")').next().text().trim(); + + let html; + + if (this.options?.useNewChapterEndpoint !== true) { + const novelId = + loadedCheerio('.rating-post-id').attr('value') || + loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; + + const formData = new FormData() + formData.append("action", "manga_get_chapters"); + formData.append("manga", novelId); - let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + html = await fetchApi( + this.site + 'wp-admin/admin-ajax.php', + { + method: 'POST', + body: formData, + }) + .then(res => res.text()); + } else { + html = await fetchApi( + novelUrl + 'ajax/chapters/', + { method: 'POST' }) + .then(res => res.text()); + } + + if (html !== '0') { + loadedCheerio = parseHTML(html); + } + + const chapters: Plugin.ChapterItem[] = []; + loadedCheerio('.wp-manga-chapter').each(function () { + const chapterName = loadedCheerio(this).find('a').text().trim(); + + let releaseDate = null; + releaseDate = loadedCheerio(this) + .find('span.chapter-release-date') + .text() + .trim(); + + if (releaseDate) { + releaseDate = parseMadaraDate(releaseDate); + } else { + /** + * Insert current date + */ + + releaseDate = dayjs().format('LL'); + } + + let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + + chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); + }); + + novel.chapters = chapters.reverse(); + return novel; + } + async parseChapter(chapterUrl: string): Promise { + const body = await fetchApi(chapterUrl).then(res => res.text()); - chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); - }); + const loadedCheerio = parseHTML(body); + const chapterText = + loadedCheerio('.text-left').html() || + loadedCheerio('.text-right').html() || + loadedCheerio('.entry-content').html() || ""; - novel.chapters = chapters.reverse(); - return novel; -}; - -export const parseChapter: Plugin.parseChapter = async (chapterUrl) => { - const url = baseUrl + "/" + "novel" + "/" + chapterUrl; - - const body = await fetchApi(chapterUrl).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - const chapterText = - loadedCheerio('.text-left').html() || - loadedCheerio('.text-right').html() || - loadedCheerio('.entry-content').html(); - - return chapterText; -}; - -export const searchNovels: Plugin.searchNovels = async (searchTerm) => { - const novels: Novel.Item[] = []; - const url = baseUrl + "?s=" + searchTerm + "&post_type=wp-manga"; - - const body = await fetchApi(url).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - - - loadedCheerio('.c-tabs-item__content').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - - let novelUrl = loadedCheerio(this) - .find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - - novels.push(novel); - }); - return novels; -}; - -export const fetchImage: Plugin.fetchImage = async (url) => { - return await fetchFile(url); -}; - -export const filters = []; \ No newline at end of file + return chapterText; + } + async searchNovels(searchTerm: string, pageNo?: number | undefined): Promise { + const novels: Plugin.NovelItem[] = []; + const url = this.site + "?s=" + searchTerm + "&post_type=wp-manga"; + + const body = await fetchApi(url).then(res => res.text()); + + const loadedCheerio = parseHTML(body); + + + loadedCheerio('.c-tabs-item__content').each(function () { + const novelName = loadedCheerio(this).find('.post-title').text().trim(); + + let image = loadedCheerio(this).find('img'); + const novelCover = image.attr('data-src') || image.attr('src'); + + let novelUrl = loadedCheerio(this) + .find('.post-title') + .find('a') + .attr('href') || ''; + const novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + + novels.push(novel); + }); + return novels; + } + async fetchImage(url: string): Promise { + return await fetchFile(url, {}); + } +} +const plugin = new MadaraPlugin({"id":"noobchanTL","sourceSite":"https://noobchan.xyz/","sourceName":"Noobchan Translation","filters":[],"options":{"useNewChapterEndpoint":true,"lang":"English"}}); +export default plugin; + \ No newline at end of file diff --git a/plugins/english/NovelFullMe.ts b/plugins/english/NovelFullMe.broken.ts similarity index 100% rename from plugins/english/NovelFullMe.ts rename to plugins/english/NovelFullMe.broken.ts diff --git a/plugins/english/NovelMultiverse[madara].ts b/plugins/english/NovelMultiverse[madara].ts index e073558..566a6f5 100644 --- a/plugins/english/NovelMultiverse[madara].ts +++ b/plugins/english/NovelMultiverse[madara].ts @@ -1,213 +1,252 @@ +import { fetchApi, fetchFile } from "@libs/fetch"; +import { Filter } from "@libs/filterInputs"; +import { Plugin } from '@typings/plugin' import { load as parseHTML } from "cheerio"; -import { fetchFile, fetchApi } from "@libs/fetch"; -import { Novel, Plugin, Chapter } from "@typings/plugin"; -import { FilterInputs } from "@libs/filterInputs"; import { defaultCover } from "@libs/defaultCover"; -import { NovelStatus } from "@libs/novelStatus" +import { NovelStatus } from "@libs/novelStatus"; import { parseMadaraDate } from "@libs/parseMadaraDate"; import dayjs from "dayjs"; -export const id = "novelmultiverse"; -export const name = "NovelMultiverse [madara]"; -export const icon = "multisrc/madara/icons/novelmultiverse.png"; -export const version = "1.0.0"; -export const site = "https://www.novelmultiverse.com/"; -const baseUrl = site; +interface MadaraOptionPath{ + genres?: string, + novels?: string, + novel?: string, + chapter?: string, +} -export const popularNovels: Plugin.popularNovels = async (pageNo, {filters, showLatestNovels}) => { - const novels: Novel.Item[] = []; +const MadaraDefaultPath: MadaraOptionPath = { + novels: 'novel', + novel: 'novel', + chapter: 'novel' +} - let url = site; +interface MadaraOptions { + useNewChapterEndpoint?: boolean, + path?: MadaraOptionPath, + lang?: string, + orderBy?: string +} - if (filters?.genres) { - url += "novel-genre/" + filters.genres + '/'; - } else { - url += "novel/"; +export interface MadaraMetadata { + id: string, + sourceSite: string, + sourceName: string, + options?: MadaraOptions, + filters?: Filter[], +} +class MadaraPlugin implements Plugin.PluginBase { + id: string; + name: string; + icon: string; + site: string; + version: string; + userAgent: string; + cookieString: string; + options?: MadaraOptions; + filter?: Filter[] | undefined; + + constructor(metadata: MadaraMetadata){ + this.id = metadata.id; + this.name = metadata.sourceName + "[madara]"; + const iconFileName = metadata.sourceName.replace(/\s+/g, "").toLowerCase(); + this.icon = `multisrc/madara/icons/${iconFileName}.png`; + this.site = metadata.sourceSite; + this.version = "1.0.0"; + this.userAgent = ""; + this.cookieString = ""; + this.options = metadata.options; + this.filter = metadata.filters; } + async popularNovels(pageNo: number, {filters, showLatestNovels}: Plugin.PopularNovelsOptions): Promise { + const novels: Plugin.NovelItem[] = []; - url += '/page/' + pageNo + '/' + - '?m_orderby=' + (showLatestNovels ? 'latest' : (filters?.sort || 'rating')); - - const body = await fetchApi(url).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - - loadedCheerio('.manga-title-badges').remove(); - - loadedCheerio('.page-item-detail').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - - let novelUrl = loadedCheerio(this).find('.post-title') - .find('a') - .attr('href') || ''; - const novel: Novel.Item = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - - novels.push(novel); - }); - - return novels; -}; - -export const parseNovelAndChapters: Plugin.parseNovelAndChapters = async ( - novelUrl -) => { - const novel: Novel.instance = { - url: novelUrl, - }; - - const body = await fetchApi(novelUrl).then(res => res.text()); - - let loadedCheerio = parseHTML(body); - - loadedCheerio('.manga-title-badges').remove(); - - novel.name = loadedCheerio('.post-title h1').text().trim(); - - novel.cover = - loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || - loadedCheerio('.summary_image > a > img').attr('data-src') || - loadedCheerio('.summary_image > a > img').attr('src') || - defaultCover; - - loadedCheerio('.post-content_item, .post-content').each(function () { - const detailName = loadedCheerio(this).find('h5').text().trim(); - const detail = loadedCheerio(this).find('.summary-content').text().trim(); - - switch (detailName) { - case 'Genre(s)': - case 'التصنيفات': - novel.genres = detail.replace(/[\t\n]/g, ','); - break; - case 'Author(s)': - case 'المؤلف': - case 'المؤلف (ين)': - novel.author = detail; - break; - case 'Status': - case 'الحالة': - novel.status = - detail.includes('OnGoing') || detail.includes('مستمرة') - ? NovelStatus.Ongoing - : NovelStatus.Completed; - break; - } - }); - - loadedCheerio('div.summary__content .code-block,script').remove(); - novel.summary = loadedCheerio('div.summary__content').text().trim(); - - - let html; - - if (false) { - const novelId = - loadedCheerio('.rating-post-id').attr('value') || - loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; - - const body = { - action: "manga_get_chapters", - manga: novelId, - } - html = await fetchApi( - baseUrl + 'wp-admin/admin-ajax.php', - { - method: 'POST', - body: JSON.stringify(body), - }) - .then(res => res.text()); - } else { - html = await fetchApi( - baseUrl + 'ajax/chapters/', - { method: 'POST' }) - .then(res => res.text()); - } - - if (html !== '0') { - loadedCheerio = parseHTML(html); - } - - const chapters: Chapter.Item[] = []; - loadedCheerio('.wp-manga-chapter').each(function () { - const chapterName = loadedCheerio(this).find('a').text().trim(); - - let releaseDate = null; - releaseDate = loadedCheerio(this) - .find('span.chapter-release-date') - .text() - .trim(); - - if (releaseDate) { - releaseDate = parseMadaraDate(releaseDate); + let url = this.site; + if (filters?.genres && this.options?.path?.genres) { + url += this.options?.path?.genres + filters.genres + '/'; } else { - /** - * Insert current date - */ - - releaseDate = dayjs().format('LL'); + url += this.options?.path?.novels ? this.options.path.novels : MadaraDefaultPath.novels; } + + url += '/page/' + pageNo + '/' + + '?m_orderby=' + (showLatestNovels ? 'latest' : (filters?.sort || 'rating')); + + const body = await fetchApi(url).then(res => res.text()); + + const loadedCheerio = parseHTML(body); + + loadedCheerio('.manga-title-badges').remove(); + + loadedCheerio('.page-item-detail').each(function () { + const novelName = loadedCheerio(this).find('.post-title').text().trim(); + let image = loadedCheerio(this).find('img'); + const novelCover = image.attr('data-src') || image.attr('src'); + + let novelUrl = loadedCheerio(this).find('.post-title') + .find('a') + .attr('href') || ''; + const novel: Plugin.NovelItem = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + + novels.push(novel); + }); + + return novels; + } + async parseNovelAndChapters(novelUrl: string): Promise { + const novel: Plugin.SourceNovel = { + url: novelUrl, + }; + + const body = await fetchApi(novelUrl).then(res => res.text()); + + let loadedCheerio = parseHTML(body); + + loadedCheerio('.manga-title-badges, #manga-title span').remove(); + novel.name = + loadedCheerio('.post-title h1').text().trim() || + loadedCheerio('#manga-title h1').text(); + + novel.cover = + loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || + loadedCheerio('.summary_image > a > img').attr('data-src') || + loadedCheerio('.summary_image > a > img').attr('src') || + defaultCover; + + loadedCheerio('.post-content_item, .post-content').each(function () { + const detailName = loadedCheerio(this).find('h5').text().trim(); + const detail = loadedCheerio(this).find('.summary-content').text().trim(); + + switch (detailName) { + case 'Genre(s)': + case 'التصنيفات': + novel.genres = detail.replace(/[\\t\\n]/g, ','); + break; + case 'Author(s)': + case 'المؤلف': + case 'المؤلف (ين)': + novel.author = detail; + break; + case 'Status': + case 'الحالة': + novel.status = + detail.includes('OnGoing') || detail.includes('مستمرة') + ? NovelStatus.Ongoing + : NovelStatus.Completed; + break; + } + }); + + loadedCheerio('div.summary__content .code-block,script').remove(); + novel.summary = + loadedCheerio('div.summary__content').text().trim() || + loadedCheerio('#tab-manga-about').text().trim() || + loadedCheerio('.post-content_item h5:contains("Summary")').next().text().trim(); + + let html; + + if (this.options?.useNewChapterEndpoint !== true) { + const novelId = + loadedCheerio('.rating-post-id').attr('value') || + loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; + + const formData = new FormData() + formData.append("action", "manga_get_chapters"); + formData.append("manga", novelId); - let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + html = await fetchApi( + this.site + 'wp-admin/admin-ajax.php', + { + method: 'POST', + body: formData, + }) + .then(res => res.text()); + } else { + html = await fetchApi( + novelUrl + 'ajax/chapters/', + { method: 'POST' }) + .then(res => res.text()); + } + + if (html !== '0') { + loadedCheerio = parseHTML(html); + } + + const chapters: Plugin.ChapterItem[] = []; + loadedCheerio('.wp-manga-chapter').each(function () { + const chapterName = loadedCheerio(this).find('a').text().trim(); + + let releaseDate = null; + releaseDate = loadedCheerio(this) + .find('span.chapter-release-date') + .text() + .trim(); + + if (releaseDate) { + releaseDate = parseMadaraDate(releaseDate); + } else { + /** + * Insert current date + */ + + releaseDate = dayjs().format('LL'); + } + + let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + + chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); + }); + + novel.chapters = chapters.reverse(); + return novel; + } + async parseChapter(chapterUrl: string): Promise { + const body = await fetchApi(chapterUrl).then(res => res.text()); - chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); - }); + const loadedCheerio = parseHTML(body); + const chapterText = + loadedCheerio('.text-left').html() || + loadedCheerio('.text-right').html() || + loadedCheerio('.entry-content').html() || ""; - novel.chapters = chapters.reverse(); - return novel; -}; - -export const parseChapter: Plugin.parseChapter = async (chapterUrl) => { - const url = baseUrl + "/" + "novel" + "/" + chapterUrl; - - const body = await fetchApi(chapterUrl).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - const chapterText = - loadedCheerio('.text-left').html() || - loadedCheerio('.text-right').html() || - loadedCheerio('.entry-content').html(); - - return chapterText; -}; - -export const searchNovels: Plugin.searchNovels = async (searchTerm) => { - const novels: Novel.Item[] = []; - const url = baseUrl + "?s=" + searchTerm + "&post_type=wp-manga"; - - const body = await fetchApi(url).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - - - loadedCheerio('.c-tabs-item__content').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - - let novelUrl = loadedCheerio(this) - .find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - - novels.push(novel); - }); - return novels; -}; - -export const fetchImage: Plugin.fetchImage = async (url) => { - return await fetchFile(url); -}; - -export const filters = [{"key":"sort","label":"Order by","values":[{"label":"Rating","value":"rating"},{"label":"A-Z","value":"alphabet"},{"label":"Latest","value":"latest"},{"label":"Most Views","value":"views"},{"label":"New","value":"new-manga"},{"label":"Trending","value":"trending"}],"inputType":FilterInputs.Picker},{"key":"genres","label":"GENRES","values":[{"label":"Action","value":"action"},{"label":"Adult","value":"adult"},{"label":"Adventure","value":"adventure"},{"label":"Anime","value":"anime"},{"label":"Cartoon","value":"cartoon"},{"label":"Comedy","value":"comedy"},{"label":"Comic","value":"comic"},{"label":"Cooking","value":"cooking"},{"label":"Detective","value":"detective"},{"label":"Doujinshi","value":"doujinshi"},{"label":"Drama","value":"drama"},{"label":"Ecchi","value":"ecchi"},{"label":"Fantasy","value":"fantasy"},{"label":"Gender Bender","value":"gender-bender"},{"label":"Harem","value":"harem"},{"label":"Historical","value":"historical"},{"label":"Horror","value":"horror"},{"label":"Josei","value":"josei"},{"label":"Live action","value":"live-action"},{"label":"Manga","value":"manga"},{"label":"Manhua","value":"manhua"},{"label":"Manhwa","value":"manhwa"},{"label":"Martial Arts","value":"martial-arts"},{"label":"Mature","value":"mature"},{"label":"Mecha","value":"mecha"},{"label":"Mystery","value":"mystery"},{"label":"One shot","value":"one-shot"},{"label":"Original","value":"original"},{"label":"Psychological","value":"psychological"},{"label":"Romance","value":"romance"},{"label":"School Life","value":"school-life"},{"label":"Sci-fi","value":"sci-fi"},{"label":"Seinen","value":"seinen"},{"label":"Shoujo","value":"shoujo"},{"label":"Shoujo Ai","value":"shoujo-ai"},{"label":"Shounen","value":"shounen"},{"label":"Shounen Ai","value":"shounen-ai"},{"label":"Slice of Life","value":"slice-of-life"},{"label":"Smut","value":"smut"},{"label":"Soft Yaoi","value":"soft-yaoi"},{"label":"Soft Yuri","value":"soft-yuri"},{"label":"Sports","value":"sports"},{"label":"Supernatural","value":"supernatural"},{"label":"Tragedy","value":"tragedy"},{"label":"Translation","value":"translation"},{"label":"Webtoon","value":"webtoon"},{"label":"Wuxia","value":"wuxia"},{"label":"Xianxia","value":"xianxia"},{"label":"Xuanhuan","value":"xuanhuan"},{"label":"Yaoi","value":"yaoi"},{"label":"Yuri","value":"yuri"}],"inputType":FilterInputs.Picker}]; \ No newline at end of file + return chapterText; + } + async searchNovels(searchTerm: string, pageNo?: number | undefined): Promise { + const novels: Plugin.NovelItem[] = []; + const url = this.site + "?s=" + searchTerm + "&post_type=wp-manga"; + + const body = await fetchApi(url).then(res => res.text()); + + const loadedCheerio = parseHTML(body); + + + loadedCheerio('.c-tabs-item__content').each(function () { + const novelName = loadedCheerio(this).find('.post-title').text().trim(); + + let image = loadedCheerio(this).find('img'); + const novelCover = image.attr('data-src') || image.attr('src'); + + let novelUrl = loadedCheerio(this) + .find('.post-title') + .find('a') + .attr('href') || ''; + const novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + + novels.push(novel); + }); + return novels; + } + async fetchImage(url: string): Promise { + return await fetchFile(url, {}); + } +} +const plugin = new MadaraPlugin({"id":"novelmultiverse","sourceSite":"https://www.novelmultiverse.com/","sourceName":"NovelMultiverse","filters":[{"key":"sort","label":"Order by","values":[{"label":"Rating","value":"rating"},{"label":"A-Z","value":"alphabet"},{"label":"Latest","value":"latest"},{"label":"Most Views","value":"views"},{"label":"New","value":"new-manga"},{"label":"Trending","value":"trending"}],"inputType":"Picker"},{"key":"genres","label":"GENRES","values":[{"label":"Action","value":"action"},{"label":"Adult","value":"adult"},{"label":"Adventure","value":"adventure"},{"label":"Anime","value":"anime"},{"label":"Cartoon","value":"cartoon"},{"label":"Comedy","value":"comedy"},{"label":"Comic","value":"comic"},{"label":"Cooking","value":"cooking"},{"label":"Detective","value":"detective"},{"label":"Doujinshi","value":"doujinshi"},{"label":"Drama","value":"drama"},{"label":"Ecchi","value":"ecchi"},{"label":"Fantasy","value":"fantasy"},{"label":"Gender Bender","value":"gender-bender"},{"label":"Harem","value":"harem"},{"label":"Historical","value":"historical"},{"label":"Horror","value":"horror"},{"label":"Josei","value":"josei"},{"label":"Live action","value":"live-action"},{"label":"Manga","value":"manga"},{"label":"Manhua","value":"manhua"},{"label":"Manhwa","value":"manhwa"},{"label":"Martial Arts","value":"martial-arts"},{"label":"Mature","value":"mature"},{"label":"Mecha","value":"mecha"},{"label":"Mystery","value":"mystery"},{"label":"One shot","value":"one-shot"},{"label":"Original","value":"original"},{"label":"Psychological","value":"psychological"},{"label":"Romance","value":"romance"},{"label":"School Life","value":"school-life"},{"label":"Sci-fi","value":"sci-fi"},{"label":"Seinen","value":"seinen"},{"label":"Shoujo","value":"shoujo"},{"label":"Shoujo Ai","value":"shoujo-ai"},{"label":"Shounen","value":"shounen"},{"label":"Shounen Ai","value":"shounen-ai"},{"label":"Slice of Life","value":"slice-of-life"},{"label":"Smut","value":"smut"},{"label":"Soft Yaoi","value":"soft-yaoi"},{"label":"Soft Yuri","value":"soft-yuri"},{"label":"Sports","value":"sports"},{"label":"Supernatural","value":"supernatural"},{"label":"Tragedy","value":"tragedy"},{"label":"Translation","value":"translation"},{"label":"Webtoon","value":"webtoon"},{"label":"Wuxia","value":"wuxia"},{"label":"Xianxia","value":"xianxia"},{"label":"Xuanhuan","value":"xuanhuan"},{"label":"Yaoi","value":"yaoi"},{"label":"Yuri","value":"yuri"}],"inputType":"Picker"}],"options":{"lang":"English"}}); +export default plugin; + \ No newline at end of file diff --git a/plugins/english/NovelOnline.ts b/plugins/english/NovelOnline.broken.ts similarity index 100% rename from plugins/english/NovelOnline.ts rename to plugins/english/NovelOnline.broken.ts diff --git a/plugins/english/NovelR18[madara].ts b/plugins/english/NovelR18[madara].ts index 14937f5..f7e0db5 100644 --- a/plugins/english/NovelR18[madara].ts +++ b/plugins/english/NovelR18[madara].ts @@ -1,213 +1,252 @@ +import { fetchApi, fetchFile } from "@libs/fetch"; +import { Filter } from "@libs/filterInputs"; +import { Plugin } from '@typings/plugin' import { load as parseHTML } from "cheerio"; -import { fetchFile, fetchApi } from "@libs/fetch"; -import { Novel, Plugin, Chapter } from "@typings/plugin"; -import { FilterInputs } from "@libs/filterInputs"; import { defaultCover } from "@libs/defaultCover"; -import { NovelStatus } from "@libs/novelStatus" +import { NovelStatus } from "@libs/novelStatus"; import { parseMadaraDate } from "@libs/parseMadaraDate"; import dayjs from "dayjs"; -export const id = "novelr18"; -export const name = "NovelR18 [madara]"; -export const icon = "multisrc/madara/icons/novelr18.png"; -export const version = "1.0.0"; -export const site = "https://novelr18.com/"; -const baseUrl = site; +interface MadaraOptionPath{ + genres?: string, + novels?: string, + novel?: string, + chapter?: string, +} -export const popularNovels: Plugin.popularNovels = async (pageNo, {filters, showLatestNovels}) => { - const novels: Novel.Item[] = []; +const MadaraDefaultPath: MadaraOptionPath = { + novels: 'novel', + novel: 'novel', + chapter: 'novel' +} - let url = site; +interface MadaraOptions { + useNewChapterEndpoint?: boolean, + path?: MadaraOptionPath, + lang?: string, + orderBy?: string +} - if (filters?.genres) { - url += "novel-genre/" + filters.genres + '/'; - } else { - url += "novel/"; +export interface MadaraMetadata { + id: string, + sourceSite: string, + sourceName: string, + options?: MadaraOptions, + filters?: Filter[], +} +class MadaraPlugin implements Plugin.PluginBase { + id: string; + name: string; + icon: string; + site: string; + version: string; + userAgent: string; + cookieString: string; + options?: MadaraOptions; + filter?: Filter[] | undefined; + + constructor(metadata: MadaraMetadata){ + this.id = metadata.id; + this.name = metadata.sourceName + "[madara]"; + const iconFileName = metadata.sourceName.replace(/\s+/g, "").toLowerCase(); + this.icon = `multisrc/madara/icons/${iconFileName}.png`; + this.site = metadata.sourceSite; + this.version = "1.0.0"; + this.userAgent = ""; + this.cookieString = ""; + this.options = metadata.options; + this.filter = metadata.filters; } + async popularNovels(pageNo: number, {filters, showLatestNovels}: Plugin.PopularNovelsOptions): Promise { + const novels: Plugin.NovelItem[] = []; - url += '/page/' + pageNo + '/' + - '?m_orderby=' + (showLatestNovels ? 'latest' : (filters?.sort || 'rating')); - - const body = await fetchApi(url).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - - loadedCheerio('.manga-title-badges').remove(); - - loadedCheerio('.page-item-detail').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - - let novelUrl = loadedCheerio(this).find('.post-title') - .find('a') - .attr('href') || ''; - const novel: Novel.Item = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - - novels.push(novel); - }); - - return novels; -}; - -export const parseNovelAndChapters: Plugin.parseNovelAndChapters = async ( - novelUrl -) => { - const novel: Novel.instance = { - url: novelUrl, - }; - - const body = await fetchApi(novelUrl).then(res => res.text()); - - let loadedCheerio = parseHTML(body); - - loadedCheerio('.manga-title-badges').remove(); - - novel.name = loadedCheerio('.post-title h1').text().trim(); - - novel.cover = - loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || - loadedCheerio('.summary_image > a > img').attr('data-src') || - loadedCheerio('.summary_image > a > img').attr('src') || - defaultCover; - - loadedCheerio('.post-content_item, .post-content').each(function () { - const detailName = loadedCheerio(this).find('h5').text().trim(); - const detail = loadedCheerio(this).find('.summary-content').text().trim(); - - switch (detailName) { - case 'Genre(s)': - case 'التصنيفات': - novel.genres = detail.replace(/[\t\n]/g, ','); - break; - case 'Author(s)': - case 'المؤلف': - case 'المؤلف (ين)': - novel.author = detail; - break; - case 'Status': - case 'الحالة': - novel.status = - detail.includes('OnGoing') || detail.includes('مستمرة') - ? NovelStatus.Ongoing - : NovelStatus.Completed; - break; - } - }); - - loadedCheerio('div.summary__content .code-block,script').remove(); - novel.summary = loadedCheerio('div.summary__content').text().trim(); - - - let html; - - if (true) { - const novelId = - loadedCheerio('.rating-post-id').attr('value') || - loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; - - const body = { - action: "manga_get_chapters", - manga: novelId, - } - html = await fetchApi( - baseUrl + 'wp-admin/admin-ajax.php', - { - method: 'POST', - body: JSON.stringify(body), - }) - .then(res => res.text()); - } else { - html = await fetchApi( - baseUrl + 'ajax/chapters/', - { method: 'POST' }) - .then(res => res.text()); - } - - if (html !== '0') { - loadedCheerio = parseHTML(html); - } - - const chapters: Chapter.Item[] = []; - loadedCheerio('.wp-manga-chapter').each(function () { - const chapterName = loadedCheerio(this).find('a').text().trim(); - - let releaseDate = null; - releaseDate = loadedCheerio(this) - .find('span.chapter-release-date') - .text() - .trim(); - - if (releaseDate) { - releaseDate = parseMadaraDate(releaseDate); + let url = this.site; + if (filters?.genres && this.options?.path?.genres) { + url += this.options?.path?.genres + filters.genres + '/'; } else { - /** - * Insert current date - */ - - releaseDate = dayjs().format('LL'); + url += this.options?.path?.novels ? this.options.path.novels : MadaraDefaultPath.novels; } + + url += '/page/' + pageNo + '/' + + '?m_orderby=' + (showLatestNovels ? 'latest' : (filters?.sort || 'rating')); + + const body = await fetchApi(url).then(res => res.text()); + + const loadedCheerio = parseHTML(body); + + loadedCheerio('.manga-title-badges').remove(); + + loadedCheerio('.page-item-detail').each(function () { + const novelName = loadedCheerio(this).find('.post-title').text().trim(); + let image = loadedCheerio(this).find('img'); + const novelCover = image.attr('data-src') || image.attr('src'); + + let novelUrl = loadedCheerio(this).find('.post-title') + .find('a') + .attr('href') || ''; + const novel: Plugin.NovelItem = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + + novels.push(novel); + }); + + return novels; + } + async parseNovelAndChapters(novelUrl: string): Promise { + const novel: Plugin.SourceNovel = { + url: novelUrl, + }; + + const body = await fetchApi(novelUrl).then(res => res.text()); + + let loadedCheerio = parseHTML(body); + + loadedCheerio('.manga-title-badges, #manga-title span').remove(); + novel.name = + loadedCheerio('.post-title h1').text().trim() || + loadedCheerio('#manga-title h1').text(); + + novel.cover = + loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || + loadedCheerio('.summary_image > a > img').attr('data-src') || + loadedCheerio('.summary_image > a > img').attr('src') || + defaultCover; + + loadedCheerio('.post-content_item, .post-content').each(function () { + const detailName = loadedCheerio(this).find('h5').text().trim(); + const detail = loadedCheerio(this).find('.summary-content').text().trim(); + + switch (detailName) { + case 'Genre(s)': + case 'التصنيفات': + novel.genres = detail.replace(/[\\t\\n]/g, ','); + break; + case 'Author(s)': + case 'المؤلف': + case 'المؤلف (ين)': + novel.author = detail; + break; + case 'Status': + case 'الحالة': + novel.status = + detail.includes('OnGoing') || detail.includes('مستمرة') + ? NovelStatus.Ongoing + : NovelStatus.Completed; + break; + } + }); + + loadedCheerio('div.summary__content .code-block,script').remove(); + novel.summary = + loadedCheerio('div.summary__content').text().trim() || + loadedCheerio('#tab-manga-about').text().trim() || + loadedCheerio('.post-content_item h5:contains("Summary")').next().text().trim(); + + let html; + + if (this.options?.useNewChapterEndpoint !== true) { + const novelId = + loadedCheerio('.rating-post-id').attr('value') || + loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; + + const formData = new FormData() + formData.append("action", "manga_get_chapters"); + formData.append("manga", novelId); - let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + html = await fetchApi( + this.site + 'wp-admin/admin-ajax.php', + { + method: 'POST', + body: formData, + }) + .then(res => res.text()); + } else { + html = await fetchApi( + novelUrl + 'ajax/chapters/', + { method: 'POST' }) + .then(res => res.text()); + } + + if (html !== '0') { + loadedCheerio = parseHTML(html); + } + + const chapters: Plugin.ChapterItem[] = []; + loadedCheerio('.wp-manga-chapter').each(function () { + const chapterName = loadedCheerio(this).find('a').text().trim(); + + let releaseDate = null; + releaseDate = loadedCheerio(this) + .find('span.chapter-release-date') + .text() + .trim(); + + if (releaseDate) { + releaseDate = parseMadaraDate(releaseDate); + } else { + /** + * Insert current date + */ + + releaseDate = dayjs().format('LL'); + } + + let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + + chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); + }); + + novel.chapters = chapters.reverse(); + return novel; + } + async parseChapter(chapterUrl: string): Promise { + const body = await fetchApi(chapterUrl).then(res => res.text()); - chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); - }); + const loadedCheerio = parseHTML(body); + const chapterText = + loadedCheerio('.text-left').html() || + loadedCheerio('.text-right').html() || + loadedCheerio('.entry-content').html() || ""; - novel.chapters = chapters.reverse(); - return novel; -}; - -export const parseChapter: Plugin.parseChapter = async (chapterUrl) => { - const url = baseUrl + "/" + "manga" + "/" + chapterUrl; - - const body = await fetchApi(chapterUrl).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - const chapterText = - loadedCheerio('.text-left').html() || - loadedCheerio('.text-right').html() || - loadedCheerio('.entry-content').html(); - - return chapterText; -}; - -export const searchNovels: Plugin.searchNovels = async (searchTerm) => { - const novels: Novel.Item[] = []; - const url = baseUrl + "?s=" + searchTerm + "&post_type=wp-manga"; - - const body = await fetchApi(url).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - - - loadedCheerio('.c-tabs-item__content').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - - let novelUrl = loadedCheerio(this) - .find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - - novels.push(novel); - }); - return novels; -}; - -export const fetchImage: Plugin.fetchImage = async (url) => { - return await fetchFile(url); -}; - -export const filters = [{"key":"sort","label":"Sort by :","values":[{"label":"Rating","value":"rating"},{"label":"A-Z","value":"alphabet"},{"label":"Latest Update","value":"latest"},{"label":"Most Views","value":"views"},{"label":"Newly Added Novels","value":"new-manga"},{"label":"Trending","value":"trending"}],"inputType":FilterInputs.Picker}]; \ No newline at end of file + return chapterText; + } + async searchNovels(searchTerm: string, pageNo?: number | undefined): Promise { + const novels: Plugin.NovelItem[] = []; + const url = this.site + "?s=" + searchTerm + "&post_type=wp-manga"; + + const body = await fetchApi(url).then(res => res.text()); + + const loadedCheerio = parseHTML(body); + + + loadedCheerio('.c-tabs-item__content').each(function () { + const novelName = loadedCheerio(this).find('.post-title').text().trim(); + + let image = loadedCheerio(this).find('img'); + const novelCover = image.attr('data-src') || image.attr('src'); + + let novelUrl = loadedCheerio(this) + .find('.post-title') + .find('a') + .attr('href') || ''; + const novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + + novels.push(novel); + }); + return novels; + } + async fetchImage(url: string): Promise { + return await fetchFile(url, {}); + } +} +const plugin = new MadaraPlugin({"id":"novelr18","sourceSite":"https://novelr18.com/","sourceName":"NovelR18","filters":[{"key":"sort","label":"Sort by :","values":[{"label":"Rating","value":"rating"},{"label":"A-Z","value":"alphabet"},{"label":"Latest Update","value":"latest"},{"label":"Most Views","value":"views"},{"label":"Newly Added Novels","value":"new-manga"},{"label":"Trending","value":"trending"}],"inputType":"Picker"}],"options":{"path":{"novels":"novel","novel":"manga","chapter":"manga"},"useNewChapterEndpoint":true,"lang":"English"}}); +export default plugin; + \ No newline at end of file diff --git a/plugins/english/NovelTranslate[madara].ts b/plugins/english/NovelTranslate[madara].ts index 0fb49f9..efa9572 100644 --- a/plugins/english/NovelTranslate[madara].ts +++ b/plugins/english/NovelTranslate[madara].ts @@ -1,213 +1,252 @@ +import { fetchApi, fetchFile } from "@libs/fetch"; +import { Filter } from "@libs/filterInputs"; +import { Plugin } from '@typings/plugin' import { load as parseHTML } from "cheerio"; -import { fetchFile, fetchApi } from "@libs/fetch"; -import { Novel, Plugin, Chapter } from "@typings/plugin"; -import { FilterInputs } from "@libs/filterInputs"; import { defaultCover } from "@libs/defaultCover"; -import { NovelStatus } from "@libs/novelStatus" +import { NovelStatus } from "@libs/novelStatus"; import { parseMadaraDate } from "@libs/parseMadaraDate"; import dayjs from "dayjs"; -export const id = "novelTL"; -export const name = "NovelTranslate [madara]"; -export const icon = "multisrc/madara/icons/noveltranslate.png"; -export const version = "1.0.0"; -export const site = "https://noveltranslate.com/"; -const baseUrl = site; +interface MadaraOptionPath{ + genres?: string, + novels?: string, + novel?: string, + chapter?: string, +} -export const popularNovels: Plugin.popularNovels = async (pageNo, {filters, showLatestNovels}) => { - const novels: Novel.Item[] = []; +const MadaraDefaultPath: MadaraOptionPath = { + novels: 'novel', + novel: 'novel', + chapter: 'novel' +} - let url = site; +interface MadaraOptions { + useNewChapterEndpoint?: boolean, + path?: MadaraOptionPath, + lang?: string, + orderBy?: string +} - if (filters?.genres) { - url += "manga-genre/" + filters.genres + '/'; - } else { - url += "all-novels/"; +export interface MadaraMetadata { + id: string, + sourceSite: string, + sourceName: string, + options?: MadaraOptions, + filters?: Filter[], +} +class MadaraPlugin implements Plugin.PluginBase { + id: string; + name: string; + icon: string; + site: string; + version: string; + userAgent: string; + cookieString: string; + options?: MadaraOptions; + filter?: Filter[] | undefined; + + constructor(metadata: MadaraMetadata){ + this.id = metadata.id; + this.name = metadata.sourceName + "[madara]"; + const iconFileName = metadata.sourceName.replace(/\s+/g, "").toLowerCase(); + this.icon = `multisrc/madara/icons/${iconFileName}.png`; + this.site = metadata.sourceSite; + this.version = "1.0.0"; + this.userAgent = ""; + this.cookieString = ""; + this.options = metadata.options; + this.filter = metadata.filters; } + async popularNovels(pageNo: number, {filters, showLatestNovels}: Plugin.PopularNovelsOptions): Promise { + const novels: Plugin.NovelItem[] = []; - url += '/page/' + pageNo + '/' + - '?m_orderby=' + (showLatestNovels ? 'latest' : (filters?.sort || 'rating')); - - const body = await fetchApi(url).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - - loadedCheerio('.manga-title-badges').remove(); - - loadedCheerio('.page-item-detail').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - - let novelUrl = loadedCheerio(this).find('.post-title') - .find('a') - .attr('href') || ''; - const novel: Novel.Item = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - - novels.push(novel); - }); - - return novels; -}; - -export const parseNovelAndChapters: Plugin.parseNovelAndChapters = async ( - novelUrl -) => { - const novel: Novel.instance = { - url: novelUrl, - }; - - const body = await fetchApi(novelUrl).then(res => res.text()); - - let loadedCheerio = parseHTML(body); - - loadedCheerio('.manga-title-badges').remove(); - - novel.name = loadedCheerio('.post-title h1').text().trim(); - - novel.cover = - loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || - loadedCheerio('.summary_image > a > img').attr('data-src') || - loadedCheerio('.summary_image > a > img').attr('src') || - defaultCover; - - loadedCheerio('.post-content_item, .post-content').each(function () { - const detailName = loadedCheerio(this).find('h5').text().trim(); - const detail = loadedCheerio(this).find('.summary-content').text().trim(); - - switch (detailName) { - case 'Genre(s)': - case 'التصنيفات': - novel.genres = detail.replace(/[\t\n]/g, ','); - break; - case 'Author(s)': - case 'المؤلف': - case 'المؤلف (ين)': - novel.author = detail; - break; - case 'Status': - case 'الحالة': - novel.status = - detail.includes('OnGoing') || detail.includes('مستمرة') - ? NovelStatus.Ongoing - : NovelStatus.Completed; - break; - } - }); - - loadedCheerio('div.summary__content .code-block,script').remove(); - novel.summary = loadedCheerio('div.summary__content').text().trim(); - - - let html; - - if (false) { - const novelId = - loadedCheerio('.rating-post-id').attr('value') || - loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; - - const body = { - action: "manga_get_chapters", - manga: novelId, - } - html = await fetchApi( - baseUrl + 'wp-admin/admin-ajax.php', - { - method: 'POST', - body: JSON.stringify(body), - }) - .then(res => res.text()); - } else { - html = await fetchApi( - baseUrl + 'ajax/chapters/', - { method: 'POST' }) - .then(res => res.text()); - } - - if (html !== '0') { - loadedCheerio = parseHTML(html); - } - - const chapters: Chapter.Item[] = []; - loadedCheerio('.wp-manga-chapter').each(function () { - const chapterName = loadedCheerio(this).find('a').text().trim(); - - let releaseDate = null; - releaseDate = loadedCheerio(this) - .find('span.chapter-release-date') - .text() - .trim(); - - if (releaseDate) { - releaseDate = parseMadaraDate(releaseDate); + let url = this.site; + if (filters?.genres && this.options?.path?.genres) { + url += this.options?.path?.genres + filters.genres + '/'; } else { - /** - * Insert current date - */ - - releaseDate = dayjs().format('LL'); + url += this.options?.path?.novels ? this.options.path.novels : MadaraDefaultPath.novels; } + + url += '/page/' + pageNo + '/' + + '?m_orderby=' + (showLatestNovels ? 'latest' : (filters?.sort || 'rating')); + + const body = await fetchApi(url).then(res => res.text()); + + const loadedCheerio = parseHTML(body); + + loadedCheerio('.manga-title-badges').remove(); + + loadedCheerio('.page-item-detail').each(function () { + const novelName = loadedCheerio(this).find('.post-title').text().trim(); + let image = loadedCheerio(this).find('img'); + const novelCover = image.attr('data-src') || image.attr('src'); + + let novelUrl = loadedCheerio(this).find('.post-title') + .find('a') + .attr('href') || ''; + const novel: Plugin.NovelItem = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + + novels.push(novel); + }); + + return novels; + } + async parseNovelAndChapters(novelUrl: string): Promise { + const novel: Plugin.SourceNovel = { + url: novelUrl, + }; + + const body = await fetchApi(novelUrl).then(res => res.text()); + + let loadedCheerio = parseHTML(body); + + loadedCheerio('.manga-title-badges, #manga-title span').remove(); + novel.name = + loadedCheerio('.post-title h1').text().trim() || + loadedCheerio('#manga-title h1').text(); + + novel.cover = + loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || + loadedCheerio('.summary_image > a > img').attr('data-src') || + loadedCheerio('.summary_image > a > img').attr('src') || + defaultCover; + + loadedCheerio('.post-content_item, .post-content').each(function () { + const detailName = loadedCheerio(this).find('h5').text().trim(); + const detail = loadedCheerio(this).find('.summary-content').text().trim(); + + switch (detailName) { + case 'Genre(s)': + case 'التصنيفات': + novel.genres = detail.replace(/[\\t\\n]/g, ','); + break; + case 'Author(s)': + case 'المؤلف': + case 'المؤلف (ين)': + novel.author = detail; + break; + case 'Status': + case 'الحالة': + novel.status = + detail.includes('OnGoing') || detail.includes('مستمرة') + ? NovelStatus.Ongoing + : NovelStatus.Completed; + break; + } + }); + + loadedCheerio('div.summary__content .code-block,script').remove(); + novel.summary = + loadedCheerio('div.summary__content').text().trim() || + loadedCheerio('#tab-manga-about').text().trim() || + loadedCheerio('.post-content_item h5:contains("Summary")').next().text().trim(); + + let html; + + if (this.options?.useNewChapterEndpoint !== true) { + const novelId = + loadedCheerio('.rating-post-id').attr('value') || + loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; + + const formData = new FormData() + formData.append("action", "manga_get_chapters"); + formData.append("manga", novelId); - let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + html = await fetchApi( + this.site + 'wp-admin/admin-ajax.php', + { + method: 'POST', + body: formData, + }) + .then(res => res.text()); + } else { + html = await fetchApi( + novelUrl + 'ajax/chapters/', + { method: 'POST' }) + .then(res => res.text()); + } + + if (html !== '0') { + loadedCheerio = parseHTML(html); + } + + const chapters: Plugin.ChapterItem[] = []; + loadedCheerio('.wp-manga-chapter').each(function () { + const chapterName = loadedCheerio(this).find('a').text().trim(); + + let releaseDate = null; + releaseDate = loadedCheerio(this) + .find('span.chapter-release-date') + .text() + .trim(); + + if (releaseDate) { + releaseDate = parseMadaraDate(releaseDate); + } else { + /** + * Insert current date + */ + + releaseDate = dayjs().format('LL'); + } + + let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + + chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); + }); + + novel.chapters = chapters.reverse(); + return novel; + } + async parseChapter(chapterUrl: string): Promise { + const body = await fetchApi(chapterUrl).then(res => res.text()); - chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); - }); + const loadedCheerio = parseHTML(body); + const chapterText = + loadedCheerio('.text-left').html() || + loadedCheerio('.text-right').html() || + loadedCheerio('.entry-content').html() || ""; - novel.chapters = chapters.reverse(); - return novel; -}; - -export const parseChapter: Plugin.parseChapter = async (chapterUrl) => { - const url = baseUrl + "/" + "manga" + "/" + chapterUrl; - - const body = await fetchApi(chapterUrl).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - const chapterText = - loadedCheerio('.text-left').html() || - loadedCheerio('.text-right').html() || - loadedCheerio('.entry-content').html(); - - return chapterText; -}; - -export const searchNovels: Plugin.searchNovels = async (searchTerm) => { - const novels: Novel.Item[] = []; - const url = baseUrl + "?s=" + searchTerm + "&post_type=wp-manga"; - - const body = await fetchApi(url).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - - - loadedCheerio('.c-tabs-item__content').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - - let novelUrl = loadedCheerio(this) - .find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - - novels.push(novel); - }); - return novels; -}; - -export const fetchImage: Plugin.fetchImage = async (url) => { - return await fetchFile(url); -}; - -export const filters = [{"key":"sort","label":"Order by","values":[{"label":"Rating","value":"rating"},{"label":"A-Z","value":"alphabet"},{"label":"Latest","value":"latest"},{"label":"Most Views","value":"views"},{"label":"New","value":"new-manga"},{"label":"Trending","value":"trending"}],"inputType":FilterInputs.Picker},{"key":"genres","label":"GENRES","values":[{"label":"Action","value":"action"},{"label":"Adult","value":"adult"},{"label":"Adventure","value":"adventure"},{"label":"Bleach","value":"bleach"},{"label":"Chinese","value":"chinese"},{"label":"Comedy","value":"comedy"},{"label":"Conan","value":"conan"},{"label":"cooking","value":"cooking"},{"label":"Dragon Ball","value":"dragon-ball"},{"label":"Drama","value":"drama"},{"label":"Ecchi","value":"ecchi"},{"label":"Erciyuan","value":"erciyuan"},{"label":"Fairy Tail","value":"fairy-tail"},{"label":"Faloo","value":"faloo"},{"label":"Fan-Fiction","value":"fan-fiction"},{"label":"Fantasy","value":"fantasy"},{"label":"FoodWars!","value":"foodwars"},{"label":"Game","value":"game"},{"label":"Gender Bender","value":"gender-bender"},{"label":"Harem","value":"harem"},{"label":"Historical","value":"historical"},{"label":"Horror","value":"horror"},{"label":"Hunter x Hunter","value":"hunter-x-hunter"},{"label":"Isekai","value":"isekai"},{"label":"Japanese","value":"japanese"},{"label":"Jojo","value":"jojo"},{"label":"Josei","value":"josei"},{"label":"Korean","value":"korean"},{"label":"Martial Arts","value":"martial-arts"},{"label":"Marvel","value":"marvel"},{"label":"Mature","value":"mature"},{"label":"Mecha","value":"mecha"},{"label":"Military","value":"military"},{"label":"Mystery","value":"mystery"},{"label":"Naruto","value":"naruto"},{"label":"One piece","value":"one-piece"},{"label":"Pokemon","value":"pokemon"},{"label":"Political","value":"political"},{"label":"Psychological","value":"psychological"},{"label":"Romance","value":"romance"},{"label":"School Life","value":"school-life"},{"label":"Sci-fi","value":"sci-fi"},{"label":"Seinen","value":"seinen"},{"label":"Shoujo","value":"shoujo"},{"label":"Shoujo Ai","value":"shoujo-ai"},{"label":"Shounen","value":"shounen"},{"label":"Shounen Ai","value":"shounen-ai"},{"label":"Slice of Life","value":"slice-of-life"},{"label":"Smut","value":"smut"},{"label":"Sport","value":"sport"},{"label":"Sports","value":"sports"},{"label":"Supernatural","value":"supernatural"},{"label":"System","value":"system"},{"label":"Toriko","value":"toriko"},{"label":"Tragedy","value":"tragedy"},{"label":"Urban","value":"urban"},{"label":"Urban Life","value":"urban-life"},{"label":"Wuxia","value":"wuxia"},{"label":"Xianxia","value":"xianxia"},{"label":"Xuanhuan","value":"xuanhuan"},{"label":"Yaoi","value":"yaoi"},{"label":"Yuri","value":"yuri"}],"inputType":FilterInputs.Picker}]; \ No newline at end of file + return chapterText; + } + async searchNovels(searchTerm: string, pageNo?: number | undefined): Promise { + const novels: Plugin.NovelItem[] = []; + const url = this.site + "?s=" + searchTerm + "&post_type=wp-manga"; + + const body = await fetchApi(url).then(res => res.text()); + + const loadedCheerio = parseHTML(body); + + + loadedCheerio('.c-tabs-item__content').each(function () { + const novelName = loadedCheerio(this).find('.post-title').text().trim(); + + let image = loadedCheerio(this).find('img'); + const novelCover = image.attr('data-src') || image.attr('src'); + + let novelUrl = loadedCheerio(this) + .find('.post-title') + .find('a') + .attr('href') || ''; + const novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + + novels.push(novel); + }); + return novels; + } + async fetchImage(url: string): Promise { + return await fetchFile(url, {}); + } +} +const plugin = new MadaraPlugin({"id":"novelTL","sourceSite":"https://noveltranslate.com/","sourceName":"NovelTranslate","filters":[{"key":"sort","label":"Order by","values":[{"label":"Rating","value":"rating"},{"label":"A-Z","value":"alphabet"},{"label":"Latest","value":"latest"},{"label":"Most Views","value":"views"},{"label":"New","value":"new-manga"},{"label":"Trending","value":"trending"}],"inputType":"Picker"},{"key":"genres","label":"GENRES","values":[{"label":"Action","value":"action"},{"label":"Adult","value":"adult"},{"label":"Adventure","value":"adventure"},{"label":"Bleach","value":"bleach"},{"label":"Chinese","value":"chinese"},{"label":"Comedy","value":"comedy"},{"label":"Conan","value":"conan"},{"label":"cooking","value":"cooking"},{"label":"Dragon Ball","value":"dragon-ball"},{"label":"Drama","value":"drama"},{"label":"Ecchi","value":"ecchi"},{"label":"Erciyuan","value":"erciyuan"},{"label":"Fairy Tail","value":"fairy-tail"},{"label":"Faloo","value":"faloo"},{"label":"Fan-Fiction","value":"fan-fiction"},{"label":"Fantasy","value":"fantasy"},{"label":"FoodWars!","value":"foodwars"},{"label":"Game","value":"game"},{"label":"Gender Bender","value":"gender-bender"},{"label":"Harem","value":"harem"},{"label":"Historical","value":"historical"},{"label":"Horror","value":"horror"},{"label":"Hunter x Hunter","value":"hunter-x-hunter"},{"label":"Isekai","value":"isekai"},{"label":"Japanese","value":"japanese"},{"label":"Jojo","value":"jojo"},{"label":"Josei","value":"josei"},{"label":"Korean","value":"korean"},{"label":"Martial Arts","value":"martial-arts"},{"label":"Marvel","value":"marvel"},{"label":"Mature","value":"mature"},{"label":"Mecha","value":"mecha"},{"label":"Military","value":"military"},{"label":"Mystery","value":"mystery"},{"label":"Naruto","value":"naruto"},{"label":"One piece","value":"one-piece"},{"label":"Pokemon","value":"pokemon"},{"label":"Political","value":"political"},{"label":"Psychological","value":"psychological"},{"label":"Romance","value":"romance"},{"label":"School Life","value":"school-life"},{"label":"Sci-fi","value":"sci-fi"},{"label":"Seinen","value":"seinen"},{"label":"Shoujo","value":"shoujo"},{"label":"Shoujo Ai","value":"shoujo-ai"},{"label":"Shounen","value":"shounen"},{"label":"Shounen Ai","value":"shounen-ai"},{"label":"Slice of Life","value":"slice-of-life"},{"label":"Smut","value":"smut"},{"label":"Sport","value":"sport"},{"label":"Sports","value":"sports"},{"label":"Supernatural","value":"supernatural"},{"label":"System","value":"system"},{"label":"Toriko","value":"toriko"},{"label":"Tragedy","value":"tragedy"},{"label":"Urban","value":"urban"},{"label":"Urban Life","value":"urban-life"},{"label":"Wuxia","value":"wuxia"},{"label":"Xianxia","value":"xianxia"},{"label":"Xuanhuan","value":"xuanhuan"},{"label":"Yaoi","value":"yaoi"},{"label":"Yuri","value":"yuri"}],"inputType":"Picker"}],"options":{"path":{"novels":"all-novels","novel":"manga","chapter":"manga","genres":"manga-genre"},"lang":"English"}}); +export default plugin; + \ No newline at end of file diff --git a/plugins/english/Novelmtcom[readwn].ts b/plugins/english/Novelmtcom[readwn].ts deleted file mode 100644 index 9cdce91..0000000 --- a/plugins/english/Novelmtcom[readwn].ts +++ /dev/null @@ -1,195 +0,0 @@ - -import { load as parseHTML } from "cheerio"; -// import dayjs from 'dayjs'; -import { fetchFile, fetchApi } from "@libs/fetch"; -import { Novel, Plugin, Chapter } from "@typings/plugin"; -import { parseMadaraDate } from "@libs/parseMadaraDate"; -// import { isUrlAbsolute } from '@libs/isAbsoluteUrl'; -// import { showToast } from "@libs/showToast"; -import { FilterInputs } from "@libs/filterInputs"; -// import { NovelStatus } from '@libs/novelStatus'; -// import { defaultCover } from "@libs/defaultCover"; - -export const id = "Novelmt.com"; -export const name = "Novelmt.com"; -export const icon = "multisrc/readwn/icons/novelmt.png"; -export const version = "1.0.0"; -export const site = "https://www.novelmt.com/"; - -export const popularNovels: Plugin.popularNovels = async function ( - page, - { filters, showLatestNovels } -) { - const novels: Novel.Item[] = []; - const pageNo = page - 1; - - let url = site + 'list/'; - url += (filters?.genres || 'all') + '/'; - url += (filters?.status || 'all') + '-'; - url += (showLatestNovels ? 'lastdotime' : filters?.sort || 'newstime') + '-'; - url += pageNo + '.html'; - - const result = await fetchApi(url); - const body = await result.text(); - - const loadedCheerio = parseHTML(body); - - - loadedCheerio('li.novel-item').each(function () { - const novelName = loadedCheerio(this).find('h4').text(); - const novelUrl = site + loadedCheerio(this).find('a').attr('href'); - - const coverUri = loadedCheerio(this) - .find('.novel-cover > img') - .attr('data-src'); - - const novelCover = site + coverUri; - - const novel = { name: novelName, cover: novelCover, url: novelUrl }; - - novels.push(novel); - }); - - return novels; -}; - - -export const parseNovelAndChapters: Plugin.parseNovelAndChapters = - async function (novelUrl) { - const result = await fetchApi(novelUrl); - const body = await result.text(); - - let loadedCheerio = parseHTML(body); - - const novel: Novel.instance = { - url: novelUrl, - chapters: [], - }; - - novel.name = loadedCheerio('h1.novel-title').text(); - - const coverUri = loadedCheerio('figure.cover > img').attr('data-src'); - novel.cover = site + coverUri; - - novel.summary = loadedCheerio('.summary') - .text() - .replace('Summary', '') - .trim(); - - novel.genres = ''; - - loadedCheerio('div.categories > ul > li').each(function () { - novel.genres += loadedCheerio(this).text().trim() + ','; - }); - - loadedCheerio('div.header-stats > span').each(function () { - if (loadedCheerio(this).find('small').text() === 'Status') { - novel.status = loadedCheerio(this).find('strong').text(); - } - }); - - novel.genres = novel.genres.slice(0, -1); - - novel.author = loadedCheerio('span[itemprop=author]').text(); - - let novelChapters: Chapter.Item[] = []; - - const novelId = novelUrl.replace('.html', '').replace(site, ''); - - const latestChapterNo = parseInt(loadedCheerio('.header-stats') - .find('span > strong') - .first() - .text() - .trim()); - - let lastChapterNo = 1; - loadedCheerio('.chapter-list li').each(function () { - const chapterName = loadedCheerio(this) - .find('a .chapter-title') - .text() - .trim(); - - const chapterUrl = site + loadedCheerio(this).find('a').attr('href')?.trim(); - - const releaseDate = loadedCheerio(this) - .find('a .chapter-update') - .text() - .trim(); - - lastChapterNo = parseInt(loadedCheerio(this).find('a .chapter-no').text().trim()); - - const chapter = { name: chapterName, releaseTime: parseMadaraDate(releaseDate), url: chapterUrl }; - - novelChapters.push(chapter); - }); - - // Itterate once more before loop to finish off - lastChapterNo++; - for (let i = lastChapterNo; i <= latestChapterNo; i++) { - const chapterName = 'Chapter ' + i; - const chapterUrl = site + novelId+'_'+ i +'.html'; - const releaseDate = null; - - const chapter = { name: chapterName, releaseTime: releaseDate,url: chapterUrl }; - - novelChapters.push(chapter); - } - - novel.chapters = novelChapters; - return novel; - }; - -export const parseChapter: Plugin.parseChapter = async function (chapterUrl) { - const result = await fetchApi(chapterUrl); - const body = await result.text(); - - const loadedCheerio = parseHTML(body); - - const chapterText = loadedCheerio('.chapter-content').html(); - return chapterText; -}; - -export const searchNovels: Plugin.searchNovels = async (searchTerm) => { - const novels: Novel.Item[] = []; - const searchUrl = site + 'e/search/index.php'; - - const result = await fetchApi(searchUrl, { - headers: { - 'Content-Type': 'application/x-www-form-urlencoded', - Referer: site + 'search.html', - Origin: site, - 'user-agent': - 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36', - }, - method: 'POST', - body: JSON.stringify({ - show: 'title', - tempid: 1, - tbname: 'news', - keyboard: searchTerm, - }), - }); - const body = await result.text(); - - const loadedCheerio = parseHTML(body); - - loadedCheerio('li.novel-item').each(function () { - const novelName = loadedCheerio(this).find('h4').text(); - const novelUrl = site + loadedCheerio(this).find('a').attr('href'); - - const coverUri = site + loadedCheerio(this).find('img').attr('data-src'); - const novelCover = site + coverUri; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - - novels.push(novel); - }); - return novels; -}; - -export const fetchImage: Plugin.fetchImage = fetchFile; - -export const filters = [{"key":"sort","label":"Sort By","values":[{"label":"New","value":"newstime"},{"label":"Popular","value":"onclick"},{"label":"Updates","value":"lastdotime"}], "inputType":FilterInputs.Picker},{"key":"status","label":"Status","values":[{"label":"All","value":"all"},{"label":"Completed","value":"Completed"},{"label":"Ongoing","value":"Ongoing"}], "inputType":FilterInputs.Picker},{"key":"genres","label":"Genre / Category","values":[{"label":"All","value":"all"},{"label":"Action","value":"action"},{"label":"Adult","value":"adult"},{"label":"Adventure","value":"adventure"},{"label":"Billionaire","value":"billionaire"},{"label":"CEO","value":"ceo"},{"label":"Chinese","value":"chinese"},{"label":"Comedy","value":"comedy"},{"label":"Contemporary Romance","value":"contemporary-romance"},{"label":"Drama","value":"drama"},{"label":"Eastern Fantasy","value":"eastern-fantasy"},{"label":"Ecchi","value":"ecchi"},{"label":"Erciyuan","value":"erciyuan"},{"label":"Faloo","value":"faloo"},{"label":"Fan-Fiction","value":"fan-fiction"},{"label":"Fantasy","value":"fantasy"},{"label":"Fantasy Romance","value":"fantasy-romance"},{"label":"Farming","value":"farming"},{"label":"Game","value":"game"},{"label":"Games","value":"games"},{"label":"Gay Romance","value":"gay-romance"},{"label":"Gender Bender","value":"gender-bender"},{"label":"Harem","value":"harem"},{"label":"Historical","value":"historical"},{"label":"Historical Romance","value":"historical-romance"},{"label":"Horror","value":"horror"},{"label":"Isekai","value":"isekai"},{"label":"Japanese","value":"japanese"},{"label":"Josei","value":"josei"},{"label":"Korean","value":"korean"},{"label":"Lolicon","value":"lolicon"},{"label":"Magic","value":"magic"},{"label":"Magical Realism","value":"magical-realism"},{"label":"Martial Arts","value":"martial-arts"},{"label":"Mature","value":"mature"},{"label":"Mecha","value":"mecha"},{"label":"Military","value":"military"},{"label":"Modern Life","value":"modern-life"},{"label":"Modern Romance","value":"modern-romance"},{"label":"Mystery","value":"mystery"},{"label":"Psychological","value":"psychological"},{"label":"Romance","value":"romance"},{"label":"Romantic","value":"romantic"},{"label":"School Life","value":"school-life"},{"label":"Sci-fi","value":"sci-fi"},{"label":"Seinen","value":"seinen"},{"label":"Shoujo","value":"shoujo"},{"label":"Shoujo Ai","value":"shoujo-ai"},{"label":"Shounen","value":"shounen"},{"label":"Shounen Ai","value":"shounen-ai"},{"label":"Slice of Life","value":"slice-of-life"},{"label":"Smut","value":"smut"},{"label":"Sports","value":"sports"},{"label":"Supernatural","value":"supernatural"},{"label":"Tragedy","value":"tragedy"},{"label":"Two-dimensional","value":"two-dimensional"},{"label":"Urban","value":"urban"},{"label":"Urban Life","value":"urban-life"},{"label":"Video Games","value":"video-games"},{"label":"Virtual Reality","value":"virtual-reality"},{"label":"Wuxia","value":"wuxia"},{"label":"Xianxia","value":"xianxia"},{"label":"Xuanhuan","value":"xuanhuan"},{"label":"Yaoi","value":"yaoi"},{"label":"Yuri","value":"yuri"}], "inputType":FilterInputs.Picker}]; \ No newline at end of file diff --git a/plugins/english/Novelroomnet[madara].ts b/plugins/english/Novelroomnet[madara].ts index 6bae24b..d074355 100644 --- a/plugins/english/Novelroomnet[madara].ts +++ b/plugins/english/Novelroomnet[madara].ts @@ -1,213 +1,252 @@ +import { fetchApi, fetchFile } from "@libs/fetch"; +import { Filter } from "@libs/filterInputs"; +import { Plugin } from '@typings/plugin' import { load as parseHTML } from "cheerio"; -import { fetchFile, fetchApi } from "@libs/fetch"; -import { Novel, Plugin, Chapter } from "@typings/plugin"; -import { FilterInputs } from "@libs/filterInputs"; import { defaultCover } from "@libs/defaultCover"; -import { NovelStatus } from "@libs/novelStatus" +import { NovelStatus } from "@libs/novelStatus"; import { parseMadaraDate } from "@libs/parseMadaraDate"; import dayjs from "dayjs"; -export const id = "novelroom"; -export const name = "Novelroom.net [madara]"; -export const icon = "multisrc/madara/icons/novelroom.net.png"; -export const version = "1.0.0"; -export const site = "https://novelroom.net/"; -const baseUrl = site; +interface MadaraOptionPath{ + genres?: string, + novels?: string, + novel?: string, + chapter?: string, +} -export const popularNovels: Plugin.popularNovels = async (pageNo, {filters, showLatestNovels}) => { - const novels: Novel.Item[] = []; +const MadaraDefaultPath: MadaraOptionPath = { + novels: 'novel', + novel: 'novel', + chapter: 'novel' +} - let url = site; +interface MadaraOptions { + useNewChapterEndpoint?: boolean, + path?: MadaraOptionPath, + lang?: string, + orderBy?: string +} - if (filters?.genres) { - url += "novel-genre/" + filters.genres + '/'; - } else { - url += "manga/"; +export interface MadaraMetadata { + id: string, + sourceSite: string, + sourceName: string, + options?: MadaraOptions, + filters?: Filter[], +} +class MadaraPlugin implements Plugin.PluginBase { + id: string; + name: string; + icon: string; + site: string; + version: string; + userAgent: string; + cookieString: string; + options?: MadaraOptions; + filter?: Filter[] | undefined; + + constructor(metadata: MadaraMetadata){ + this.id = metadata.id; + this.name = metadata.sourceName + "[madara]"; + const iconFileName = metadata.sourceName.replace(/\s+/g, "").toLowerCase(); + this.icon = `multisrc/madara/icons/${iconFileName}.png`; + this.site = metadata.sourceSite; + this.version = "1.0.0"; + this.userAgent = ""; + this.cookieString = ""; + this.options = metadata.options; + this.filter = metadata.filters; } + async popularNovels(pageNo: number, {filters, showLatestNovels}: Plugin.PopularNovelsOptions): Promise { + const novels: Plugin.NovelItem[] = []; - url += '/page/' + pageNo + '/' + - '?m_orderby=' + (showLatestNovels ? 'latest' : (filters?.sort || 'rating')); - - const body = await fetchApi(url).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - - loadedCheerio('.manga-title-badges').remove(); - - loadedCheerio('.page-item-detail').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - - let novelUrl = loadedCheerio(this).find('.post-title') - .find('a') - .attr('href') || ''; - const novel: Novel.Item = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - - novels.push(novel); - }); - - return novels; -}; - -export const parseNovelAndChapters: Plugin.parseNovelAndChapters = async ( - novelUrl -) => { - const novel: Novel.instance = { - url: novelUrl, - }; - - const body = await fetchApi(novelUrl).then(res => res.text()); - - let loadedCheerio = parseHTML(body); - - loadedCheerio('.manga-title-badges').remove(); - - novel.name = loadedCheerio('.post-title h1').text().trim(); - - novel.cover = - loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || - loadedCheerio('.summary_image > a > img').attr('data-src') || - loadedCheerio('.summary_image > a > img').attr('src') || - defaultCover; - - loadedCheerio('.post-content_item, .post-content').each(function () { - const detailName = loadedCheerio(this).find('h5').text().trim(); - const detail = loadedCheerio(this).find('.summary-content').text().trim(); - - switch (detailName) { - case 'Genre(s)': - case 'التصنيفات': - novel.genres = detail.replace(/[\t\n]/g, ','); - break; - case 'Author(s)': - case 'المؤلف': - case 'المؤلف (ين)': - novel.author = detail; - break; - case 'Status': - case 'الحالة': - novel.status = - detail.includes('OnGoing') || detail.includes('مستمرة') - ? NovelStatus.Ongoing - : NovelStatus.Completed; - break; - } - }); - - loadedCheerio('div.summary__content .code-block,script').remove(); - novel.summary = loadedCheerio('div.summary__content').text().trim(); - - - let html; - - if (false) { - const novelId = - loadedCheerio('.rating-post-id').attr('value') || - loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; - - const body = { - action: "manga_get_chapters", - manga: novelId, - } - html = await fetchApi( - baseUrl + 'wp-admin/admin-ajax.php', - { - method: 'POST', - body: JSON.stringify(body), - }) - .then(res => res.text()); - } else { - html = await fetchApi( - baseUrl + 'ajax/chapters/', - { method: 'POST' }) - .then(res => res.text()); - } - - if (html !== '0') { - loadedCheerio = parseHTML(html); - } - - const chapters: Chapter.Item[] = []; - loadedCheerio('.wp-manga-chapter').each(function () { - const chapterName = loadedCheerio(this).find('a').text().trim(); - - let releaseDate = null; - releaseDate = loadedCheerio(this) - .find('span.chapter-release-date') - .text() - .trim(); - - if (releaseDate) { - releaseDate = parseMadaraDate(releaseDate); + let url = this.site; + if (filters?.genres && this.options?.path?.genres) { + url += this.options?.path?.genres + filters.genres + '/'; } else { - /** - * Insert current date - */ - - releaseDate = dayjs().format('LL'); + url += this.options?.path?.novels ? this.options.path.novels : MadaraDefaultPath.novels; } + + url += '/page/' + pageNo + '/' + + '?m_orderby=' + (showLatestNovels ? 'latest' : (filters?.sort || 'rating')); + + const body = await fetchApi(url).then(res => res.text()); + + const loadedCheerio = parseHTML(body); + + loadedCheerio('.manga-title-badges').remove(); + + loadedCheerio('.page-item-detail').each(function () { + const novelName = loadedCheerio(this).find('.post-title').text().trim(); + let image = loadedCheerio(this).find('img'); + const novelCover = image.attr('data-src') || image.attr('src'); + + let novelUrl = loadedCheerio(this).find('.post-title') + .find('a') + .attr('href') || ''; + const novel: Plugin.NovelItem = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + + novels.push(novel); + }); + + return novels; + } + async parseNovelAndChapters(novelUrl: string): Promise { + const novel: Plugin.SourceNovel = { + url: novelUrl, + }; + + const body = await fetchApi(novelUrl).then(res => res.text()); + + let loadedCheerio = parseHTML(body); + + loadedCheerio('.manga-title-badges, #manga-title span').remove(); + novel.name = + loadedCheerio('.post-title h1').text().trim() || + loadedCheerio('#manga-title h1').text(); + + novel.cover = + loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || + loadedCheerio('.summary_image > a > img').attr('data-src') || + loadedCheerio('.summary_image > a > img').attr('src') || + defaultCover; + + loadedCheerio('.post-content_item, .post-content').each(function () { + const detailName = loadedCheerio(this).find('h5').text().trim(); + const detail = loadedCheerio(this).find('.summary-content').text().trim(); + + switch (detailName) { + case 'Genre(s)': + case 'التصنيفات': + novel.genres = detail.replace(/[\\t\\n]/g, ','); + break; + case 'Author(s)': + case 'المؤلف': + case 'المؤلف (ين)': + novel.author = detail; + break; + case 'Status': + case 'الحالة': + novel.status = + detail.includes('OnGoing') || detail.includes('مستمرة') + ? NovelStatus.Ongoing + : NovelStatus.Completed; + break; + } + }); + + loadedCheerio('div.summary__content .code-block,script').remove(); + novel.summary = + loadedCheerio('div.summary__content').text().trim() || + loadedCheerio('#tab-manga-about').text().trim() || + loadedCheerio('.post-content_item h5:contains("Summary")').next().text().trim(); + + let html; + + if (this.options?.useNewChapterEndpoint !== true) { + const novelId = + loadedCheerio('.rating-post-id').attr('value') || + loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; + + const formData = new FormData() + formData.append("action", "manga_get_chapters"); + formData.append("manga", novelId); - let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + html = await fetchApi( + this.site + 'wp-admin/admin-ajax.php', + { + method: 'POST', + body: formData, + }) + .then(res => res.text()); + } else { + html = await fetchApi( + novelUrl + 'ajax/chapters/', + { method: 'POST' }) + .then(res => res.text()); + } + + if (html !== '0') { + loadedCheerio = parseHTML(html); + } + + const chapters: Plugin.ChapterItem[] = []; + loadedCheerio('.wp-manga-chapter').each(function () { + const chapterName = loadedCheerio(this).find('a').text().trim(); + + let releaseDate = null; + releaseDate = loadedCheerio(this) + .find('span.chapter-release-date') + .text() + .trim(); + + if (releaseDate) { + releaseDate = parseMadaraDate(releaseDate); + } else { + /** + * Insert current date + */ + + releaseDate = dayjs().format('LL'); + } + + let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + + chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); + }); + + novel.chapters = chapters.reverse(); + return novel; + } + async parseChapter(chapterUrl: string): Promise { + const body = await fetchApi(chapterUrl).then(res => res.text()); - chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); - }); + const loadedCheerio = parseHTML(body); + const chapterText = + loadedCheerio('.text-left').html() || + loadedCheerio('.text-right').html() || + loadedCheerio('.entry-content').html() || ""; - novel.chapters = chapters.reverse(); - return novel; -}; - -export const parseChapter: Plugin.parseChapter = async (chapterUrl) => { - const url = baseUrl + "/" + "manga" + "/" + chapterUrl; - - const body = await fetchApi(chapterUrl).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - const chapterText = - loadedCheerio('.text-left').html() || - loadedCheerio('.text-right').html() || - loadedCheerio('.entry-content').html(); - - return chapterText; -}; - -export const searchNovels: Plugin.searchNovels = async (searchTerm) => { - const novels: Novel.Item[] = []; - const url = baseUrl + "?s=" + searchTerm + "&post_type=wp-manga"; - - const body = await fetchApi(url).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - - - loadedCheerio('.c-tabs-item__content').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - - let novelUrl = loadedCheerio(this) - .find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - - novels.push(novel); - }); - return novels; -}; - -export const fetchImage: Plugin.fetchImage = async (url) => { - return await fetchFile(url); -}; - -export const filters = []; \ No newline at end of file + return chapterText; + } + async searchNovels(searchTerm: string, pageNo?: number | undefined): Promise { + const novels: Plugin.NovelItem[] = []; + const url = this.site + "?s=" + searchTerm + "&post_type=wp-manga"; + + const body = await fetchApi(url).then(res => res.text()); + + const loadedCheerio = parseHTML(body); + + + loadedCheerio('.c-tabs-item__content').each(function () { + const novelName = loadedCheerio(this).find('.post-title').text().trim(); + + let image = loadedCheerio(this).find('img'); + const novelCover = image.attr('data-src') || image.attr('src'); + + let novelUrl = loadedCheerio(this) + .find('.post-title') + .find('a') + .attr('href') || ''; + const novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + + novels.push(novel); + }); + return novels; + } + async fetchImage(url: string): Promise { + return await fetchFile(url, {}); + } +} +const plugin = new MadaraPlugin({"id":"novelroom","sourceSite":"https://novelroom.net/","sourceName":"Novelroom.net","filters":[],"options":{"path":{"novels":"manga","novel":"manga","chapter":"manga"},"lang":"English"}}); +export default plugin; + \ No newline at end of file diff --git a/plugins/english/Novelstic[madara].ts b/plugins/english/Novelstic[madara].ts index 05ac934..c9d81ed 100644 --- a/plugins/english/Novelstic[madara].ts +++ b/plugins/english/Novelstic[madara].ts @@ -1,213 +1,252 @@ +import { fetchApi, fetchFile } from "@libs/fetch"; +import { Filter } from "@libs/filterInputs"; +import { Plugin } from '@typings/plugin' import { load as parseHTML } from "cheerio"; -import { fetchFile, fetchApi } from "@libs/fetch"; -import { Novel, Plugin, Chapter } from "@typings/plugin"; -import { FilterInputs } from "@libs/filterInputs"; import { defaultCover } from "@libs/defaultCover"; -import { NovelStatus } from "@libs/novelStatus" +import { NovelStatus } from "@libs/novelStatus"; import { parseMadaraDate } from "@libs/parseMadaraDate"; import dayjs from "dayjs"; -export const id = "novelstic"; -export const name = "Novelstic [madara]"; -export const icon = "multisrc/madara/icons/novelstic.png"; -export const version = "1.0.0"; -export const site = "https://novelstic.com/"; -const baseUrl = site; +interface MadaraOptionPath{ + genres?: string, + novels?: string, + novel?: string, + chapter?: string, +} -export const popularNovels: Plugin.popularNovels = async (pageNo, {filters, showLatestNovels}) => { - const novels: Novel.Item[] = []; +const MadaraDefaultPath: MadaraOptionPath = { + novels: 'novel', + novel: 'novel', + chapter: 'novel' +} - let url = site; +interface MadaraOptions { + useNewChapterEndpoint?: boolean, + path?: MadaraOptionPath, + lang?: string, + orderBy?: string +} - if (filters?.genres) { - url += "novel-genre/" + filters.genres + '/'; - } else { - url += "novel/"; +export interface MadaraMetadata { + id: string, + sourceSite: string, + sourceName: string, + options?: MadaraOptions, + filters?: Filter[], +} +class MadaraPlugin implements Plugin.PluginBase { + id: string; + name: string; + icon: string; + site: string; + version: string; + userAgent: string; + cookieString: string; + options?: MadaraOptions; + filter?: Filter[] | undefined; + + constructor(metadata: MadaraMetadata){ + this.id = metadata.id; + this.name = metadata.sourceName + "[madara]"; + const iconFileName = metadata.sourceName.replace(/\s+/g, "").toLowerCase(); + this.icon = `multisrc/madara/icons/${iconFileName}.png`; + this.site = metadata.sourceSite; + this.version = "1.0.0"; + this.userAgent = ""; + this.cookieString = ""; + this.options = metadata.options; + this.filter = metadata.filters; } + async popularNovels(pageNo: number, {filters, showLatestNovels}: Plugin.PopularNovelsOptions): Promise { + const novels: Plugin.NovelItem[] = []; - url += '/page/' + pageNo + '/' + - '?m_orderby=' + (showLatestNovels ? 'latest' : (filters?.sort || 'rating')); - - const body = await fetchApi(url).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - - loadedCheerio('.manga-title-badges').remove(); - - loadedCheerio('.page-item-detail').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - - let novelUrl = loadedCheerio(this).find('.post-title') - .find('a') - .attr('href') || ''; - const novel: Novel.Item = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - - novels.push(novel); - }); - - return novels; -}; - -export const parseNovelAndChapters: Plugin.parseNovelAndChapters = async ( - novelUrl -) => { - const novel: Novel.instance = { - url: novelUrl, - }; - - const body = await fetchApi(novelUrl).then(res => res.text()); - - let loadedCheerio = parseHTML(body); - - loadedCheerio('.manga-title-badges').remove(); - - novel.name = loadedCheerio('.post-title h1').text().trim(); - - novel.cover = - loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || - loadedCheerio('.summary_image > a > img').attr('data-src') || - loadedCheerio('.summary_image > a > img').attr('src') || - defaultCover; - - loadedCheerio('.post-content_item, .post-content').each(function () { - const detailName = loadedCheerio(this).find('h5').text().trim(); - const detail = loadedCheerio(this).find('.summary-content').text().trim(); - - switch (detailName) { - case 'Genre(s)': - case 'التصنيفات': - novel.genres = detail.replace(/[\t\n]/g, ','); - break; - case 'Author(s)': - case 'المؤلف': - case 'المؤلف (ين)': - novel.author = detail; - break; - case 'Status': - case 'الحالة': - novel.status = - detail.includes('OnGoing') || detail.includes('مستمرة') - ? NovelStatus.Ongoing - : NovelStatus.Completed; - break; - } - }); - - loadedCheerio('div.summary__content .code-block,script').remove(); - novel.summary = loadedCheerio('div.summary__content').text().trim(); - - - let html; - - if (true) { - const novelId = - loadedCheerio('.rating-post-id').attr('value') || - loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; - - const body = { - action: "manga_get_chapters", - manga: novelId, - } - html = await fetchApi( - baseUrl + 'wp-admin/admin-ajax.php', - { - method: 'POST', - body: JSON.stringify(body), - }) - .then(res => res.text()); - } else { - html = await fetchApi( - baseUrl + 'ajax/chapters/', - { method: 'POST' }) - .then(res => res.text()); - } - - if (html !== '0') { - loadedCheerio = parseHTML(html); - } - - const chapters: Chapter.Item[] = []; - loadedCheerio('.wp-manga-chapter').each(function () { - const chapterName = loadedCheerio(this).find('a').text().trim(); - - let releaseDate = null; - releaseDate = loadedCheerio(this) - .find('span.chapter-release-date') - .text() - .trim(); - - if (releaseDate) { - releaseDate = parseMadaraDate(releaseDate); + let url = this.site; + if (filters?.genres && this.options?.path?.genres) { + url += this.options?.path?.genres + filters.genres + '/'; } else { - /** - * Insert current date - */ - - releaseDate = dayjs().format('LL'); + url += this.options?.path?.novels ? this.options.path.novels : MadaraDefaultPath.novels; } + + url += '/page/' + pageNo + '/' + + '?m_orderby=' + (showLatestNovels ? 'latest' : (filters?.sort || 'rating')); + + const body = await fetchApi(url).then(res => res.text()); + + const loadedCheerio = parseHTML(body); + + loadedCheerio('.manga-title-badges').remove(); + + loadedCheerio('.page-item-detail').each(function () { + const novelName = loadedCheerio(this).find('.post-title').text().trim(); + let image = loadedCheerio(this).find('img'); + const novelCover = image.attr('data-src') || image.attr('src'); + + let novelUrl = loadedCheerio(this).find('.post-title') + .find('a') + .attr('href') || ''; + const novel: Plugin.NovelItem = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + + novels.push(novel); + }); + + return novels; + } + async parseNovelAndChapters(novelUrl: string): Promise { + const novel: Plugin.SourceNovel = { + url: novelUrl, + }; + + const body = await fetchApi(novelUrl).then(res => res.text()); + + let loadedCheerio = parseHTML(body); + + loadedCheerio('.manga-title-badges, #manga-title span').remove(); + novel.name = + loadedCheerio('.post-title h1').text().trim() || + loadedCheerio('#manga-title h1').text(); + + novel.cover = + loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || + loadedCheerio('.summary_image > a > img').attr('data-src') || + loadedCheerio('.summary_image > a > img').attr('src') || + defaultCover; + + loadedCheerio('.post-content_item, .post-content').each(function () { + const detailName = loadedCheerio(this).find('h5').text().trim(); + const detail = loadedCheerio(this).find('.summary-content').text().trim(); + + switch (detailName) { + case 'Genre(s)': + case 'التصنيفات': + novel.genres = detail.replace(/[\\t\\n]/g, ','); + break; + case 'Author(s)': + case 'المؤلف': + case 'المؤلف (ين)': + novel.author = detail; + break; + case 'Status': + case 'الحالة': + novel.status = + detail.includes('OnGoing') || detail.includes('مستمرة') + ? NovelStatus.Ongoing + : NovelStatus.Completed; + break; + } + }); + + loadedCheerio('div.summary__content .code-block,script').remove(); + novel.summary = + loadedCheerio('div.summary__content').text().trim() || + loadedCheerio('#tab-manga-about').text().trim() || + loadedCheerio('.post-content_item h5:contains("Summary")').next().text().trim(); + + let html; + + if (this.options?.useNewChapterEndpoint !== true) { + const novelId = + loadedCheerio('.rating-post-id').attr('value') || + loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; + + const formData = new FormData() + formData.append("action", "manga_get_chapters"); + formData.append("manga", novelId); - let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + html = await fetchApi( + this.site + 'wp-admin/admin-ajax.php', + { + method: 'POST', + body: formData, + }) + .then(res => res.text()); + } else { + html = await fetchApi( + novelUrl + 'ajax/chapters/', + { method: 'POST' }) + .then(res => res.text()); + } + + if (html !== '0') { + loadedCheerio = parseHTML(html); + } + + const chapters: Plugin.ChapterItem[] = []; + loadedCheerio('.wp-manga-chapter').each(function () { + const chapterName = loadedCheerio(this).find('a').text().trim(); + + let releaseDate = null; + releaseDate = loadedCheerio(this) + .find('span.chapter-release-date') + .text() + .trim(); + + if (releaseDate) { + releaseDate = parseMadaraDate(releaseDate); + } else { + /** + * Insert current date + */ + + releaseDate = dayjs().format('LL'); + } + + let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + + chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); + }); + + novel.chapters = chapters.reverse(); + return novel; + } + async parseChapter(chapterUrl: string): Promise { + const body = await fetchApi(chapterUrl).then(res => res.text()); - chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); - }); + const loadedCheerio = parseHTML(body); + const chapterText = + loadedCheerio('.text-left').html() || + loadedCheerio('.text-right').html() || + loadedCheerio('.entry-content').html() || ""; - novel.chapters = chapters.reverse(); - return novel; -}; - -export const parseChapter: Plugin.parseChapter = async (chapterUrl) => { - const url = baseUrl + "/" + "novel" + "/" + chapterUrl; - - const body = await fetchApi(chapterUrl).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - const chapterText = - loadedCheerio('.text-left').html() || - loadedCheerio('.text-right').html() || - loadedCheerio('.entry-content').html(); - - return chapterText; -}; - -export const searchNovels: Plugin.searchNovels = async (searchTerm) => { - const novels: Novel.Item[] = []; - const url = baseUrl + "?s=" + searchTerm + "&post_type=wp-manga"; - - const body = await fetchApi(url).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - - - loadedCheerio('.c-tabs-item__content').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - - let novelUrl = loadedCheerio(this) - .find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - - novels.push(novel); - }); - return novels; -}; - -export const fetchImage: Plugin.fetchImage = async (url) => { - return await fetchFile(url); -}; - -export const filters = [{"key":"sort","label":"Order by","values":[{"label":"Rating","value":"rating"},{"label":"A-Z","value":"alphabet"},{"label":"Latest","value":"latest"},{"label":"Most Views","value":"views"},{"label":"New","value":"new-manga"},{"label":"Trending","value":"trending"}],"inputType":FilterInputs.Picker}]; \ No newline at end of file + return chapterText; + } + async searchNovels(searchTerm: string, pageNo?: number | undefined): Promise { + const novels: Plugin.NovelItem[] = []; + const url = this.site + "?s=" + searchTerm + "&post_type=wp-manga"; + + const body = await fetchApi(url).then(res => res.text()); + + const loadedCheerio = parseHTML(body); + + + loadedCheerio('.c-tabs-item__content').each(function () { + const novelName = loadedCheerio(this).find('.post-title').text().trim(); + + let image = loadedCheerio(this).find('img'); + const novelCover = image.attr('data-src') || image.attr('src'); + + let novelUrl = loadedCheerio(this) + .find('.post-title') + .find('a') + .attr('href') || ''; + const novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + + novels.push(novel); + }); + return novels; + } + async fetchImage(url: string): Promise { + return await fetchFile(url, {}); + } +} +const plugin = new MadaraPlugin({"id":"novelstic","sourceSite":"https://novelstic.com/","sourceName":"Novelstic","filters":[{"key":"sort","label":"Order by","values":[{"label":"Rating","value":"rating"},{"label":"A-Z","value":"alphabet"},{"label":"Latest","value":"latest"},{"label":"Most Views","value":"views"},{"label":"New","value":"new-manga"},{"label":"Trending","value":"trending"}],"inputType":"Picker"}],"options":{"useNewChapterEndpoint":true,"lang":"English"}}); +export default plugin; + \ No newline at end of file diff --git a/plugins/english/OnlyMTL[madara].ts b/plugins/english/OnlyMTL[madara].ts index b427b3a..e8aa732 100644 --- a/plugins/english/OnlyMTL[madara].ts +++ b/plugins/english/OnlyMTL[madara].ts @@ -1,213 +1,252 @@ +import { fetchApi, fetchFile } from "@libs/fetch"; +import { Filter } from "@libs/filterInputs"; +import { Plugin } from '@typings/plugin' import { load as parseHTML } from "cheerio"; -import { fetchFile, fetchApi } from "@libs/fetch"; -import { Novel, Plugin, Chapter } from "@typings/plugin"; -import { FilterInputs } from "@libs/filterInputs"; import { defaultCover } from "@libs/defaultCover"; -import { NovelStatus } from "@libs/novelStatus" +import { NovelStatus } from "@libs/novelStatus"; import { parseMadaraDate } from "@libs/parseMadaraDate"; import dayjs from "dayjs"; -export const id = "onlymtl"; -export const name = "OnlyMTL [madara]"; -export const icon = "multisrc/madara/icons/onlymtl.png"; -export const version = "1.0.0"; -export const site = "https://www.onlymtl.com/"; -const baseUrl = site; +interface MadaraOptionPath{ + genres?: string, + novels?: string, + novel?: string, + chapter?: string, +} -export const popularNovels: Plugin.popularNovels = async (pageNo, {filters, showLatestNovels}) => { - const novels: Novel.Item[] = []; +const MadaraDefaultPath: MadaraOptionPath = { + novels: 'novel', + novel: 'novel', + chapter: 'novel' +} - let url = site; +interface MadaraOptions { + useNewChapterEndpoint?: boolean, + path?: MadaraOptionPath, + lang?: string, + orderBy?: string +} - if (filters?.genres) { - url += "novel-genre/" + filters.genres + '/'; - } else { - url += "novel/"; +export interface MadaraMetadata { + id: string, + sourceSite: string, + sourceName: string, + options?: MadaraOptions, + filters?: Filter[], +} +class MadaraPlugin implements Plugin.PluginBase { + id: string; + name: string; + icon: string; + site: string; + version: string; + userAgent: string; + cookieString: string; + options?: MadaraOptions; + filter?: Filter[] | undefined; + + constructor(metadata: MadaraMetadata){ + this.id = metadata.id; + this.name = metadata.sourceName + "[madara]"; + const iconFileName = metadata.sourceName.replace(/\s+/g, "").toLowerCase(); + this.icon = `multisrc/madara/icons/${iconFileName}.png`; + this.site = metadata.sourceSite; + this.version = "1.0.0"; + this.userAgent = ""; + this.cookieString = ""; + this.options = metadata.options; + this.filter = metadata.filters; } + async popularNovels(pageNo: number, {filters, showLatestNovels}: Plugin.PopularNovelsOptions): Promise { + const novels: Plugin.NovelItem[] = []; - url += '/page/' + pageNo + '/' + - '?m_orderby=' + (showLatestNovels ? 'latest' : (filters?.sort || 'rating')); - - const body = await fetchApi(url).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - - loadedCheerio('.manga-title-badges').remove(); - - loadedCheerio('.page-item-detail').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - - let novelUrl = loadedCheerio(this).find('.post-title') - .find('a') - .attr('href') || ''; - const novel: Novel.Item = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - - novels.push(novel); - }); - - return novels; -}; - -export const parseNovelAndChapters: Plugin.parseNovelAndChapters = async ( - novelUrl -) => { - const novel: Novel.instance = { - url: novelUrl, - }; - - const body = await fetchApi(novelUrl).then(res => res.text()); - - let loadedCheerio = parseHTML(body); - - loadedCheerio('.manga-title-badges').remove(); - - novel.name = loadedCheerio('.post-title h1').text().trim(); - - novel.cover = - loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || - loadedCheerio('.summary_image > a > img').attr('data-src') || - loadedCheerio('.summary_image > a > img').attr('src') || - defaultCover; - - loadedCheerio('.post-content_item, .post-content').each(function () { - const detailName = loadedCheerio(this).find('h5').text().trim(); - const detail = loadedCheerio(this).find('.summary-content').text().trim(); - - switch (detailName) { - case 'Genre(s)': - case 'التصنيفات': - novel.genres = detail.replace(/[\t\n]/g, ','); - break; - case 'Author(s)': - case 'المؤلف': - case 'المؤلف (ين)': - novel.author = detail; - break; - case 'Status': - case 'الحالة': - novel.status = - detail.includes('OnGoing') || detail.includes('مستمرة') - ? NovelStatus.Ongoing - : NovelStatus.Completed; - break; - } - }); - - loadedCheerio('div.summary__content .code-block,script').remove(); - novel.summary = loadedCheerio('div.summary__content').text().trim(); - - - let html; - - if (true) { - const novelId = - loadedCheerio('.rating-post-id').attr('value') || - loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; - - const body = { - action: "manga_get_chapters", - manga: novelId, - } - html = await fetchApi( - baseUrl + 'wp-admin/admin-ajax.php', - { - method: 'POST', - body: JSON.stringify(body), - }) - .then(res => res.text()); - } else { - html = await fetchApi( - baseUrl + 'ajax/chapters/', - { method: 'POST' }) - .then(res => res.text()); - } - - if (html !== '0') { - loadedCheerio = parseHTML(html); - } - - const chapters: Chapter.Item[] = []; - loadedCheerio('.wp-manga-chapter').each(function () { - const chapterName = loadedCheerio(this).find('a').text().trim(); - - let releaseDate = null; - releaseDate = loadedCheerio(this) - .find('span.chapter-release-date') - .text() - .trim(); - - if (releaseDate) { - releaseDate = parseMadaraDate(releaseDate); + let url = this.site; + if (filters?.genres && this.options?.path?.genres) { + url += this.options?.path?.genres + filters.genres + '/'; } else { - /** - * Insert current date - */ - - releaseDate = dayjs().format('LL'); + url += this.options?.path?.novels ? this.options.path.novels : MadaraDefaultPath.novels; } + + url += '/page/' + pageNo + '/' + + '?m_orderby=' + (showLatestNovels ? 'latest' : (filters?.sort || 'rating')); + + const body = await fetchApi(url).then(res => res.text()); + + const loadedCheerio = parseHTML(body); + + loadedCheerio('.manga-title-badges').remove(); + + loadedCheerio('.page-item-detail').each(function () { + const novelName = loadedCheerio(this).find('.post-title').text().trim(); + let image = loadedCheerio(this).find('img'); + const novelCover = image.attr('data-src') || image.attr('src'); + + let novelUrl = loadedCheerio(this).find('.post-title') + .find('a') + .attr('href') || ''; + const novel: Plugin.NovelItem = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + + novels.push(novel); + }); + + return novels; + } + async parseNovelAndChapters(novelUrl: string): Promise { + const novel: Plugin.SourceNovel = { + url: novelUrl, + }; + + const body = await fetchApi(novelUrl).then(res => res.text()); + + let loadedCheerio = parseHTML(body); + + loadedCheerio('.manga-title-badges, #manga-title span').remove(); + novel.name = + loadedCheerio('.post-title h1').text().trim() || + loadedCheerio('#manga-title h1').text(); + + novel.cover = + loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || + loadedCheerio('.summary_image > a > img').attr('data-src') || + loadedCheerio('.summary_image > a > img').attr('src') || + defaultCover; + + loadedCheerio('.post-content_item, .post-content').each(function () { + const detailName = loadedCheerio(this).find('h5').text().trim(); + const detail = loadedCheerio(this).find('.summary-content').text().trim(); + + switch (detailName) { + case 'Genre(s)': + case 'التصنيفات': + novel.genres = detail.replace(/[\\t\\n]/g, ','); + break; + case 'Author(s)': + case 'المؤلف': + case 'المؤلف (ين)': + novel.author = detail; + break; + case 'Status': + case 'الحالة': + novel.status = + detail.includes('OnGoing') || detail.includes('مستمرة') + ? NovelStatus.Ongoing + : NovelStatus.Completed; + break; + } + }); + + loadedCheerio('div.summary__content .code-block,script').remove(); + novel.summary = + loadedCheerio('div.summary__content').text().trim() || + loadedCheerio('#tab-manga-about').text().trim() || + loadedCheerio('.post-content_item h5:contains("Summary")').next().text().trim(); + + let html; + + if (this.options?.useNewChapterEndpoint !== true) { + const novelId = + loadedCheerio('.rating-post-id').attr('value') || + loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; + + const formData = new FormData() + formData.append("action", "manga_get_chapters"); + formData.append("manga", novelId); - let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + html = await fetchApi( + this.site + 'wp-admin/admin-ajax.php', + { + method: 'POST', + body: formData, + }) + .then(res => res.text()); + } else { + html = await fetchApi( + novelUrl + 'ajax/chapters/', + { method: 'POST' }) + .then(res => res.text()); + } + + if (html !== '0') { + loadedCheerio = parseHTML(html); + } + + const chapters: Plugin.ChapterItem[] = []; + loadedCheerio('.wp-manga-chapter').each(function () { + const chapterName = loadedCheerio(this).find('a').text().trim(); + + let releaseDate = null; + releaseDate = loadedCheerio(this) + .find('span.chapter-release-date') + .text() + .trim(); + + if (releaseDate) { + releaseDate = parseMadaraDate(releaseDate); + } else { + /** + * Insert current date + */ + + releaseDate = dayjs().format('LL'); + } + + let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + + chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); + }); + + novel.chapters = chapters.reverse(); + return novel; + } + async parseChapter(chapterUrl: string): Promise { + const body = await fetchApi(chapterUrl).then(res => res.text()); - chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); - }); + const loadedCheerio = parseHTML(body); + const chapterText = + loadedCheerio('.text-left').html() || + loadedCheerio('.text-right').html() || + loadedCheerio('.entry-content').html() || ""; - novel.chapters = chapters.reverse(); - return novel; -}; - -export const parseChapter: Plugin.parseChapter = async (chapterUrl) => { - const url = baseUrl + "/" + "novel" + "/" + chapterUrl; - - const body = await fetchApi(chapterUrl).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - const chapterText = - loadedCheerio('.text-left').html() || - loadedCheerio('.text-right').html() || - loadedCheerio('.entry-content').html(); - - return chapterText; -}; - -export const searchNovels: Plugin.searchNovels = async (searchTerm) => { - const novels: Novel.Item[] = []; - const url = baseUrl + "?s=" + searchTerm + "&post_type=wp-manga"; - - const body = await fetchApi(url).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - - - loadedCheerio('.c-tabs-item__content').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - - let novelUrl = loadedCheerio(this) - .find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - - novels.push(novel); - }); - return novels; -}; - -export const fetchImage: Plugin.fetchImage = async (url) => { - return await fetchFile(url); -}; - -export const filters = []; \ No newline at end of file + return chapterText; + } + async searchNovels(searchTerm: string, pageNo?: number | undefined): Promise { + const novels: Plugin.NovelItem[] = []; + const url = this.site + "?s=" + searchTerm + "&post_type=wp-manga"; + + const body = await fetchApi(url).then(res => res.text()); + + const loadedCheerio = parseHTML(body); + + + loadedCheerio('.c-tabs-item__content').each(function () { + const novelName = loadedCheerio(this).find('.post-title').text().trim(); + + let image = loadedCheerio(this).find('img'); + const novelCover = image.attr('data-src') || image.attr('src'); + + let novelUrl = loadedCheerio(this) + .find('.post-title') + .find('a') + .attr('href') || ''; + const novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + + novels.push(novel); + }); + return novels; + } + async fetchImage(url: string): Promise { + return await fetchFile(url, {}); + } +} +const plugin = new MadaraPlugin({"id":"onlymtl","sourceSite":"https://www.onlymtl.com/","sourceName":"OnlyMTL","filters":[],"options":{"useNewChapterEndpoint":true,"lang":"English"}}); +export default plugin; + \ No newline at end of file diff --git a/plugins/english/ReadWebNovels[madara].ts b/plugins/english/ReadWebNovels[madara].ts index e1bb54b..39af4b1 100644 --- a/plugins/english/ReadWebNovels[madara].ts +++ b/plugins/english/ReadWebNovels[madara].ts @@ -1,213 +1,252 @@ +import { fetchApi, fetchFile } from "@libs/fetch"; +import { Filter } from "@libs/filterInputs"; +import { Plugin } from '@typings/plugin' import { load as parseHTML } from "cheerio"; -import { fetchFile, fetchApi } from "@libs/fetch"; -import { Novel, Plugin, Chapter } from "@typings/plugin"; -import { FilterInputs } from "@libs/filterInputs"; import { defaultCover } from "@libs/defaultCover"; -import { NovelStatus } from "@libs/novelStatus" +import { NovelStatus } from "@libs/novelStatus"; import { parseMadaraDate } from "@libs/parseMadaraDate"; import dayjs from "dayjs"; -export const id = "readwebnovels"; -export const name = "ReadWebNovels [madara]"; -export const icon = "multisrc/madara/icons/readwebnovels.png"; -export const version = "1.0.0"; -export const site = "https://readwebnovels.net/"; -const baseUrl = site; +interface MadaraOptionPath{ + genres?: string, + novels?: string, + novel?: string, + chapter?: string, +} -export const popularNovels: Plugin.popularNovels = async (pageNo, {filters, showLatestNovels}) => { - const novels: Novel.Item[] = []; +const MadaraDefaultPath: MadaraOptionPath = { + novels: 'novel', + novel: 'novel', + chapter: 'novel' +} - let url = site; +interface MadaraOptions { + useNewChapterEndpoint?: boolean, + path?: MadaraOptionPath, + lang?: string, + orderBy?: string +} - if (filters?.genres) { - url += "novel-genre/" + filters.genres + '/'; - } else { - url += "novel/"; +export interface MadaraMetadata { + id: string, + sourceSite: string, + sourceName: string, + options?: MadaraOptions, + filters?: Filter[], +} +class MadaraPlugin implements Plugin.PluginBase { + id: string; + name: string; + icon: string; + site: string; + version: string; + userAgent: string; + cookieString: string; + options?: MadaraOptions; + filter?: Filter[] | undefined; + + constructor(metadata: MadaraMetadata){ + this.id = metadata.id; + this.name = metadata.sourceName + "[madara]"; + const iconFileName = metadata.sourceName.replace(/\s+/g, "").toLowerCase(); + this.icon = `multisrc/madara/icons/${iconFileName}.png`; + this.site = metadata.sourceSite; + this.version = "1.0.0"; + this.userAgent = ""; + this.cookieString = ""; + this.options = metadata.options; + this.filter = metadata.filters; } + async popularNovels(pageNo: number, {filters, showLatestNovels}: Plugin.PopularNovelsOptions): Promise { + const novels: Plugin.NovelItem[] = []; - url += '/page/' + pageNo + '/' + - '?m_orderby=' + (showLatestNovels ? 'latest' : (filters?.sort || 'rating')); - - const body = await fetchApi(url).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - - loadedCheerio('.manga-title-badges').remove(); - - loadedCheerio('.page-item-detail').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - - let novelUrl = loadedCheerio(this).find('.post-title') - .find('a') - .attr('href') || ''; - const novel: Novel.Item = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - - novels.push(novel); - }); - - return novels; -}; - -export const parseNovelAndChapters: Plugin.parseNovelAndChapters = async ( - novelUrl -) => { - const novel: Novel.instance = { - url: novelUrl, - }; - - const body = await fetchApi(novelUrl).then(res => res.text()); - - let loadedCheerio = parseHTML(body); - - loadedCheerio('.manga-title-badges').remove(); - - novel.name = loadedCheerio('.post-title h1').text().trim(); - - novel.cover = - loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || - loadedCheerio('.summary_image > a > img').attr('data-src') || - loadedCheerio('.summary_image > a > img').attr('src') || - defaultCover; - - loadedCheerio('.post-content_item, .post-content').each(function () { - const detailName = loadedCheerio(this).find('h5').text().trim(); - const detail = loadedCheerio(this).find('.summary-content').text().trim(); - - switch (detailName) { - case 'Genre(s)': - case 'التصنيفات': - novel.genres = detail.replace(/[\t\n]/g, ','); - break; - case 'Author(s)': - case 'المؤلف': - case 'المؤلف (ين)': - novel.author = detail; - break; - case 'Status': - case 'الحالة': - novel.status = - detail.includes('OnGoing') || detail.includes('مستمرة') - ? NovelStatus.Ongoing - : NovelStatus.Completed; - break; - } - }); - - loadedCheerio('div.summary__content .code-block,script').remove(); - novel.summary = loadedCheerio('div.summary__content').text().trim(); - - - let html; - - if (false) { - const novelId = - loadedCheerio('.rating-post-id').attr('value') || - loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; - - const body = { - action: "manga_get_chapters", - manga: novelId, - } - html = await fetchApi( - baseUrl + 'wp-admin/admin-ajax.php', - { - method: 'POST', - body: JSON.stringify(body), - }) - .then(res => res.text()); - } else { - html = await fetchApi( - baseUrl + 'ajax/chapters/', - { method: 'POST' }) - .then(res => res.text()); - } - - if (html !== '0') { - loadedCheerio = parseHTML(html); - } - - const chapters: Chapter.Item[] = []; - loadedCheerio('.wp-manga-chapter').each(function () { - const chapterName = loadedCheerio(this).find('a').text().trim(); - - let releaseDate = null; - releaseDate = loadedCheerio(this) - .find('span.chapter-release-date') - .text() - .trim(); - - if (releaseDate) { - releaseDate = parseMadaraDate(releaseDate); + let url = this.site; + if (filters?.genres && this.options?.path?.genres) { + url += this.options?.path?.genres + filters.genres + '/'; } else { - /** - * Insert current date - */ - - releaseDate = dayjs().format('LL'); + url += this.options?.path?.novels ? this.options.path.novels : MadaraDefaultPath.novels; } + + url += '/page/' + pageNo + '/' + + '?m_orderby=' + (showLatestNovels ? 'latest' : (filters?.sort || 'rating')); + + const body = await fetchApi(url).then(res => res.text()); + + const loadedCheerio = parseHTML(body); + + loadedCheerio('.manga-title-badges').remove(); + + loadedCheerio('.page-item-detail').each(function () { + const novelName = loadedCheerio(this).find('.post-title').text().trim(); + let image = loadedCheerio(this).find('img'); + const novelCover = image.attr('data-src') || image.attr('src'); + + let novelUrl = loadedCheerio(this).find('.post-title') + .find('a') + .attr('href') || ''; + const novel: Plugin.NovelItem = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + + novels.push(novel); + }); + + return novels; + } + async parseNovelAndChapters(novelUrl: string): Promise { + const novel: Plugin.SourceNovel = { + url: novelUrl, + }; + + const body = await fetchApi(novelUrl).then(res => res.text()); + + let loadedCheerio = parseHTML(body); + + loadedCheerio('.manga-title-badges, #manga-title span').remove(); + novel.name = + loadedCheerio('.post-title h1').text().trim() || + loadedCheerio('#manga-title h1').text(); + + novel.cover = + loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || + loadedCheerio('.summary_image > a > img').attr('data-src') || + loadedCheerio('.summary_image > a > img').attr('src') || + defaultCover; + + loadedCheerio('.post-content_item, .post-content').each(function () { + const detailName = loadedCheerio(this).find('h5').text().trim(); + const detail = loadedCheerio(this).find('.summary-content').text().trim(); + + switch (detailName) { + case 'Genre(s)': + case 'التصنيفات': + novel.genres = detail.replace(/[\\t\\n]/g, ','); + break; + case 'Author(s)': + case 'المؤلف': + case 'المؤلف (ين)': + novel.author = detail; + break; + case 'Status': + case 'الحالة': + novel.status = + detail.includes('OnGoing') || detail.includes('مستمرة') + ? NovelStatus.Ongoing + : NovelStatus.Completed; + break; + } + }); + + loadedCheerio('div.summary__content .code-block,script').remove(); + novel.summary = + loadedCheerio('div.summary__content').text().trim() || + loadedCheerio('#tab-manga-about').text().trim() || + loadedCheerio('.post-content_item h5:contains("Summary")').next().text().trim(); + + let html; + + if (this.options?.useNewChapterEndpoint !== true) { + const novelId = + loadedCheerio('.rating-post-id').attr('value') || + loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; + + const formData = new FormData() + formData.append("action", "manga_get_chapters"); + formData.append("manga", novelId); - let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + html = await fetchApi( + this.site + 'wp-admin/admin-ajax.php', + { + method: 'POST', + body: formData, + }) + .then(res => res.text()); + } else { + html = await fetchApi( + novelUrl + 'ajax/chapters/', + { method: 'POST' }) + .then(res => res.text()); + } + + if (html !== '0') { + loadedCheerio = parseHTML(html); + } + + const chapters: Plugin.ChapterItem[] = []; + loadedCheerio('.wp-manga-chapter').each(function () { + const chapterName = loadedCheerio(this).find('a').text().trim(); + + let releaseDate = null; + releaseDate = loadedCheerio(this) + .find('span.chapter-release-date') + .text() + .trim(); + + if (releaseDate) { + releaseDate = parseMadaraDate(releaseDate); + } else { + /** + * Insert current date + */ + + releaseDate = dayjs().format('LL'); + } + + let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + + chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); + }); + + novel.chapters = chapters.reverse(); + return novel; + } + async parseChapter(chapterUrl: string): Promise { + const body = await fetchApi(chapterUrl).then(res => res.text()); - chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); - }); + const loadedCheerio = parseHTML(body); + const chapterText = + loadedCheerio('.text-left').html() || + loadedCheerio('.text-right').html() || + loadedCheerio('.entry-content').html() || ""; - novel.chapters = chapters.reverse(); - return novel; -}; - -export const parseChapter: Plugin.parseChapter = async (chapterUrl) => { - const url = baseUrl + "/" + "novel" + "/" + chapterUrl; - - const body = await fetchApi(chapterUrl).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - const chapterText = - loadedCheerio('.text-left').html() || - loadedCheerio('.text-right').html() || - loadedCheerio('.entry-content').html(); - - return chapterText; -}; - -export const searchNovels: Plugin.searchNovels = async (searchTerm) => { - const novels: Novel.Item[] = []; - const url = baseUrl + "?s=" + searchTerm + "&post_type=wp-manga"; - - const body = await fetchApi(url).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - - - loadedCheerio('.c-tabs-item__content').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - - let novelUrl = loadedCheerio(this) - .find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - - novels.push(novel); - }); - return novels; -}; - -export const fetchImage: Plugin.fetchImage = async (url) => { - return await fetchFile(url); -}; - -export const filters = [{"key":"sort","label":"Order by","values":[{"label":"Rating","value":"rating"},{"label":"A-Z","value":"alphabet"},{"label":"Latest","value":"latest"},{"label":"Most Views","value":"views"},{"label":"New","value":"new-manga"},{"label":"Trending","value":"trending"}],"inputType":FilterInputs.Picker}]; \ No newline at end of file + return chapterText; + } + async searchNovels(searchTerm: string, pageNo?: number | undefined): Promise { + const novels: Plugin.NovelItem[] = []; + const url = this.site + "?s=" + searchTerm + "&post_type=wp-manga"; + + const body = await fetchApi(url).then(res => res.text()); + + const loadedCheerio = parseHTML(body); + + + loadedCheerio('.c-tabs-item__content').each(function () { + const novelName = loadedCheerio(this).find('.post-title').text().trim(); + + let image = loadedCheerio(this).find('img'); + const novelCover = image.attr('data-src') || image.attr('src'); + + let novelUrl = loadedCheerio(this) + .find('.post-title') + .find('a') + .attr('href') || ''; + const novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + + novels.push(novel); + }); + return novels; + } + async fetchImage(url: string): Promise { + return await fetchFile(url, {}); + } +} +const plugin = new MadaraPlugin({"id":"readwebnovels","sourceSite":"https://readwebnovels.net/","sourceName":"ReadWebNovels","filters":[{"key":"sort","label":"Order by","values":[{"label":"Rating","value":"rating"},{"label":"A-Z","value":"alphabet"},{"label":"Latest","value":"latest"},{"label":"Most Views","value":"views"},{"label":"New","value":"new-manga"},{"label":"Trending","value":"trending"}],"inputType":"Picker"}],"options":{"lang":"English"}}); +export default plugin; + \ No newline at end of file diff --git a/plugins/english/Readwncom[readwn].ts b/plugins/english/Readwncom[readwn].ts deleted file mode 100644 index 415dd65..0000000 --- a/plugins/english/Readwncom[readwn].ts +++ /dev/null @@ -1,195 +0,0 @@ - -import { load as parseHTML } from "cheerio"; -// import dayjs from 'dayjs'; -import { fetchFile, fetchApi } from "@libs/fetch"; -import { Novel, Plugin, Chapter } from "@typings/plugin"; -import { parseMadaraDate } from "@libs/parseMadaraDate"; -// import { isUrlAbsolute } from '@libs/isAbsoluteUrl'; -// import { showToast } from "@libs/showToast"; -import { FilterInputs } from "@libs/filterInputs"; -// import { NovelStatus } from '@libs/novelStatus'; -// import { defaultCover } from "@libs/defaultCover"; - -export const id = "Readwn.com"; -export const name = "Readwn.com"; -export const icon = "multisrc/readwn/icons/readwn.png"; -export const version = "1.0.0"; -export const site = "https://www.readwn.com/"; - -export const popularNovels: Plugin.popularNovels = async function ( - page, - { filters, showLatestNovels } -) { - const novels: Novel.Item[] = []; - const pageNo = page - 1; - - let url = site + 'list/'; - url += (filters?.genres || 'all') + '/'; - url += (filters?.status || 'all') + '-'; - url += (showLatestNovels ? 'lastdotime' : filters?.sort || 'newstime') + '-'; - url += pageNo + '.html'; - - const result = await fetchApi(url); - const body = await result.text(); - - const loadedCheerio = parseHTML(body); - - - loadedCheerio('li.novel-item').each(function () { - const novelName = loadedCheerio(this).find('h4').text(); - const novelUrl = site + loadedCheerio(this).find('a').attr('href'); - - const coverUri = loadedCheerio(this) - .find('.novel-cover > img') - .attr('data-src'); - - const novelCover = site + coverUri; - - const novel = { name: novelName, cover: novelCover, url: novelUrl }; - - novels.push(novel); - }); - - return novels; -}; - - -export const parseNovelAndChapters: Plugin.parseNovelAndChapters = - async function (novelUrl) { - const result = await fetchApi(novelUrl); - const body = await result.text(); - - let loadedCheerio = parseHTML(body); - - const novel: Novel.instance = { - url: novelUrl, - chapters: [], - }; - - novel.name = loadedCheerio('h1.novel-title').text(); - - const coverUri = loadedCheerio('figure.cover > img').attr('data-src'); - novel.cover = site + coverUri; - - novel.summary = loadedCheerio('.summary') - .text() - .replace('Summary', '') - .trim(); - - novel.genres = ''; - - loadedCheerio('div.categories > ul > li').each(function () { - novel.genres += loadedCheerio(this).text().trim() + ','; - }); - - loadedCheerio('div.header-stats > span').each(function () { - if (loadedCheerio(this).find('small').text() === 'Status') { - novel.status = loadedCheerio(this).find('strong').text(); - } - }); - - novel.genres = novel.genres.slice(0, -1); - - novel.author = loadedCheerio('span[itemprop=author]').text(); - - let novelChapters: Chapter.Item[] = []; - - const novelId = novelUrl.replace('.html', '').replace(site, ''); - - const latestChapterNo = parseInt(loadedCheerio('.header-stats') - .find('span > strong') - .first() - .text() - .trim()); - - let lastChapterNo = 1; - loadedCheerio('.chapter-list li').each(function () { - const chapterName = loadedCheerio(this) - .find('a .chapter-title') - .text() - .trim(); - - const chapterUrl = site + loadedCheerio(this).find('a').attr('href')?.trim(); - - const releaseDate = loadedCheerio(this) - .find('a .chapter-update') - .text() - .trim(); - - lastChapterNo = parseInt(loadedCheerio(this).find('a .chapter-no').text().trim()); - - const chapter = { name: chapterName, releaseTime: parseMadaraDate(releaseDate), url: chapterUrl }; - - novelChapters.push(chapter); - }); - - // Itterate once more before loop to finish off - lastChapterNo++; - for (let i = lastChapterNo; i <= latestChapterNo; i++) { - const chapterName = 'Chapter ' + i; - const chapterUrl = site + novelId+'_'+ i +'.html'; - const releaseDate = null; - - const chapter = { name: chapterName, releaseTime: releaseDate,url: chapterUrl }; - - novelChapters.push(chapter); - } - - novel.chapters = novelChapters; - return novel; - }; - -export const parseChapter: Plugin.parseChapter = async function (chapterUrl) { - const result = await fetchApi(chapterUrl); - const body = await result.text(); - - const loadedCheerio = parseHTML(body); - - const chapterText = loadedCheerio('.chapter-content').html(); - return chapterText; -}; - -export const searchNovels: Plugin.searchNovels = async (searchTerm) => { - const novels: Novel.Item[] = []; - const searchUrl = site + 'e/search/index.php'; - - const result = await fetchApi(searchUrl, { - headers: { - 'Content-Type': 'application/x-www-form-urlencoded', - Referer: site + 'search.html', - Origin: site, - 'user-agent': - 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36', - }, - method: 'POST', - body: JSON.stringify({ - show: 'title', - tempid: 1, - tbname: 'news', - keyboard: searchTerm, - }), - }); - const body = await result.text(); - - const loadedCheerio = parseHTML(body); - - loadedCheerio('li.novel-item').each(function () { - const novelName = loadedCheerio(this).find('h4').text(); - const novelUrl = site + loadedCheerio(this).find('a').attr('href'); - - const coverUri = site + loadedCheerio(this).find('img').attr('data-src'); - const novelCover = site + coverUri; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - - novels.push(novel); - }); - return novels; -}; - -export const fetchImage: Plugin.fetchImage = fetchFile; - -export const filters = [{"key":"sort","label":"Sort By","values":[{"label":"New","value":"newstime"},{"label":"Popular","value":"onclick"},{"label":"Updates","value":"lastdotime"}], "inputType":FilterInputs.Picker},{"key":"status","label":"Status","values":[{"label":"All","value":"all"},{"label":"Completed","value":"Completed"},{"label":"Ongoing","value":"Ongoing"}], "inputType":FilterInputs.Picker},{"key":"genres","label":"Genre / Category","values":[{"label":"All","value":"all"},{"label":"Action","value":"action"},{"label":"Adventure","value":"adventure"},{"label":"Chinese","value":"chinese"},{"label":"Comedy","value":"comedy"},{"label":"Contemporary Romance","value":"contemporary-romance"},{"label":"Drama","value":"drama"},{"label":"Eastern Fantasy","value":"eastern-fantasy"},{"label":"Ecchi","value":"ecchi"},{"label":"Erciyuan","value":"erciyuan"},{"label":"Faloo","value":"faloo"},{"label":"Fan-Fiction","value":"fan-fiction"},{"label":"Fantasy","value":"fantasy"},{"label":"Fantasy Romance","value":"fantasy-romance"},{"label":"Game","value":"game"},{"label":"Gender Bender","value":"gender-bender"},{"label":"Harem","value":"harem"},{"label":"Hentai","value":"hentai"},{"label":"Historical","value":"historical"},{"label":"Horror","value":"horror"},{"label":"Isekai","value":"isekai"},{"label":"Japanese","value":"japanese"},{"label":"Josei","value":"josei"},{"label":"Korean","value":"korean"},{"label":"Lolicon","value":"lolicon"},{"label":"Magic","value":"magic"},{"label":"Magical Realism","value":"magical-realism"},{"label":"Martial Arts","value":"martial-arts"},{"label":"Mecha","value":"mecha"},{"label":"Military","value":"military"},{"label":"Mystery","value":"mystery"},{"label":"Official Circles","value":"official_circles"},{"label":"Psychological","value":"psychological"},{"label":"Romance","value":"romance"},{"label":"School Life","value":"school-life"},{"label":"Sci-fi","value":"sci-fi"},{"label":"Science Fiction","value":"science_fiction"},{"label":"Seinen","value":"seinen"},{"label":"Shoujo","value":"shoujo"},{"label":"Shoujo Ai","value":"shoujo-ai"},{"label":"Shounen","value":"shounen"},{"label":"Shounen Ai","value":"shounen-ai"},{"label":"Slice of Life","value":"slice-of-life"},{"label":"Sports","value":"sports"},{"label":"Supernatural","value":"supernatural"},{"label":"Suspense Thriller","value":"suspense_thriller"},{"label":"Tragedy","value":"tragedy"},{"label":"Travel Through Time","value":"travel_through_time"},{"label":"Two-dimensional","value":"two-dimensional"},{"label":"Urban","value":"urban"},{"label":"Urban Life","value":"urban-life"},{"label":"Video Games","value":"video-games"},{"label":"Virtual Reality","value":"virtual-reality"},{"label":"Wuxia","value":"wuxia"},{"label":"Wuxia Xianxia","value":"wuxia_xianxia"},{"label":"Xianxia","value":"xianxia"},{"label":"Xuanhuan","value":"xuanhuan"},{"label":"Yaoi","value":"yaoi"},{"label":"Yuri","value":"yuri"}], "inputType":FilterInputs.Picker}]; \ No newline at end of file diff --git a/plugins/english/SleepyTranslations[madara].ts b/plugins/english/SleepyTranslations[madara].ts index 69f5623..4591520 100644 --- a/plugins/english/SleepyTranslations[madara].ts +++ b/plugins/english/SleepyTranslations[madara].ts @@ -1,213 +1,252 @@ +import { fetchApi, fetchFile } from "@libs/fetch"; +import { Filter } from "@libs/filterInputs"; +import { Plugin } from '@typings/plugin' import { load as parseHTML } from "cheerio"; -import { fetchFile, fetchApi } from "@libs/fetch"; -import { Novel, Plugin, Chapter } from "@typings/plugin"; -import { FilterInputs } from "@libs/filterInputs"; import { defaultCover } from "@libs/defaultCover"; -import { NovelStatus } from "@libs/novelStatus" +import { NovelStatus } from "@libs/novelStatus"; import { parseMadaraDate } from "@libs/parseMadaraDate"; import dayjs from "dayjs"; -export const id = "sleeptTLS"; -export const name = "SleepyTranslations [madara]"; -export const icon = "multisrc/madara/icons/sleepytranslations.png"; -export const version = "1.0.0"; -export const site = "https://sleepytranslations.com/"; -const baseUrl = site; +interface MadaraOptionPath{ + genres?: string, + novels?: string, + novel?: string, + chapter?: string, +} -export const popularNovels: Plugin.popularNovels = async (pageNo, {filters, showLatestNovels}) => { - const novels: Novel.Item[] = []; +const MadaraDefaultPath: MadaraOptionPath = { + novels: 'novel', + novel: 'novel', + chapter: 'novel' +} - let url = site; +interface MadaraOptions { + useNewChapterEndpoint?: boolean, + path?: MadaraOptionPath, + lang?: string, + orderBy?: string +} - if (filters?.genres) { - url += "novel-genre/" + filters.genres + '/'; - } else { - url += "series/"; +export interface MadaraMetadata { + id: string, + sourceSite: string, + sourceName: string, + options?: MadaraOptions, + filters?: Filter[], +} +class MadaraPlugin implements Plugin.PluginBase { + id: string; + name: string; + icon: string; + site: string; + version: string; + userAgent: string; + cookieString: string; + options?: MadaraOptions; + filter?: Filter[] | undefined; + + constructor(metadata: MadaraMetadata){ + this.id = metadata.id; + this.name = metadata.sourceName + "[madara]"; + const iconFileName = metadata.sourceName.replace(/\s+/g, "").toLowerCase(); + this.icon = `multisrc/madara/icons/${iconFileName}.png`; + this.site = metadata.sourceSite; + this.version = "1.0.0"; + this.userAgent = ""; + this.cookieString = ""; + this.options = metadata.options; + this.filter = metadata.filters; } + async popularNovels(pageNo: number, {filters, showLatestNovels}: Plugin.PopularNovelsOptions): Promise { + const novels: Plugin.NovelItem[] = []; - url += '/page/' + pageNo + '/' + - '?m_orderby=' + (showLatestNovels ? 'latest' : (filters?.sort || 'rating')); - - const body = await fetchApi(url).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - - loadedCheerio('.manga-title-badges').remove(); - - loadedCheerio('.page-item-detail').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - - let novelUrl = loadedCheerio(this).find('.post-title') - .find('a') - .attr('href') || ''; - const novel: Novel.Item = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - - novels.push(novel); - }); - - return novels; -}; - -export const parseNovelAndChapters: Plugin.parseNovelAndChapters = async ( - novelUrl -) => { - const novel: Novel.instance = { - url: novelUrl, - }; - - const body = await fetchApi(novelUrl).then(res => res.text()); - - let loadedCheerio = parseHTML(body); - - loadedCheerio('.manga-title-badges').remove(); - - novel.name = loadedCheerio('.post-title h1').text().trim(); - - novel.cover = - loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || - loadedCheerio('.summary_image > a > img').attr('data-src') || - loadedCheerio('.summary_image > a > img').attr('src') || - defaultCover; - - loadedCheerio('.post-content_item, .post-content').each(function () { - const detailName = loadedCheerio(this).find('h5').text().trim(); - const detail = loadedCheerio(this).find('.summary-content').text().trim(); - - switch (detailName) { - case 'Genre(s)': - case 'التصنيفات': - novel.genres = detail.replace(/[\t\n]/g, ','); - break; - case 'Author(s)': - case 'المؤلف': - case 'المؤلف (ين)': - novel.author = detail; - break; - case 'Status': - case 'الحالة': - novel.status = - detail.includes('OnGoing') || detail.includes('مستمرة') - ? NovelStatus.Ongoing - : NovelStatus.Completed; - break; - } - }); - - loadedCheerio('div.summary__content .code-block,script').remove(); - novel.summary = loadedCheerio('div.summary__content').text().trim(); - - - let html; - - if (true) { - const novelId = - loadedCheerio('.rating-post-id').attr('value') || - loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; - - const body = { - action: "manga_get_chapters", - manga: novelId, - } - html = await fetchApi( - baseUrl + 'wp-admin/admin-ajax.php', - { - method: 'POST', - body: JSON.stringify(body), - }) - .then(res => res.text()); - } else { - html = await fetchApi( - baseUrl + 'ajax/chapters/', - { method: 'POST' }) - .then(res => res.text()); - } - - if (html !== '0') { - loadedCheerio = parseHTML(html); - } - - const chapters: Chapter.Item[] = []; - loadedCheerio('.wp-manga-chapter').each(function () { - const chapterName = loadedCheerio(this).find('a').text().trim(); - - let releaseDate = null; - releaseDate = loadedCheerio(this) - .find('span.chapter-release-date') - .text() - .trim(); - - if (releaseDate) { - releaseDate = parseMadaraDate(releaseDate); + let url = this.site; + if (filters?.genres && this.options?.path?.genres) { + url += this.options?.path?.genres + filters.genres + '/'; } else { - /** - * Insert current date - */ - - releaseDate = dayjs().format('LL'); + url += this.options?.path?.novels ? this.options.path.novels : MadaraDefaultPath.novels; } + + url += '/page/' + pageNo + '/' + + '?m_orderby=' + (showLatestNovels ? 'latest' : (filters?.sort || 'rating')); + + const body = await fetchApi(url).then(res => res.text()); + + const loadedCheerio = parseHTML(body); + + loadedCheerio('.manga-title-badges').remove(); + + loadedCheerio('.page-item-detail').each(function () { + const novelName = loadedCheerio(this).find('.post-title').text().trim(); + let image = loadedCheerio(this).find('img'); + const novelCover = image.attr('data-src') || image.attr('src'); + + let novelUrl = loadedCheerio(this).find('.post-title') + .find('a') + .attr('href') || ''; + const novel: Plugin.NovelItem = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + + novels.push(novel); + }); + + return novels; + } + async parseNovelAndChapters(novelUrl: string): Promise { + const novel: Plugin.SourceNovel = { + url: novelUrl, + }; + + const body = await fetchApi(novelUrl).then(res => res.text()); + + let loadedCheerio = parseHTML(body); + + loadedCheerio('.manga-title-badges, #manga-title span').remove(); + novel.name = + loadedCheerio('.post-title h1').text().trim() || + loadedCheerio('#manga-title h1').text(); + + novel.cover = + loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || + loadedCheerio('.summary_image > a > img').attr('data-src') || + loadedCheerio('.summary_image > a > img').attr('src') || + defaultCover; + + loadedCheerio('.post-content_item, .post-content').each(function () { + const detailName = loadedCheerio(this).find('h5').text().trim(); + const detail = loadedCheerio(this).find('.summary-content').text().trim(); + + switch (detailName) { + case 'Genre(s)': + case 'التصنيفات': + novel.genres = detail.replace(/[\\t\\n]/g, ','); + break; + case 'Author(s)': + case 'المؤلف': + case 'المؤلف (ين)': + novel.author = detail; + break; + case 'Status': + case 'الحالة': + novel.status = + detail.includes('OnGoing') || detail.includes('مستمرة') + ? NovelStatus.Ongoing + : NovelStatus.Completed; + break; + } + }); + + loadedCheerio('div.summary__content .code-block,script').remove(); + novel.summary = + loadedCheerio('div.summary__content').text().trim() || + loadedCheerio('#tab-manga-about').text().trim() || + loadedCheerio('.post-content_item h5:contains("Summary")').next().text().trim(); + + let html; + + if (this.options?.useNewChapterEndpoint !== true) { + const novelId = + loadedCheerio('.rating-post-id').attr('value') || + loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; + + const formData = new FormData() + formData.append("action", "manga_get_chapters"); + formData.append("manga", novelId); - let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + html = await fetchApi( + this.site + 'wp-admin/admin-ajax.php', + { + method: 'POST', + body: formData, + }) + .then(res => res.text()); + } else { + html = await fetchApi( + novelUrl + 'ajax/chapters/', + { method: 'POST' }) + .then(res => res.text()); + } + + if (html !== '0') { + loadedCheerio = parseHTML(html); + } + + const chapters: Plugin.ChapterItem[] = []; + loadedCheerio('.wp-manga-chapter').each(function () { + const chapterName = loadedCheerio(this).find('a').text().trim(); + + let releaseDate = null; + releaseDate = loadedCheerio(this) + .find('span.chapter-release-date') + .text() + .trim(); + + if (releaseDate) { + releaseDate = parseMadaraDate(releaseDate); + } else { + /** + * Insert current date + */ + + releaseDate = dayjs().format('LL'); + } + + let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + + chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); + }); + + novel.chapters = chapters.reverse(); + return novel; + } + async parseChapter(chapterUrl: string): Promise { + const body = await fetchApi(chapterUrl).then(res => res.text()); - chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); - }); + const loadedCheerio = parseHTML(body); + const chapterText = + loadedCheerio('.text-left').html() || + loadedCheerio('.text-right').html() || + loadedCheerio('.entry-content').html() || ""; - novel.chapters = chapters.reverse(); - return novel; -}; - -export const parseChapter: Plugin.parseChapter = async (chapterUrl) => { - const url = baseUrl + "/" + "series" + "/" + chapterUrl; - - const body = await fetchApi(chapterUrl).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - const chapterText = - loadedCheerio('.text-left').html() || - loadedCheerio('.text-right').html() || - loadedCheerio('.entry-content').html(); - - return chapterText; -}; - -export const searchNovels: Plugin.searchNovels = async (searchTerm) => { - const novels: Novel.Item[] = []; - const url = baseUrl + "?s=" + searchTerm + "&post_type=wp-manga"; - - const body = await fetchApi(url).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - - - loadedCheerio('.c-tabs-item__content').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - - let novelUrl = loadedCheerio(this) - .find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - - novels.push(novel); - }); - return novels; -}; - -export const fetchImage: Plugin.fetchImage = async (url) => { - return await fetchFile(url); -}; - -export const filters = [{"key":"sort","label":"Order by","values":[{"label":"Rating","value":"rating"},{"label":"A-Z","value":"alphabet"},{"label":"Latest","value":"latest"},{"label":"Most Views","value":"views"},{"label":"New","value":"new-manga"},{"label":"Trending","value":"trending"}],"inputType":FilterInputs.Picker}]; \ No newline at end of file + return chapterText; + } + async searchNovels(searchTerm: string, pageNo?: number | undefined): Promise { + const novels: Plugin.NovelItem[] = []; + const url = this.site + "?s=" + searchTerm + "&post_type=wp-manga"; + + const body = await fetchApi(url).then(res => res.text()); + + const loadedCheerio = parseHTML(body); + + + loadedCheerio('.c-tabs-item__content').each(function () { + const novelName = loadedCheerio(this).find('.post-title').text().trim(); + + let image = loadedCheerio(this).find('img'); + const novelCover = image.attr('data-src') || image.attr('src'); + + let novelUrl = loadedCheerio(this) + .find('.post-title') + .find('a') + .attr('href') || ''; + const novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + + novels.push(novel); + }); + return novels; + } + async fetchImage(url: string): Promise { + return await fetchFile(url, {}); + } +} +const plugin = new MadaraPlugin({"id":"sleeptTLS","sourceSite":"https://sleepytranslations.com/","sourceName":"SleepyTranslations","filters":[{"key":"sort","label":"Order by","values":[{"label":"Rating","value":"rating"},{"label":"A-Z","value":"alphabet"},{"label":"Latest","value":"latest"},{"label":"Most Views","value":"views"},{"label":"New","value":"new-manga"},{"label":"Trending","value":"trending"}],"inputType":"Picker"}],"options":{"path":{"novels":"series","novel":"series","chapter":"series"},"useNewChapterEndpoint":true,"lang":"English"}}); +export default plugin; + \ No newline at end of file diff --git a/plugins/english/SonicMTL[madara].ts b/plugins/english/SonicMTL[madara].ts index 6d21056..71a73e1 100644 --- a/plugins/english/SonicMTL[madara].ts +++ b/plugins/english/SonicMTL[madara].ts @@ -1,213 +1,252 @@ +import { fetchApi, fetchFile } from "@libs/fetch"; +import { Filter } from "@libs/filterInputs"; +import { Plugin } from '@typings/plugin' import { load as parseHTML } from "cheerio"; -import { fetchFile, fetchApi } from "@libs/fetch"; -import { Novel, Plugin, Chapter } from "@typings/plugin"; -import { FilterInputs } from "@libs/filterInputs"; import { defaultCover } from "@libs/defaultCover"; -import { NovelStatus } from "@libs/novelStatus" +import { NovelStatus } from "@libs/novelStatus"; import { parseMadaraDate } from "@libs/parseMadaraDate"; import dayjs from "dayjs"; -export const id = "sonicmtl"; -export const name = "SonicMTL [madara]"; -export const icon = "multisrc/madara/icons/sonicmtl.png"; -export const version = "1.0.0"; -export const site = "https://www.sonicmtl.com/"; -const baseUrl = site; +interface MadaraOptionPath{ + genres?: string, + novels?: string, + novel?: string, + chapter?: string, +} -export const popularNovels: Plugin.popularNovels = async (pageNo, {filters, showLatestNovels}) => { - const novels: Novel.Item[] = []; +const MadaraDefaultPath: MadaraOptionPath = { + novels: 'novel', + novel: 'novel', + chapter: 'novel' +} - let url = site; +interface MadaraOptions { + useNewChapterEndpoint?: boolean, + path?: MadaraOptionPath, + lang?: string, + orderBy?: string +} - if (filters?.genres) { - url += "novel-genre/" + filters.genres + '/'; - } else { - url += "novel/"; +export interface MadaraMetadata { + id: string, + sourceSite: string, + sourceName: string, + options?: MadaraOptions, + filters?: Filter[], +} +class MadaraPlugin implements Plugin.PluginBase { + id: string; + name: string; + icon: string; + site: string; + version: string; + userAgent: string; + cookieString: string; + options?: MadaraOptions; + filter?: Filter[] | undefined; + + constructor(metadata: MadaraMetadata){ + this.id = metadata.id; + this.name = metadata.sourceName + "[madara]"; + const iconFileName = metadata.sourceName.replace(/\s+/g, "").toLowerCase(); + this.icon = `multisrc/madara/icons/${iconFileName}.png`; + this.site = metadata.sourceSite; + this.version = "1.0.0"; + this.userAgent = ""; + this.cookieString = ""; + this.options = metadata.options; + this.filter = metadata.filters; } + async popularNovels(pageNo: number, {filters, showLatestNovels}: Plugin.PopularNovelsOptions): Promise { + const novels: Plugin.NovelItem[] = []; - url += '/page/' + pageNo + '/' + - '?m_orderby=' + (showLatestNovels ? 'latest' : (filters?.sort || 'rating')); - - const body = await fetchApi(url).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - - loadedCheerio('.manga-title-badges').remove(); - - loadedCheerio('.page-item-detail').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - - let novelUrl = loadedCheerio(this).find('.post-title') - .find('a') - .attr('href') || ''; - const novel: Novel.Item = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - - novels.push(novel); - }); - - return novels; -}; - -export const parseNovelAndChapters: Plugin.parseNovelAndChapters = async ( - novelUrl -) => { - const novel: Novel.instance = { - url: novelUrl, - }; - - const body = await fetchApi(novelUrl).then(res => res.text()); - - let loadedCheerio = parseHTML(body); - - loadedCheerio('.manga-title-badges').remove(); - - novel.name = loadedCheerio('.post-title h1').text().trim(); - - novel.cover = - loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || - loadedCheerio('.summary_image > a > img').attr('data-src') || - loadedCheerio('.summary_image > a > img').attr('src') || - defaultCover; - - loadedCheerio('.post-content_item, .post-content').each(function () { - const detailName = loadedCheerio(this).find('h5').text().trim(); - const detail = loadedCheerio(this).find('.summary-content').text().trim(); - - switch (detailName) { - case 'Genre(s)': - case 'التصنيفات': - novel.genres = detail.replace(/[\t\n]/g, ','); - break; - case 'Author(s)': - case 'المؤلف': - case 'المؤلف (ين)': - novel.author = detail; - break; - case 'Status': - case 'الحالة': - novel.status = - detail.includes('OnGoing') || detail.includes('مستمرة') - ? NovelStatus.Ongoing - : NovelStatus.Completed; - break; - } - }); - - loadedCheerio('div.summary__content .code-block,script').remove(); - novel.summary = loadedCheerio('div.summary__content').text().trim(); - - - let html; - - if (true) { - const novelId = - loadedCheerio('.rating-post-id').attr('value') || - loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; - - const body = { - action: "manga_get_chapters", - manga: novelId, - } - html = await fetchApi( - baseUrl + 'wp-admin/admin-ajax.php', - { - method: 'POST', - body: JSON.stringify(body), - }) - .then(res => res.text()); - } else { - html = await fetchApi( - baseUrl + 'ajax/chapters/', - { method: 'POST' }) - .then(res => res.text()); - } - - if (html !== '0') { - loadedCheerio = parseHTML(html); - } - - const chapters: Chapter.Item[] = []; - loadedCheerio('.wp-manga-chapter').each(function () { - const chapterName = loadedCheerio(this).find('a').text().trim(); - - let releaseDate = null; - releaseDate = loadedCheerio(this) - .find('span.chapter-release-date') - .text() - .trim(); - - if (releaseDate) { - releaseDate = parseMadaraDate(releaseDate); + let url = this.site; + if (filters?.genres && this.options?.path?.genres) { + url += this.options?.path?.genres + filters.genres + '/'; } else { - /** - * Insert current date - */ - - releaseDate = dayjs().format('LL'); + url += this.options?.path?.novels ? this.options.path.novels : MadaraDefaultPath.novels; } + + url += '/page/' + pageNo + '/' + + '?m_orderby=' + (showLatestNovels ? 'latest' : (filters?.sort || 'rating')); + + const body = await fetchApi(url).then(res => res.text()); + + const loadedCheerio = parseHTML(body); + + loadedCheerio('.manga-title-badges').remove(); + + loadedCheerio('.page-item-detail').each(function () { + const novelName = loadedCheerio(this).find('.post-title').text().trim(); + let image = loadedCheerio(this).find('img'); + const novelCover = image.attr('data-src') || image.attr('src'); + + let novelUrl = loadedCheerio(this).find('.post-title') + .find('a') + .attr('href') || ''; + const novel: Plugin.NovelItem = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + + novels.push(novel); + }); + + return novels; + } + async parseNovelAndChapters(novelUrl: string): Promise { + const novel: Plugin.SourceNovel = { + url: novelUrl, + }; + + const body = await fetchApi(novelUrl).then(res => res.text()); + + let loadedCheerio = parseHTML(body); + + loadedCheerio('.manga-title-badges, #manga-title span').remove(); + novel.name = + loadedCheerio('.post-title h1').text().trim() || + loadedCheerio('#manga-title h1').text(); + + novel.cover = + loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || + loadedCheerio('.summary_image > a > img').attr('data-src') || + loadedCheerio('.summary_image > a > img').attr('src') || + defaultCover; + + loadedCheerio('.post-content_item, .post-content').each(function () { + const detailName = loadedCheerio(this).find('h5').text().trim(); + const detail = loadedCheerio(this).find('.summary-content').text().trim(); + + switch (detailName) { + case 'Genre(s)': + case 'التصنيفات': + novel.genres = detail.replace(/[\\t\\n]/g, ','); + break; + case 'Author(s)': + case 'المؤلف': + case 'المؤلف (ين)': + novel.author = detail; + break; + case 'Status': + case 'الحالة': + novel.status = + detail.includes('OnGoing') || detail.includes('مستمرة') + ? NovelStatus.Ongoing + : NovelStatus.Completed; + break; + } + }); + + loadedCheerio('div.summary__content .code-block,script').remove(); + novel.summary = + loadedCheerio('div.summary__content').text().trim() || + loadedCheerio('#tab-manga-about').text().trim() || + loadedCheerio('.post-content_item h5:contains("Summary")').next().text().trim(); + + let html; + + if (this.options?.useNewChapterEndpoint !== true) { + const novelId = + loadedCheerio('.rating-post-id').attr('value') || + loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; + + const formData = new FormData() + formData.append("action", "manga_get_chapters"); + formData.append("manga", novelId); - let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + html = await fetchApi( + this.site + 'wp-admin/admin-ajax.php', + { + method: 'POST', + body: formData, + }) + .then(res => res.text()); + } else { + html = await fetchApi( + novelUrl + 'ajax/chapters/', + { method: 'POST' }) + .then(res => res.text()); + } + + if (html !== '0') { + loadedCheerio = parseHTML(html); + } + + const chapters: Plugin.ChapterItem[] = []; + loadedCheerio('.wp-manga-chapter').each(function () { + const chapterName = loadedCheerio(this).find('a').text().trim(); + + let releaseDate = null; + releaseDate = loadedCheerio(this) + .find('span.chapter-release-date') + .text() + .trim(); + + if (releaseDate) { + releaseDate = parseMadaraDate(releaseDate); + } else { + /** + * Insert current date + */ + + releaseDate = dayjs().format('LL'); + } + + let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + + chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); + }); + + novel.chapters = chapters.reverse(); + return novel; + } + async parseChapter(chapterUrl: string): Promise { + const body = await fetchApi(chapterUrl).then(res => res.text()); - chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); - }); + const loadedCheerio = parseHTML(body); + const chapterText = + loadedCheerio('.text-left').html() || + loadedCheerio('.text-right').html() || + loadedCheerio('.entry-content').html() || ""; - novel.chapters = chapters.reverse(); - return novel; -}; - -export const parseChapter: Plugin.parseChapter = async (chapterUrl) => { - const url = baseUrl + "/" + "novel" + "/" + chapterUrl; - - const body = await fetchApi(chapterUrl).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - const chapterText = - loadedCheerio('.text-left').html() || - loadedCheerio('.text-right').html() || - loadedCheerio('.entry-content').html(); - - return chapterText; -}; - -export const searchNovels: Plugin.searchNovels = async (searchTerm) => { - const novels: Novel.Item[] = []; - const url = baseUrl + "?s=" + searchTerm + "&post_type=wp-manga"; - - const body = await fetchApi(url).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - - - loadedCheerio('.c-tabs-item__content').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - - let novelUrl = loadedCheerio(this) - .find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - - novels.push(novel); - }); - return novels; -}; - -export const fetchImage: Plugin.fetchImage = async (url) => { - return await fetchFile(url); -}; - -export const filters = [{"key":"sort","label":"Order by","values":[{"label":"Rating","value":"rating"},{"label":"A-Z","value":"alphabet"},{"label":"Latest","value":"latest"},{"label":"Most Views","value":"views"},{"label":"New","value":"new-manga"},{"label":"Trending","value":"trending"}],"inputType":FilterInputs.Picker},{"key":"genres","label":"GENRES","values":[{"label":"Action","value":"action"},{"label":"Adult","value":"adult"},{"label":"Adventure","value":"adventure"},{"label":"Comedy","value":"comedy"},{"label":"Cooking","value":"cooking"},{"label":"Detective","value":"detective"},{"label":"Doujinshi","value":"doujinshi"},{"label":"Drama","value":"drama"},{"label":"Ecchi","value":"ecchi"},{"label":"Fan-Fiction","value":"fan-fiction"},{"label":"Fantasy","value":"fantasy"},{"label":"Gender Bender","value":"gender-bender"},{"label":"Harem","value":"harem"},{"label":"Historical","value":"historical"},{"label":"Horror","value":"horror"},{"label":"Josei","value":"josei"},{"label":"Live action","value":"live-action"},{"label":"Manga","value":"manga"},{"label":"Manhua","value":"manhua"},{"label":"Manhwa","value":"manhwa"},{"label":"Martial Arts","value":"martial-arts"},{"label":"Mature","value":"mature"},{"label":"Mecha","value":"mecha"},{"label":"Mystery","value":"mystery"},{"label":"One shot","value":"one-shot"},{"label":"Psychological","value":"psychological"},{"label":"Romance","value":"romance"},{"label":"School Life","value":"school-life"},{"label":"Sci-fi","value":"sci-fi"},{"label":"Seinen","value":"seinen"},{"label":"Shoujo","value":"shoujo"},{"label":"Shoujo Ai","value":"shoujo-ai"},{"label":"Shounen","value":"shounen"},{"label":"Shounen Ai","value":"shounen-ai"},{"label":"Slice of Life","value":"slice-of-life"},{"label":"Smut","value":"smut"},{"label":"Soft Yaoi","value":"soft-yaoi"},{"label":"Soft Yuri","value":"soft-yuri"},{"label":"Sports","value":"sports"},{"label":"Supernatural","value":"supernatural"},{"label":"Tragedy","value":"tragedy"},{"label":"Urban Life","value":"urban-life"},{"label":"Wuxia","value":"wuxia"},{"label":"Xianxia","value":"xianxia"},{"label":"Xuanhuan","value":"xuanhuan"},{"label":"Yaoi","value":"yaoi"},{"label":"Yuri","value":"yuri"}],"inputType":FilterInputs.Picker}]; \ No newline at end of file + return chapterText; + } + async searchNovels(searchTerm: string, pageNo?: number | undefined): Promise { + const novels: Plugin.NovelItem[] = []; + const url = this.site + "?s=" + searchTerm + "&post_type=wp-manga"; + + const body = await fetchApi(url).then(res => res.text()); + + const loadedCheerio = parseHTML(body); + + + loadedCheerio('.c-tabs-item__content').each(function () { + const novelName = loadedCheerio(this).find('.post-title').text().trim(); + + let image = loadedCheerio(this).find('img'); + const novelCover = image.attr('data-src') || image.attr('src'); + + let novelUrl = loadedCheerio(this) + .find('.post-title') + .find('a') + .attr('href') || ''; + const novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + + novels.push(novel); + }); + return novels; + } + async fetchImage(url: string): Promise { + return await fetchFile(url, {}); + } +} +const plugin = new MadaraPlugin({"id":"sonicmtl","sourceSite":"https://www.sonicmtl.com/","sourceName":"SonicMTL","filters":[{"key":"sort","label":"Order by","values":[{"label":"Rating","value":"rating"},{"label":"A-Z","value":"alphabet"},{"label":"Latest","value":"latest"},{"label":"Most Views","value":"views"},{"label":"New","value":"new-manga"},{"label":"Trending","value":"trending"}],"inputType":"Picker"},{"key":"genres","label":"GENRES","values":[{"label":"Action","value":"action"},{"label":"Adult","value":"adult"},{"label":"Adventure","value":"adventure"},{"label":"Comedy","value":"comedy"},{"label":"Cooking","value":"cooking"},{"label":"Detective","value":"detective"},{"label":"Doujinshi","value":"doujinshi"},{"label":"Drama","value":"drama"},{"label":"Ecchi","value":"ecchi"},{"label":"Fan-Fiction","value":"fan-fiction"},{"label":"Fantasy","value":"fantasy"},{"label":"Gender Bender","value":"gender-bender"},{"label":"Harem","value":"harem"},{"label":"Historical","value":"historical"},{"label":"Horror","value":"horror"},{"label":"Josei","value":"josei"},{"label":"Live action","value":"live-action"},{"label":"Manga","value":"manga"},{"label":"Manhua","value":"manhua"},{"label":"Manhwa","value":"manhwa"},{"label":"Martial Arts","value":"martial-arts"},{"label":"Mature","value":"mature"},{"label":"Mecha","value":"mecha"},{"label":"Mystery","value":"mystery"},{"label":"One shot","value":"one-shot"},{"label":"Psychological","value":"psychological"},{"label":"Romance","value":"romance"},{"label":"School Life","value":"school-life"},{"label":"Sci-fi","value":"sci-fi"},{"label":"Seinen","value":"seinen"},{"label":"Shoujo","value":"shoujo"},{"label":"Shoujo Ai","value":"shoujo-ai"},{"label":"Shounen","value":"shounen"},{"label":"Shounen Ai","value":"shounen-ai"},{"label":"Slice of Life","value":"slice-of-life"},{"label":"Smut","value":"smut"},{"label":"Soft Yaoi","value":"soft-yaoi"},{"label":"Soft Yuri","value":"soft-yuri"},{"label":"Sports","value":"sports"},{"label":"Supernatural","value":"supernatural"},{"label":"Tragedy","value":"tragedy"},{"label":"Urban Life","value":"urban-life"},{"label":"Wuxia","value":"wuxia"},{"label":"Xianxia","value":"xianxia"},{"label":"Xuanhuan","value":"xuanhuan"},{"label":"Yaoi","value":"yaoi"},{"label":"Yuri","value":"yuri"}],"inputType":"Picker"}],"options":{"useNewChapterEndpoint":true,"lang":"English"}}); +export default plugin; + \ No newline at end of file diff --git a/plugins/english/SugarBabies[madara].ts b/plugins/english/SugarBabies[madara].ts index 4b13e63..9db8cc7 100644 --- a/plugins/english/SugarBabies[madara].ts +++ b/plugins/english/SugarBabies[madara].ts @@ -1,213 +1,252 @@ +import { fetchApi, fetchFile } from "@libs/fetch"; +import { Filter } from "@libs/filterInputs"; +import { Plugin } from '@typings/plugin' import { load as parseHTML } from "cheerio"; -import { fetchFile, fetchApi } from "@libs/fetch"; -import { Novel, Plugin, Chapter } from "@typings/plugin"; -import { FilterInputs } from "@libs/filterInputs"; import { defaultCover } from "@libs/defaultCover"; -import { NovelStatus } from "@libs/novelStatus" +import { NovelStatus } from "@libs/novelStatus"; import { parseMadaraDate } from "@libs/parseMadaraDate"; import dayjs from "dayjs"; -export const id = "sugarbbscan"; -export const name = "Sugar Babies [madara]"; -export const icon = "multisrc/madara/icons/sugarbabies.png"; -export const version = "1.0.0"; -export const site = "https://sugarbbscan.com/"; -const baseUrl = site; +interface MadaraOptionPath{ + genres?: string, + novels?: string, + novel?: string, + chapter?: string, +} -export const popularNovels: Plugin.popularNovels = async (pageNo, {filters, showLatestNovels}) => { - const novels: Novel.Item[] = []; +const MadaraDefaultPath: MadaraOptionPath = { + novels: 'novel', + novel: 'novel', + chapter: 'novel' +} - let url = site; +interface MadaraOptions { + useNewChapterEndpoint?: boolean, + path?: MadaraOptionPath, + lang?: string, + orderBy?: string +} - if (filters?.genres) { - url += "novel-genre/" + filters.genres + '/'; - } else { - url += "series/"; +export interface MadaraMetadata { + id: string, + sourceSite: string, + sourceName: string, + options?: MadaraOptions, + filters?: Filter[], +} +class MadaraPlugin implements Plugin.PluginBase { + id: string; + name: string; + icon: string; + site: string; + version: string; + userAgent: string; + cookieString: string; + options?: MadaraOptions; + filter?: Filter[] | undefined; + + constructor(metadata: MadaraMetadata){ + this.id = metadata.id; + this.name = metadata.sourceName + "[madara]"; + const iconFileName = metadata.sourceName.replace(/\s+/g, "").toLowerCase(); + this.icon = `multisrc/madara/icons/${iconFileName}.png`; + this.site = metadata.sourceSite; + this.version = "1.0.0"; + this.userAgent = ""; + this.cookieString = ""; + this.options = metadata.options; + this.filter = metadata.filters; } + async popularNovels(pageNo: number, {filters, showLatestNovels}: Plugin.PopularNovelsOptions): Promise { + const novels: Plugin.NovelItem[] = []; - url += '/page/' + pageNo + '/' + - '?m_orderby=' + (showLatestNovels ? 'latest' : (filters?.sort || 'rating')); - - const body = await fetchApi(url).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - - loadedCheerio('.manga-title-badges').remove(); - - loadedCheerio('.page-item-detail').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - - let novelUrl = loadedCheerio(this).find('.post-title') - .find('a') - .attr('href') || ''; - const novel: Novel.Item = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - - novels.push(novel); - }); - - return novels; -}; - -export const parseNovelAndChapters: Plugin.parseNovelAndChapters = async ( - novelUrl -) => { - const novel: Novel.instance = { - url: novelUrl, - }; - - const body = await fetchApi(novelUrl).then(res => res.text()); - - let loadedCheerio = parseHTML(body); - - loadedCheerio('.manga-title-badges').remove(); - - novel.name = loadedCheerio('.post-title h1').text().trim(); - - novel.cover = - loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || - loadedCheerio('.summary_image > a > img').attr('data-src') || - loadedCheerio('.summary_image > a > img').attr('src') || - defaultCover; - - loadedCheerio('.post-content_item, .post-content').each(function () { - const detailName = loadedCheerio(this).find('h5').text().trim(); - const detail = loadedCheerio(this).find('.summary-content').text().trim(); - - switch (detailName) { - case 'Genre(s)': - case 'التصنيفات': - novel.genres = detail.replace(/[\t\n]/g, ','); - break; - case 'Author(s)': - case 'المؤلف': - case 'المؤلف (ين)': - novel.author = detail; - break; - case 'Status': - case 'الحالة': - novel.status = - detail.includes('OnGoing') || detail.includes('مستمرة') - ? NovelStatus.Ongoing - : NovelStatus.Completed; - break; - } - }); - - loadedCheerio('div.summary__content .code-block,script').remove(); - novel.summary = loadedCheerio('div.summary__content').text().trim(); - - - let html; - - if (false) { - const novelId = - loadedCheerio('.rating-post-id').attr('value') || - loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; - - const body = { - action: "manga_get_chapters", - manga: novelId, - } - html = await fetchApi( - baseUrl + 'wp-admin/admin-ajax.php', - { - method: 'POST', - body: JSON.stringify(body), - }) - .then(res => res.text()); - } else { - html = await fetchApi( - baseUrl + 'ajax/chapters/', - { method: 'POST' }) - .then(res => res.text()); - } - - if (html !== '0') { - loadedCheerio = parseHTML(html); - } - - const chapters: Chapter.Item[] = []; - loadedCheerio('.wp-manga-chapter').each(function () { - const chapterName = loadedCheerio(this).find('a').text().trim(); - - let releaseDate = null; - releaseDate = loadedCheerio(this) - .find('span.chapter-release-date') - .text() - .trim(); - - if (releaseDate) { - releaseDate = parseMadaraDate(releaseDate); + let url = this.site; + if (filters?.genres && this.options?.path?.genres) { + url += this.options?.path?.genres + filters.genres + '/'; } else { - /** - * Insert current date - */ - - releaseDate = dayjs().format('LL'); + url += this.options?.path?.novels ? this.options.path.novels : MadaraDefaultPath.novels; } + + url += '/page/' + pageNo + '/' + + '?m_orderby=' + (showLatestNovels ? 'latest' : (filters?.sort || 'rating')); + + const body = await fetchApi(url).then(res => res.text()); + + const loadedCheerio = parseHTML(body); + + loadedCheerio('.manga-title-badges').remove(); + + loadedCheerio('.page-item-detail').each(function () { + const novelName = loadedCheerio(this).find('.post-title').text().trim(); + let image = loadedCheerio(this).find('img'); + const novelCover = image.attr('data-src') || image.attr('src'); + + let novelUrl = loadedCheerio(this).find('.post-title') + .find('a') + .attr('href') || ''; + const novel: Plugin.NovelItem = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + + novels.push(novel); + }); + + return novels; + } + async parseNovelAndChapters(novelUrl: string): Promise { + const novel: Plugin.SourceNovel = { + url: novelUrl, + }; + + const body = await fetchApi(novelUrl).then(res => res.text()); + + let loadedCheerio = parseHTML(body); + + loadedCheerio('.manga-title-badges, #manga-title span').remove(); + novel.name = + loadedCheerio('.post-title h1').text().trim() || + loadedCheerio('#manga-title h1').text(); + + novel.cover = + loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || + loadedCheerio('.summary_image > a > img').attr('data-src') || + loadedCheerio('.summary_image > a > img').attr('src') || + defaultCover; + + loadedCheerio('.post-content_item, .post-content').each(function () { + const detailName = loadedCheerio(this).find('h5').text().trim(); + const detail = loadedCheerio(this).find('.summary-content').text().trim(); + + switch (detailName) { + case 'Genre(s)': + case 'التصنيفات': + novel.genres = detail.replace(/[\\t\\n]/g, ','); + break; + case 'Author(s)': + case 'المؤلف': + case 'المؤلف (ين)': + novel.author = detail; + break; + case 'Status': + case 'الحالة': + novel.status = + detail.includes('OnGoing') || detail.includes('مستمرة') + ? NovelStatus.Ongoing + : NovelStatus.Completed; + break; + } + }); + + loadedCheerio('div.summary__content .code-block,script').remove(); + novel.summary = + loadedCheerio('div.summary__content').text().trim() || + loadedCheerio('#tab-manga-about').text().trim() || + loadedCheerio('.post-content_item h5:contains("Summary")').next().text().trim(); + + let html; + + if (this.options?.useNewChapterEndpoint !== true) { + const novelId = + loadedCheerio('.rating-post-id').attr('value') || + loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; + + const formData = new FormData() + formData.append("action", "manga_get_chapters"); + formData.append("manga", novelId); - let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + html = await fetchApi( + this.site + 'wp-admin/admin-ajax.php', + { + method: 'POST', + body: formData, + }) + .then(res => res.text()); + } else { + html = await fetchApi( + novelUrl + 'ajax/chapters/', + { method: 'POST' }) + .then(res => res.text()); + } + + if (html !== '0') { + loadedCheerio = parseHTML(html); + } + + const chapters: Plugin.ChapterItem[] = []; + loadedCheerio('.wp-manga-chapter').each(function () { + const chapterName = loadedCheerio(this).find('a').text().trim(); + + let releaseDate = null; + releaseDate = loadedCheerio(this) + .find('span.chapter-release-date') + .text() + .trim(); + + if (releaseDate) { + releaseDate = parseMadaraDate(releaseDate); + } else { + /** + * Insert current date + */ + + releaseDate = dayjs().format('LL'); + } + + let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + + chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); + }); + + novel.chapters = chapters.reverse(); + return novel; + } + async parseChapter(chapterUrl: string): Promise { + const body = await fetchApi(chapterUrl).then(res => res.text()); - chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); - }); + const loadedCheerio = parseHTML(body); + const chapterText = + loadedCheerio('.text-left').html() || + loadedCheerio('.text-right').html() || + loadedCheerio('.entry-content').html() || ""; - novel.chapters = chapters.reverse(); - return novel; -}; - -export const parseChapter: Plugin.parseChapter = async (chapterUrl) => { - const url = baseUrl + "/" + "series" + "/" + chapterUrl; - - const body = await fetchApi(chapterUrl).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - const chapterText = - loadedCheerio('.text-left').html() || - loadedCheerio('.text-right').html() || - loadedCheerio('.entry-content').html(); - - return chapterText; -}; - -export const searchNovels: Plugin.searchNovels = async (searchTerm) => { - const novels: Novel.Item[] = []; - const url = baseUrl + "?s=" + searchTerm + "&post_type=wp-manga"; - - const body = await fetchApi(url).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - - - loadedCheerio('.c-tabs-item__content').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - - let novelUrl = loadedCheerio(this) - .find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - - novels.push(novel); - }); - return novels; -}; - -export const fetchImage: Plugin.fetchImage = async (url) => { - return await fetchFile(url); -}; - -export const filters = []; \ No newline at end of file + return chapterText; + } + async searchNovels(searchTerm: string, pageNo?: number | undefined): Promise { + const novels: Plugin.NovelItem[] = []; + const url = this.site + "?s=" + searchTerm + "&post_type=wp-manga"; + + const body = await fetchApi(url).then(res => res.text()); + + const loadedCheerio = parseHTML(body); + + + loadedCheerio('.c-tabs-item__content').each(function () { + const novelName = loadedCheerio(this).find('.post-title').text().trim(); + + let image = loadedCheerio(this).find('img'); + const novelCover = image.attr('data-src') || image.attr('src'); + + let novelUrl = loadedCheerio(this) + .find('.post-title') + .find('a') + .attr('href') || ''; + const novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + + novels.push(novel); + }); + return novels; + } + async fetchImage(url: string): Promise { + return await fetchFile(url, {}); + } +} +const plugin = new MadaraPlugin({"id":"sugarbbscan","sourceSite":"https://sugarbbscan.com/","sourceName":"Sugar Babies","filters":[],"options":{"path":{"novels":"series","novel":"series","chapter":"series"},"lang":"English"}}); +export default plugin; + \ No newline at end of file diff --git a/plugins/english/SweetEscapeTranslations[madara].ts b/plugins/english/SweetEscapeTranslations[madara].ts index d6b8a0b..fc1922f 100644 --- a/plugins/english/SweetEscapeTranslations[madara].ts +++ b/plugins/english/SweetEscapeTranslations[madara].ts @@ -1,213 +1,252 @@ +import { fetchApi, fetchFile } from "@libs/fetch"; +import { Filter } from "@libs/filterInputs"; +import { Plugin } from '@typings/plugin' import { load as parseHTML } from "cheerio"; -import { fetchFile, fetchApi } from "@libs/fetch"; -import { Novel, Plugin, Chapter } from "@typings/plugin"; -import { FilterInputs } from "@libs/filterInputs"; import { defaultCover } from "@libs/defaultCover"; -import { NovelStatus } from "@libs/novelStatus" +import { NovelStatus } from "@libs/novelStatus"; import { parseMadaraDate } from "@libs/parseMadaraDate"; import dayjs from "dayjs"; -export const id = "sweetEscapeTL"; -export const name = "Sweet Escape Translations [madara]"; -export const icon = "multisrc/madara/icons/sweetescapetranslations.png"; -export const version = "1.0.0"; -export const site = "https://sweetescapetranslations.com/"; -const baseUrl = site; +interface MadaraOptionPath{ + genres?: string, + novels?: string, + novel?: string, + chapter?: string, +} -export const popularNovels: Plugin.popularNovels = async (pageNo, {filters, showLatestNovels}) => { - const novels: Novel.Item[] = []; +const MadaraDefaultPath: MadaraOptionPath = { + novels: 'novel', + novel: 'novel', + chapter: 'novel' +} - let url = site; +interface MadaraOptions { + useNewChapterEndpoint?: boolean, + path?: MadaraOptionPath, + lang?: string, + orderBy?: string +} - if (filters?.genres) { - url += "manga-genre/" + filters.genres + '/'; - } else { - url += "manga/"; +export interface MadaraMetadata { + id: string, + sourceSite: string, + sourceName: string, + options?: MadaraOptions, + filters?: Filter[], +} +class MadaraPlugin implements Plugin.PluginBase { + id: string; + name: string; + icon: string; + site: string; + version: string; + userAgent: string; + cookieString: string; + options?: MadaraOptions; + filter?: Filter[] | undefined; + + constructor(metadata: MadaraMetadata){ + this.id = metadata.id; + this.name = metadata.sourceName + "[madara]"; + const iconFileName = metadata.sourceName.replace(/\s+/g, "").toLowerCase(); + this.icon = `multisrc/madara/icons/${iconFileName}.png`; + this.site = metadata.sourceSite; + this.version = "1.0.0"; + this.userAgent = ""; + this.cookieString = ""; + this.options = metadata.options; + this.filter = metadata.filters; } + async popularNovels(pageNo: number, {filters, showLatestNovels}: Plugin.PopularNovelsOptions): Promise { + const novels: Plugin.NovelItem[] = []; - url += '/page/' + pageNo + '/' + - '?m_orderby=' + (showLatestNovels ? 'latest' : (filters?.sort || 'rating')); - - const body = await fetchApi(url).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - - loadedCheerio('.manga-title-badges').remove(); - - loadedCheerio('.page-item-detail').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - - let novelUrl = loadedCheerio(this).find('.post-title') - .find('a') - .attr('href') || ''; - const novel: Novel.Item = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - - novels.push(novel); - }); - - return novels; -}; - -export const parseNovelAndChapters: Plugin.parseNovelAndChapters = async ( - novelUrl -) => { - const novel: Novel.instance = { - url: novelUrl, - }; - - const body = await fetchApi(novelUrl).then(res => res.text()); - - let loadedCheerio = parseHTML(body); - - loadedCheerio('.manga-title-badges').remove(); - - novel.name = loadedCheerio('.post-title h1').text().trim(); - - novel.cover = - loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || - loadedCheerio('.summary_image > a > img').attr('data-src') || - loadedCheerio('.summary_image > a > img').attr('src') || - defaultCover; - - loadedCheerio('.post-content_item, .post-content').each(function () { - const detailName = loadedCheerio(this).find('h5').text().trim(); - const detail = loadedCheerio(this).find('.summary-content').text().trim(); - - switch (detailName) { - case 'Genre(s)': - case 'التصنيفات': - novel.genres = detail.replace(/[\t\n]/g, ','); - break; - case 'Author(s)': - case 'المؤلف': - case 'المؤلف (ين)': - novel.author = detail; - break; - case 'Status': - case 'الحالة': - novel.status = - detail.includes('OnGoing') || detail.includes('مستمرة') - ? NovelStatus.Ongoing - : NovelStatus.Completed; - break; - } - }); - - loadedCheerio('div.summary__content .code-block,script').remove(); - novel.summary = loadedCheerio('div.summary__content').text().trim(); - - - let html; - - if (false) { - const novelId = - loadedCheerio('.rating-post-id').attr('value') || - loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; - - const body = { - action: "manga_get_chapters", - manga: novelId, - } - html = await fetchApi( - baseUrl + 'wp-admin/admin-ajax.php', - { - method: 'POST', - body: JSON.stringify(body), - }) - .then(res => res.text()); - } else { - html = await fetchApi( - baseUrl + 'ajax/chapters/', - { method: 'POST' }) - .then(res => res.text()); - } - - if (html !== '0') { - loadedCheerio = parseHTML(html); - } - - const chapters: Chapter.Item[] = []; - loadedCheerio('.wp-manga-chapter').each(function () { - const chapterName = loadedCheerio(this).find('a').text().trim(); - - let releaseDate = null; - releaseDate = loadedCheerio(this) - .find('span.chapter-release-date') - .text() - .trim(); - - if (releaseDate) { - releaseDate = parseMadaraDate(releaseDate); + let url = this.site; + if (filters?.genres && this.options?.path?.genres) { + url += this.options?.path?.genres + filters.genres + '/'; } else { - /** - * Insert current date - */ - - releaseDate = dayjs().format('LL'); + url += this.options?.path?.novels ? this.options.path.novels : MadaraDefaultPath.novels; } + + url += '/page/' + pageNo + '/' + + '?m_orderby=' + (showLatestNovels ? 'latest' : (filters?.sort || 'rating')); + + const body = await fetchApi(url).then(res => res.text()); + + const loadedCheerio = parseHTML(body); + + loadedCheerio('.manga-title-badges').remove(); + + loadedCheerio('.page-item-detail').each(function () { + const novelName = loadedCheerio(this).find('.post-title').text().trim(); + let image = loadedCheerio(this).find('img'); + const novelCover = image.attr('data-src') || image.attr('src'); + + let novelUrl = loadedCheerio(this).find('.post-title') + .find('a') + .attr('href') || ''; + const novel: Plugin.NovelItem = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + + novels.push(novel); + }); + + return novels; + } + async parseNovelAndChapters(novelUrl: string): Promise { + const novel: Plugin.SourceNovel = { + url: novelUrl, + }; + + const body = await fetchApi(novelUrl).then(res => res.text()); + + let loadedCheerio = parseHTML(body); + + loadedCheerio('.manga-title-badges, #manga-title span').remove(); + novel.name = + loadedCheerio('.post-title h1').text().trim() || + loadedCheerio('#manga-title h1').text(); + + novel.cover = + loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || + loadedCheerio('.summary_image > a > img').attr('data-src') || + loadedCheerio('.summary_image > a > img').attr('src') || + defaultCover; + + loadedCheerio('.post-content_item, .post-content').each(function () { + const detailName = loadedCheerio(this).find('h5').text().trim(); + const detail = loadedCheerio(this).find('.summary-content').text().trim(); + + switch (detailName) { + case 'Genre(s)': + case 'التصنيفات': + novel.genres = detail.replace(/[\\t\\n]/g, ','); + break; + case 'Author(s)': + case 'المؤلف': + case 'المؤلف (ين)': + novel.author = detail; + break; + case 'Status': + case 'الحالة': + novel.status = + detail.includes('OnGoing') || detail.includes('مستمرة') + ? NovelStatus.Ongoing + : NovelStatus.Completed; + break; + } + }); + + loadedCheerio('div.summary__content .code-block,script').remove(); + novel.summary = + loadedCheerio('div.summary__content').text().trim() || + loadedCheerio('#tab-manga-about').text().trim() || + loadedCheerio('.post-content_item h5:contains("Summary")').next().text().trim(); + + let html; + + if (this.options?.useNewChapterEndpoint !== true) { + const novelId = + loadedCheerio('.rating-post-id').attr('value') || + loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; + + const formData = new FormData() + formData.append("action", "manga_get_chapters"); + formData.append("manga", novelId); - let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + html = await fetchApi( + this.site + 'wp-admin/admin-ajax.php', + { + method: 'POST', + body: formData, + }) + .then(res => res.text()); + } else { + html = await fetchApi( + novelUrl + 'ajax/chapters/', + { method: 'POST' }) + .then(res => res.text()); + } + + if (html !== '0') { + loadedCheerio = parseHTML(html); + } + + const chapters: Plugin.ChapterItem[] = []; + loadedCheerio('.wp-manga-chapter').each(function () { + const chapterName = loadedCheerio(this).find('a').text().trim(); + + let releaseDate = null; + releaseDate = loadedCheerio(this) + .find('span.chapter-release-date') + .text() + .trim(); + + if (releaseDate) { + releaseDate = parseMadaraDate(releaseDate); + } else { + /** + * Insert current date + */ + + releaseDate = dayjs().format('LL'); + } + + let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + + chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); + }); + + novel.chapters = chapters.reverse(); + return novel; + } + async parseChapter(chapterUrl: string): Promise { + const body = await fetchApi(chapterUrl).then(res => res.text()); - chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); - }); + const loadedCheerio = parseHTML(body); + const chapterText = + loadedCheerio('.text-left').html() || + loadedCheerio('.text-right').html() || + loadedCheerio('.entry-content').html() || ""; - novel.chapters = chapters.reverse(); - return novel; -}; - -export const parseChapter: Plugin.parseChapter = async (chapterUrl) => { - const url = baseUrl + "/" + "manga" + "/" + chapterUrl; - - const body = await fetchApi(chapterUrl).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - const chapterText = - loadedCheerio('.text-left').html() || - loadedCheerio('.text-right').html() || - loadedCheerio('.entry-content').html(); - - return chapterText; -}; - -export const searchNovels: Plugin.searchNovels = async (searchTerm) => { - const novels: Novel.Item[] = []; - const url = baseUrl + "?s=" + searchTerm + "&post_type=wp-manga"; - - const body = await fetchApi(url).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - - - loadedCheerio('.c-tabs-item__content').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - - let novelUrl = loadedCheerio(this) - .find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - - novels.push(novel); - }); - return novels; -}; - -export const fetchImage: Plugin.fetchImage = async (url) => { - return await fetchFile(url); -}; - -export const filters = [{"key":"sort","label":"Order by","values":[{"label":"Rating","value":"rating"},{"label":"A-Z","value":"alphabet"},{"label":"Latest","value":"latest"},{"label":"Most Views","value":"views"},{"label":"New","value":"new-manga"},{"label":"Trending","value":"trending"}],"inputType":FilterInputs.Picker},{"key":"genres","label":"GENRES","values":[{"label":"Action","value":"action"},{"label":"Adult","value":"adult"},{"label":"Comedy","value":"comedy"},{"label":"Drama","value":"drama"},{"label":"Fantasy","value":"fantasy"},{"label":"Gender Bender","value":"gender-bender"},{"label":"Mature","value":"mature"},{"label":"Modern","value":"modern"},{"label":"Mystery","value":"mystery"},{"label":"R-15","value":"r-15"},{"label":"Romance","value":"romance"},{"label":"Slice of Life","value":"slice-of-life"}],"inputType":FilterInputs.Picker}]; \ No newline at end of file + return chapterText; + } + async searchNovels(searchTerm: string, pageNo?: number | undefined): Promise { + const novels: Plugin.NovelItem[] = []; + const url = this.site + "?s=" + searchTerm + "&post_type=wp-manga"; + + const body = await fetchApi(url).then(res => res.text()); + + const loadedCheerio = parseHTML(body); + + + loadedCheerio('.c-tabs-item__content').each(function () { + const novelName = loadedCheerio(this).find('.post-title').text().trim(); + + let image = loadedCheerio(this).find('img'); + const novelCover = image.attr('data-src') || image.attr('src'); + + let novelUrl = loadedCheerio(this) + .find('.post-title') + .find('a') + .attr('href') || ''; + const novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + + novels.push(novel); + }); + return novels; + } + async fetchImage(url: string): Promise { + return await fetchFile(url, {}); + } +} +const plugin = new MadaraPlugin({"id":"sweetEscapeTL","sourceSite":"https://sweetescapetranslations.com/","sourceName":"Sweet Escape Translations","filters":[{"key":"sort","label":"Order by","values":[{"label":"Rating","value":"rating"},{"label":"A-Z","value":"alphabet"},{"label":"Latest","value":"latest"},{"label":"Most Views","value":"views"},{"label":"New","value":"new-manga"},{"label":"Trending","value":"trending"}],"inputType":"Picker"},{"key":"genres","label":"GENRES","values":[{"label":"Action","value":"action"},{"label":"Adult","value":"adult"},{"label":"Comedy","value":"comedy"},{"label":"Drama","value":"drama"},{"label":"Fantasy","value":"fantasy"},{"label":"Gender Bender","value":"gender-bender"},{"label":"Mature","value":"mature"},{"label":"Modern","value":"modern"},{"label":"Mystery","value":"mystery"},{"label":"R-15","value":"r-15"},{"label":"Romance","value":"romance"},{"label":"Slice of Life","value":"slice-of-life"}],"inputType":"Picker"}],"options":{"path":{"novels":"manga","novel":"manga","chapter":"manga","genres":"manga-genre"},"useNewChapterEndpoint":false,"lang":"English"}}); +export default plugin; + \ No newline at end of file diff --git a/plugins/english/WebNovelLover[madara].ts b/plugins/english/WebNovelLover[madara].ts index 12e87c2..91209e1 100644 --- a/plugins/english/WebNovelLover[madara].ts +++ b/plugins/english/WebNovelLover[madara].ts @@ -1,213 +1,252 @@ +import { fetchApi, fetchFile } from "@libs/fetch"; +import { Filter } from "@libs/filterInputs"; +import { Plugin } from '@typings/plugin' import { load as parseHTML } from "cheerio"; -import { fetchFile, fetchApi } from "@libs/fetch"; -import { Novel, Plugin, Chapter } from "@typings/plugin"; -import { FilterInputs } from "@libs/filterInputs"; import { defaultCover } from "@libs/defaultCover"; -import { NovelStatus } from "@libs/novelStatus" +import { NovelStatus } from "@libs/novelStatus"; import { parseMadaraDate } from "@libs/parseMadaraDate"; import dayjs from "dayjs"; -export const id = "webnovelover"; -export const name = "WebNovelLover [madara]"; -export const icon = "multisrc/madara/icons/webnovellover.png"; -export const version = "1.0.0"; -export const site = "https://www.webnovelover.com/"; -const baseUrl = site; +interface MadaraOptionPath{ + genres?: string, + novels?: string, + novel?: string, + chapter?: string, +} -export const popularNovels: Plugin.popularNovels = async (pageNo, {filters, showLatestNovels}) => { - const novels: Novel.Item[] = []; +const MadaraDefaultPath: MadaraOptionPath = { + novels: 'novel', + novel: 'novel', + chapter: 'novel' +} - let url = site; +interface MadaraOptions { + useNewChapterEndpoint?: boolean, + path?: MadaraOptionPath, + lang?: string, + orderBy?: string +} - if (filters?.genres) { - url += "novel-genre/" + filters.genres + '/'; - } else { - url += "novel/"; +export interface MadaraMetadata { + id: string, + sourceSite: string, + sourceName: string, + options?: MadaraOptions, + filters?: Filter[], +} +class MadaraPlugin implements Plugin.PluginBase { + id: string; + name: string; + icon: string; + site: string; + version: string; + userAgent: string; + cookieString: string; + options?: MadaraOptions; + filter?: Filter[] | undefined; + + constructor(metadata: MadaraMetadata){ + this.id = metadata.id; + this.name = metadata.sourceName + "[madara]"; + const iconFileName = metadata.sourceName.replace(/\s+/g, "").toLowerCase(); + this.icon = `multisrc/madara/icons/${iconFileName}.png`; + this.site = metadata.sourceSite; + this.version = "1.0.0"; + this.userAgent = ""; + this.cookieString = ""; + this.options = metadata.options; + this.filter = metadata.filters; } + async popularNovels(pageNo: number, {filters, showLatestNovels}: Plugin.PopularNovelsOptions): Promise { + const novels: Plugin.NovelItem[] = []; - url += '/page/' + pageNo + '/' + - '?m_orderby=' + (showLatestNovels ? 'latest' : (filters?.sort || 'rating')); - - const body = await fetchApi(url).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - - loadedCheerio('.manga-title-badges').remove(); - - loadedCheerio('.page-item-detail').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - - let novelUrl = loadedCheerio(this).find('.post-title') - .find('a') - .attr('href') || ''; - const novel: Novel.Item = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - - novels.push(novel); - }); - - return novels; -}; - -export const parseNovelAndChapters: Plugin.parseNovelAndChapters = async ( - novelUrl -) => { - const novel: Novel.instance = { - url: novelUrl, - }; - - const body = await fetchApi(novelUrl).then(res => res.text()); - - let loadedCheerio = parseHTML(body); - - loadedCheerio('.manga-title-badges').remove(); - - novel.name = loadedCheerio('.post-title h1').text().trim(); - - novel.cover = - loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || - loadedCheerio('.summary_image > a > img').attr('data-src') || - loadedCheerio('.summary_image > a > img').attr('src') || - defaultCover; - - loadedCheerio('.post-content_item, .post-content').each(function () { - const detailName = loadedCheerio(this).find('h5').text().trim(); - const detail = loadedCheerio(this).find('.summary-content').text().trim(); - - switch (detailName) { - case 'Genre(s)': - case 'التصنيفات': - novel.genres = detail.replace(/[\t\n]/g, ','); - break; - case 'Author(s)': - case 'المؤلف': - case 'المؤلف (ين)': - novel.author = detail; - break; - case 'Status': - case 'الحالة': - novel.status = - detail.includes('OnGoing') || detail.includes('مستمرة') - ? NovelStatus.Ongoing - : NovelStatus.Completed; - break; - } - }); - - loadedCheerio('div.summary__content .code-block,script').remove(); - novel.summary = loadedCheerio('div.summary__content').text().trim(); - - - let html; - - if (false) { - const novelId = - loadedCheerio('.rating-post-id').attr('value') || - loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; - - const body = { - action: "manga_get_chapters", - manga: novelId, - } - html = await fetchApi( - baseUrl + 'wp-admin/admin-ajax.php', - { - method: 'POST', - body: JSON.stringify(body), - }) - .then(res => res.text()); - } else { - html = await fetchApi( - baseUrl + 'ajax/chapters/', - { method: 'POST' }) - .then(res => res.text()); - } - - if (html !== '0') { - loadedCheerio = parseHTML(html); - } - - const chapters: Chapter.Item[] = []; - loadedCheerio('.wp-manga-chapter').each(function () { - const chapterName = loadedCheerio(this).find('a').text().trim(); - - let releaseDate = null; - releaseDate = loadedCheerio(this) - .find('span.chapter-release-date') - .text() - .trim(); - - if (releaseDate) { - releaseDate = parseMadaraDate(releaseDate); + let url = this.site; + if (filters?.genres && this.options?.path?.genres) { + url += this.options?.path?.genres + filters.genres + '/'; } else { - /** - * Insert current date - */ - - releaseDate = dayjs().format('LL'); + url += this.options?.path?.novels ? this.options.path.novels : MadaraDefaultPath.novels; } + + url += '/page/' + pageNo + '/' + + '?m_orderby=' + (showLatestNovels ? 'latest' : (filters?.sort || 'rating')); + + const body = await fetchApi(url).then(res => res.text()); + + const loadedCheerio = parseHTML(body); + + loadedCheerio('.manga-title-badges').remove(); + + loadedCheerio('.page-item-detail').each(function () { + const novelName = loadedCheerio(this).find('.post-title').text().trim(); + let image = loadedCheerio(this).find('img'); + const novelCover = image.attr('data-src') || image.attr('src'); + + let novelUrl = loadedCheerio(this).find('.post-title') + .find('a') + .attr('href') || ''; + const novel: Plugin.NovelItem = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + + novels.push(novel); + }); + + return novels; + } + async parseNovelAndChapters(novelUrl: string): Promise { + const novel: Plugin.SourceNovel = { + url: novelUrl, + }; + + const body = await fetchApi(novelUrl).then(res => res.text()); + + let loadedCheerio = parseHTML(body); + + loadedCheerio('.manga-title-badges, #manga-title span').remove(); + novel.name = + loadedCheerio('.post-title h1').text().trim() || + loadedCheerio('#manga-title h1').text(); + + novel.cover = + loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || + loadedCheerio('.summary_image > a > img').attr('data-src') || + loadedCheerio('.summary_image > a > img').attr('src') || + defaultCover; + + loadedCheerio('.post-content_item, .post-content').each(function () { + const detailName = loadedCheerio(this).find('h5').text().trim(); + const detail = loadedCheerio(this).find('.summary-content').text().trim(); + + switch (detailName) { + case 'Genre(s)': + case 'التصنيفات': + novel.genres = detail.replace(/[\\t\\n]/g, ','); + break; + case 'Author(s)': + case 'المؤلف': + case 'المؤلف (ين)': + novel.author = detail; + break; + case 'Status': + case 'الحالة': + novel.status = + detail.includes('OnGoing') || detail.includes('مستمرة') + ? NovelStatus.Ongoing + : NovelStatus.Completed; + break; + } + }); + + loadedCheerio('div.summary__content .code-block,script').remove(); + novel.summary = + loadedCheerio('div.summary__content').text().trim() || + loadedCheerio('#tab-manga-about').text().trim() || + loadedCheerio('.post-content_item h5:contains("Summary")').next().text().trim(); + + let html; + + if (this.options?.useNewChapterEndpoint !== true) { + const novelId = + loadedCheerio('.rating-post-id').attr('value') || + loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; + + const formData = new FormData() + formData.append("action", "manga_get_chapters"); + formData.append("manga", novelId); - let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + html = await fetchApi( + this.site + 'wp-admin/admin-ajax.php', + { + method: 'POST', + body: formData, + }) + .then(res => res.text()); + } else { + html = await fetchApi( + novelUrl + 'ajax/chapters/', + { method: 'POST' }) + .then(res => res.text()); + } + + if (html !== '0') { + loadedCheerio = parseHTML(html); + } + + const chapters: Plugin.ChapterItem[] = []; + loadedCheerio('.wp-manga-chapter').each(function () { + const chapterName = loadedCheerio(this).find('a').text().trim(); + + let releaseDate = null; + releaseDate = loadedCheerio(this) + .find('span.chapter-release-date') + .text() + .trim(); + + if (releaseDate) { + releaseDate = parseMadaraDate(releaseDate); + } else { + /** + * Insert current date + */ + + releaseDate = dayjs().format('LL'); + } + + let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + + chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); + }); + + novel.chapters = chapters.reverse(); + return novel; + } + async parseChapter(chapterUrl: string): Promise { + const body = await fetchApi(chapterUrl).then(res => res.text()); - chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); - }); + const loadedCheerio = parseHTML(body); + const chapterText = + loadedCheerio('.text-left').html() || + loadedCheerio('.text-right').html() || + loadedCheerio('.entry-content').html() || ""; - novel.chapters = chapters.reverse(); - return novel; -}; - -export const parseChapter: Plugin.parseChapter = async (chapterUrl) => { - const url = baseUrl + "/" + "novel" + "/" + chapterUrl; - - const body = await fetchApi(chapterUrl).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - const chapterText = - loadedCheerio('.text-left').html() || - loadedCheerio('.text-right').html() || - loadedCheerio('.entry-content').html(); - - return chapterText; -}; - -export const searchNovels: Plugin.searchNovels = async (searchTerm) => { - const novels: Novel.Item[] = []; - const url = baseUrl + "?s=" + searchTerm + "&post_type=wp-manga"; - - const body = await fetchApi(url).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - - - loadedCheerio('.c-tabs-item__content').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - - let novelUrl = loadedCheerio(this) - .find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - - novels.push(novel); - }); - return novels; -}; - -export const fetchImage: Plugin.fetchImage = async (url) => { - return await fetchFile(url); -}; - -export const filters = [{"key":"sort","label":"Order by","values":[{"label":"Rating","value":"rating"},{"label":"A-Z","value":"alphabet"},{"label":"Latest","value":"latest"},{"label":"Most Views","value":"views"},{"label":"New","value":"new-manga"},{"label":"Trending","value":"trending"}],"inputType":FilterInputs.Picker},{"key":"genres","label":"GENRES","values":[{"label":"Action","value":"action"},{"label":"Adapted into drama","value":"adapted-into-drama"},{"label":"Adventure","value":"adventure"},{"label":"Comedy","value":"comedy"},{"label":"Completed","value":"completed"},{"label":"Drama","value":"drama"},{"label":"English Novel","value":"english-novel"},{"label":"Fantasy","value":"fantasy"},{"label":"Gender Bender","value":"gender-bender"},{"label":"Harem","value":"harem"},{"label":"Historical","value":"historical"},{"label":"Horror","value":"horror"},{"label":"Indo Novel","value":"indo-novel"},{"label":"Josei","value":"josei"},{"label":"Martial Arts","value":"martial-arts"},{"label":"Mature","value":"mature"},{"label":"Mystery","value":"mystery"},{"label":"Rebirth","value":"rebirth"},{"label":"Reincarnation","value":"reincarnation"},{"label":"Romance","value":"romance"},{"label":"Sci-fi","value":"sci-fi"},{"label":"Shoujo","value":"shoujo"},{"label":"Shounen","value":"shounen"},{"label":"Slice of Life","value":"slice-of-life"},{"label":"Spiritual","value":"spiritual"},{"label":"Supernatural","value":"supernatural"},{"label":"Tragedy","value":"tragedy"},{"label":"Transmigration","value":"transmigration"},{"label":"University","value":"university"},{"label":"Wuxia","value":"wuxia"},{"label":"Xianxia","value":"xianxia"},{"label":"Xuanhuan","value":"xuanhuan"},{"label":"Youth","value":"youth"}],"inputType":FilterInputs.Picker}]; \ No newline at end of file + return chapterText; + } + async searchNovels(searchTerm: string, pageNo?: number | undefined): Promise { + const novels: Plugin.NovelItem[] = []; + const url = this.site + "?s=" + searchTerm + "&post_type=wp-manga"; + + const body = await fetchApi(url).then(res => res.text()); + + const loadedCheerio = parseHTML(body); + + + loadedCheerio('.c-tabs-item__content').each(function () { + const novelName = loadedCheerio(this).find('.post-title').text().trim(); + + let image = loadedCheerio(this).find('img'); + const novelCover = image.attr('data-src') || image.attr('src'); + + let novelUrl = loadedCheerio(this) + .find('.post-title') + .find('a') + .attr('href') || ''; + const novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + + novels.push(novel); + }); + return novels; + } + async fetchImage(url: string): Promise { + return await fetchFile(url, {}); + } +} +const plugin = new MadaraPlugin({"id":"webnovelover","sourceSite":"https://www.webnovelover.com/","sourceName":"WebNovelLover","filters":[{"key":"sort","label":"Order by","values":[{"label":"Rating","value":"rating"},{"label":"A-Z","value":"alphabet"},{"label":"Latest","value":"latest"},{"label":"Most Views","value":"views"},{"label":"New","value":"new-manga"},{"label":"Trending","value":"trending"}],"inputType":"Picker"},{"key":"genres","label":"GENRES","values":[{"label":"Action","value":"action"},{"label":"Adapted into drama","value":"adapted-into-drama"},{"label":"Adventure","value":"adventure"},{"label":"Comedy","value":"comedy"},{"label":"Completed","value":"completed"},{"label":"Drama","value":"drama"},{"label":"English Novel","value":"english-novel"},{"label":"Fantasy","value":"fantasy"},{"label":"Gender Bender","value":"gender-bender"},{"label":"Harem","value":"harem"},{"label":"Historical","value":"historical"},{"label":"Horror","value":"horror"},{"label":"Indo Novel","value":"indo-novel"},{"label":"Josei","value":"josei"},{"label":"Martial Arts","value":"martial-arts"},{"label":"Mature","value":"mature"},{"label":"Mystery","value":"mystery"},{"label":"Rebirth","value":"rebirth"},{"label":"Reincarnation","value":"reincarnation"},{"label":"Romance","value":"romance"},{"label":"Sci-fi","value":"sci-fi"},{"label":"Shoujo","value":"shoujo"},{"label":"Shounen","value":"shounen"},{"label":"Slice of Life","value":"slice-of-life"},{"label":"Spiritual","value":"spiritual"},{"label":"Supernatural","value":"supernatural"},{"label":"Tragedy","value":"tragedy"},{"label":"Transmigration","value":"transmigration"},{"label":"University","value":"university"},{"label":"Wuxia","value":"wuxia"},{"label":"Xianxia","value":"xianxia"},{"label":"Xuanhuan","value":"xuanhuan"},{"label":"Youth","value":"youth"}],"inputType":"Picker"}],"options":{"lang":"English"}}); +export default plugin; + \ No newline at end of file diff --git a/plugins/english/WuxiaWorldSite[madara].ts b/plugins/english/WuxiaWorldSite[madara].ts index 2e2e9f0..9b800c3 100644 --- a/plugins/english/WuxiaWorldSite[madara].ts +++ b/plugins/english/WuxiaWorldSite[madara].ts @@ -1,213 +1,252 @@ +import { fetchApi, fetchFile } from "@libs/fetch"; +import { Filter } from "@libs/filterInputs"; +import { Plugin } from '@typings/plugin' import { load as parseHTML } from "cheerio"; -import { fetchFile, fetchApi } from "@libs/fetch"; -import { Novel, Plugin, Chapter } from "@typings/plugin"; -import { FilterInputs } from "@libs/filterInputs"; import { defaultCover } from "@libs/defaultCover"; -import { NovelStatus } from "@libs/novelStatus" +import { NovelStatus } from "@libs/novelStatus"; import { parseMadaraDate } from "@libs/parseMadaraDate"; import dayjs from "dayjs"; -export const id = "wuxiaworld.site"; -export const name = "WuxiaWorld.Site [madara]"; -export const icon = "multisrc/madara/icons/wuxiaworld.site.png"; -export const version = "1.0.0"; -export const site = "https://wuxiaworld.site/"; -const baseUrl = site; +interface MadaraOptionPath{ + genres?: string, + novels?: string, + novel?: string, + chapter?: string, +} -export const popularNovels: Plugin.popularNovels = async (pageNo, {filters, showLatestNovels}) => { - const novels: Novel.Item[] = []; +const MadaraDefaultPath: MadaraOptionPath = { + novels: 'novel', + novel: 'novel', + chapter: 'novel' +} - let url = site; +interface MadaraOptions { + useNewChapterEndpoint?: boolean, + path?: MadaraOptionPath, + lang?: string, + orderBy?: string +} - if (filters?.genres) { - url += "novel-genre/" + filters.genres + '/'; - } else { - url += "novel/"; +export interface MadaraMetadata { + id: string, + sourceSite: string, + sourceName: string, + options?: MadaraOptions, + filters?: Filter[], +} +class MadaraPlugin implements Plugin.PluginBase { + id: string; + name: string; + icon: string; + site: string; + version: string; + userAgent: string; + cookieString: string; + options?: MadaraOptions; + filter?: Filter[] | undefined; + + constructor(metadata: MadaraMetadata){ + this.id = metadata.id; + this.name = metadata.sourceName + "[madara]"; + const iconFileName = metadata.sourceName.replace(/\s+/g, "").toLowerCase(); + this.icon = `multisrc/madara/icons/${iconFileName}.png`; + this.site = metadata.sourceSite; + this.version = "1.0.0"; + this.userAgent = ""; + this.cookieString = ""; + this.options = metadata.options; + this.filter = metadata.filters; } + async popularNovels(pageNo: number, {filters, showLatestNovels}: Plugin.PopularNovelsOptions): Promise { + const novels: Plugin.NovelItem[] = []; - url += '/page/' + pageNo + '/' + - '?m_orderby=' + (showLatestNovels ? 'latest' : (filters?.sort || 'rating')); - - const body = await fetchApi(url).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - - loadedCheerio('.manga-title-badges').remove(); - - loadedCheerio('.page-item-detail').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - - let novelUrl = loadedCheerio(this).find('.post-title') - .find('a') - .attr('href') || ''; - const novel: Novel.Item = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - - novels.push(novel); - }); - - return novels; -}; - -export const parseNovelAndChapters: Plugin.parseNovelAndChapters = async ( - novelUrl -) => { - const novel: Novel.instance = { - url: novelUrl, - }; - - const body = await fetchApi(novelUrl).then(res => res.text()); - - let loadedCheerio = parseHTML(body); - - loadedCheerio('.manga-title-badges').remove(); - - novel.name = loadedCheerio('.post-title h1').text().trim(); - - novel.cover = - loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || - loadedCheerio('.summary_image > a > img').attr('data-src') || - loadedCheerio('.summary_image > a > img').attr('src') || - defaultCover; - - loadedCheerio('.post-content_item, .post-content').each(function () { - const detailName = loadedCheerio(this).find('h5').text().trim(); - const detail = loadedCheerio(this).find('.summary-content').text().trim(); - - switch (detailName) { - case 'Genre(s)': - case 'التصنيفات': - novel.genres = detail.replace(/[\t\n]/g, ','); - break; - case 'Author(s)': - case 'المؤلف': - case 'المؤلف (ين)': - novel.author = detail; - break; - case 'Status': - case 'الحالة': - novel.status = - detail.includes('OnGoing') || detail.includes('مستمرة') - ? NovelStatus.Ongoing - : NovelStatus.Completed; - break; - } - }); - - loadedCheerio('div.summary__content .code-block,script').remove(); - novel.summary = loadedCheerio('div.summary__content').text().trim(); - - - let html; - - if (true) { - const novelId = - loadedCheerio('.rating-post-id').attr('value') || - loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; - - const body = { - action: "manga_get_chapters", - manga: novelId, - } - html = await fetchApi( - baseUrl + 'wp-admin/admin-ajax.php', - { - method: 'POST', - body: JSON.stringify(body), - }) - .then(res => res.text()); - } else { - html = await fetchApi( - baseUrl + 'ajax/chapters/', - { method: 'POST' }) - .then(res => res.text()); - } - - if (html !== '0') { - loadedCheerio = parseHTML(html); - } - - const chapters: Chapter.Item[] = []; - loadedCheerio('.wp-manga-chapter').each(function () { - const chapterName = loadedCheerio(this).find('a').text().trim(); - - let releaseDate = null; - releaseDate = loadedCheerio(this) - .find('span.chapter-release-date') - .text() - .trim(); - - if (releaseDate) { - releaseDate = parseMadaraDate(releaseDate); + let url = this.site; + if (filters?.genres && this.options?.path?.genres) { + url += this.options?.path?.genres + filters.genres + '/'; } else { - /** - * Insert current date - */ - - releaseDate = dayjs().format('LL'); + url += this.options?.path?.novels ? this.options.path.novels : MadaraDefaultPath.novels; } + + url += '/page/' + pageNo + '/' + + '?m_orderby=' + (showLatestNovels ? 'latest' : (filters?.sort || 'rating')); + + const body = await fetchApi(url).then(res => res.text()); + + const loadedCheerio = parseHTML(body); + + loadedCheerio('.manga-title-badges').remove(); + + loadedCheerio('.page-item-detail').each(function () { + const novelName = loadedCheerio(this).find('.post-title').text().trim(); + let image = loadedCheerio(this).find('img'); + const novelCover = image.attr('data-src') || image.attr('src'); + + let novelUrl = loadedCheerio(this).find('.post-title') + .find('a') + .attr('href') || ''; + const novel: Plugin.NovelItem = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + + novels.push(novel); + }); + + return novels; + } + async parseNovelAndChapters(novelUrl: string): Promise { + const novel: Plugin.SourceNovel = { + url: novelUrl, + }; + + const body = await fetchApi(novelUrl).then(res => res.text()); + + let loadedCheerio = parseHTML(body); + + loadedCheerio('.manga-title-badges, #manga-title span').remove(); + novel.name = + loadedCheerio('.post-title h1').text().trim() || + loadedCheerio('#manga-title h1').text(); + + novel.cover = + loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || + loadedCheerio('.summary_image > a > img').attr('data-src') || + loadedCheerio('.summary_image > a > img').attr('src') || + defaultCover; + + loadedCheerio('.post-content_item, .post-content').each(function () { + const detailName = loadedCheerio(this).find('h5').text().trim(); + const detail = loadedCheerio(this).find('.summary-content').text().trim(); + + switch (detailName) { + case 'Genre(s)': + case 'التصنيفات': + novel.genres = detail.replace(/[\\t\\n]/g, ','); + break; + case 'Author(s)': + case 'المؤلف': + case 'المؤلف (ين)': + novel.author = detail; + break; + case 'Status': + case 'الحالة': + novel.status = + detail.includes('OnGoing') || detail.includes('مستمرة') + ? NovelStatus.Ongoing + : NovelStatus.Completed; + break; + } + }); + + loadedCheerio('div.summary__content .code-block,script').remove(); + novel.summary = + loadedCheerio('div.summary__content').text().trim() || + loadedCheerio('#tab-manga-about').text().trim() || + loadedCheerio('.post-content_item h5:contains("Summary")').next().text().trim(); + + let html; + + if (this.options?.useNewChapterEndpoint !== true) { + const novelId = + loadedCheerio('.rating-post-id').attr('value') || + loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; + + const formData = new FormData() + formData.append("action", "manga_get_chapters"); + formData.append("manga", novelId); - let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + html = await fetchApi( + this.site + 'wp-admin/admin-ajax.php', + { + method: 'POST', + body: formData, + }) + .then(res => res.text()); + } else { + html = await fetchApi( + novelUrl + 'ajax/chapters/', + { method: 'POST' }) + .then(res => res.text()); + } + + if (html !== '0') { + loadedCheerio = parseHTML(html); + } + + const chapters: Plugin.ChapterItem[] = []; + loadedCheerio('.wp-manga-chapter').each(function () { + const chapterName = loadedCheerio(this).find('a').text().trim(); + + let releaseDate = null; + releaseDate = loadedCheerio(this) + .find('span.chapter-release-date') + .text() + .trim(); + + if (releaseDate) { + releaseDate = parseMadaraDate(releaseDate); + } else { + /** + * Insert current date + */ + + releaseDate = dayjs().format('LL'); + } + + let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + + chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); + }); + + novel.chapters = chapters.reverse(); + return novel; + } + async parseChapter(chapterUrl: string): Promise { + const body = await fetchApi(chapterUrl).then(res => res.text()); - chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); - }); + const loadedCheerio = parseHTML(body); + const chapterText = + loadedCheerio('.text-left').html() || + loadedCheerio('.text-right').html() || + loadedCheerio('.entry-content').html() || ""; - novel.chapters = chapters.reverse(); - return novel; -}; - -export const parseChapter: Plugin.parseChapter = async (chapterUrl) => { - const url = baseUrl + "/" + "novel" + "/" + chapterUrl; - - const body = await fetchApi(chapterUrl).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - const chapterText = - loadedCheerio('.text-left').html() || - loadedCheerio('.text-right').html() || - loadedCheerio('.entry-content').html(); - - return chapterText; -}; - -export const searchNovels: Plugin.searchNovels = async (searchTerm) => { - const novels: Novel.Item[] = []; - const url = baseUrl + "?s=" + searchTerm + "&post_type=wp-manga"; - - const body = await fetchApi(url).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - - - loadedCheerio('.c-tabs-item__content').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - - let novelUrl = loadedCheerio(this) - .find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - - novels.push(novel); - }); - return novels; -}; - -export const fetchImage: Plugin.fetchImage = async (url) => { - return await fetchFile(url); -}; - -export const filters = [{"key":"sort","label":"Order by","values":[{"label":"Rating","value":"rating"},{"label":"A-Z","value":"alphabet"},{"label":"Latest","value":"latest"},{"label":"Most Views","value":"views"},{"label":"New","value":"new-manga"},{"label":"Trending","value":"trending"}],"inputType":FilterInputs.Picker}]; \ No newline at end of file + return chapterText; + } + async searchNovels(searchTerm: string, pageNo?: number | undefined): Promise { + const novels: Plugin.NovelItem[] = []; + const url = this.site + "?s=" + searchTerm + "&post_type=wp-manga"; + + const body = await fetchApi(url).then(res => res.text()); + + const loadedCheerio = parseHTML(body); + + + loadedCheerio('.c-tabs-item__content').each(function () { + const novelName = loadedCheerio(this).find('.post-title').text().trim(); + + let image = loadedCheerio(this).find('img'); + const novelCover = image.attr('data-src') || image.attr('src'); + + let novelUrl = loadedCheerio(this) + .find('.post-title') + .find('a') + .attr('href') || ''; + const novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + + novels.push(novel); + }); + return novels; + } + async fetchImage(url: string): Promise { + return await fetchFile(url, {}); + } +} +const plugin = new MadaraPlugin({"id":"wuxiaworld.site","sourceSite":"https://wuxiaworld.site/","sourceName":"WuxiaWorld.Site","filters":[{"key":"sort","label":"Order by","values":[{"label":"Rating","value":"rating"},{"label":"A-Z","value":"alphabet"},{"label":"Latest","value":"latest"},{"label":"Most Views","value":"views"},{"label":"New","value":"new-manga"},{"label":"Trending","value":"trending"}],"inputType":"Picker"}],"options":{"useNewChapterEndpoint":true,"lang":"English"}}); +export default plugin; + \ No newline at end of file diff --git a/plugins/english/ZetroTranslation[madara].ts b/plugins/english/ZetroTranslation[madara].ts index cf159bf..a22e6b9 100644 --- a/plugins/english/ZetroTranslation[madara].ts +++ b/plugins/english/ZetroTranslation[madara].ts @@ -1,213 +1,252 @@ +import { fetchApi, fetchFile } from "@libs/fetch"; +import { Filter } from "@libs/filterInputs"; +import { Plugin } from '@typings/plugin' import { load as parseHTML } from "cheerio"; -import { fetchFile, fetchApi } from "@libs/fetch"; -import { Novel, Plugin, Chapter } from "@typings/plugin"; -import { FilterInputs } from "@libs/filterInputs"; import { defaultCover } from "@libs/defaultCover"; -import { NovelStatus } from "@libs/novelStatus" +import { NovelStatus } from "@libs/novelStatus"; import { parseMadaraDate } from "@libs/parseMadaraDate"; import dayjs from "dayjs"; -export const id = "zetroTL"; -export const name = "Zetro Translation [madara]"; -export const icon = "multisrc/madara/icons/zetrotranslation.png"; -export const version = "1.0.0"; -export const site = "https://zetrotranslation.com/"; -const baseUrl = site; +interface MadaraOptionPath{ + genres?: string, + novels?: string, + novel?: string, + chapter?: string, +} -export const popularNovels: Plugin.popularNovels = async (pageNo, {filters, showLatestNovels}) => { - const novels: Novel.Item[] = []; +const MadaraDefaultPath: MadaraOptionPath = { + novels: 'novel', + novel: 'novel', + chapter: 'novel' +} - let url = site; +interface MadaraOptions { + useNewChapterEndpoint?: boolean, + path?: MadaraOptionPath, + lang?: string, + orderBy?: string +} - if (filters?.genres) { - url += "genre/" + filters.genres + '/'; - } else { - url += "novel/"; +export interface MadaraMetadata { + id: string, + sourceSite: string, + sourceName: string, + options?: MadaraOptions, + filters?: Filter[], +} +class MadaraPlugin implements Plugin.PluginBase { + id: string; + name: string; + icon: string; + site: string; + version: string; + userAgent: string; + cookieString: string; + options?: MadaraOptions; + filter?: Filter[] | undefined; + + constructor(metadata: MadaraMetadata){ + this.id = metadata.id; + this.name = metadata.sourceName + "[madara]"; + const iconFileName = metadata.sourceName.replace(/\s+/g, "").toLowerCase(); + this.icon = `multisrc/madara/icons/${iconFileName}.png`; + this.site = metadata.sourceSite; + this.version = "1.0.0"; + this.userAgent = ""; + this.cookieString = ""; + this.options = metadata.options; + this.filter = metadata.filters; } + async popularNovels(pageNo: number, {filters, showLatestNovels}: Plugin.PopularNovelsOptions): Promise { + const novels: Plugin.NovelItem[] = []; - url += '/page/' + pageNo + '/' + - '?m_orderby=' + (showLatestNovels ? 'latest' : (filters?.sort || 'rating')); - - const body = await fetchApi(url).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - - loadedCheerio('.manga-title-badges').remove(); - - loadedCheerio('.page-item-detail').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - - let novelUrl = loadedCheerio(this).find('.post-title') - .find('a') - .attr('href') || ''; - const novel: Novel.Item = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - - novels.push(novel); - }); - - return novels; -}; - -export const parseNovelAndChapters: Plugin.parseNovelAndChapters = async ( - novelUrl -) => { - const novel: Novel.instance = { - url: novelUrl, - }; - - const body = await fetchApi(novelUrl).then(res => res.text()); - - let loadedCheerio = parseHTML(body); - - loadedCheerio('.manga-title-badges').remove(); - - novel.name = loadedCheerio('.post-title h1').text().trim(); - - novel.cover = - loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || - loadedCheerio('.summary_image > a > img').attr('data-src') || - loadedCheerio('.summary_image > a > img').attr('src') || - defaultCover; - - loadedCheerio('.post-content_item, .post-content').each(function () { - const detailName = loadedCheerio(this).find('h5').text().trim(); - const detail = loadedCheerio(this).find('.summary-content').text().trim(); - - switch (detailName) { - case 'Genre(s)': - case 'التصنيفات': - novel.genres = detail.replace(/[\t\n]/g, ','); - break; - case 'Author(s)': - case 'المؤلف': - case 'المؤلف (ين)': - novel.author = detail; - break; - case 'Status': - case 'الحالة': - novel.status = - detail.includes('OnGoing') || detail.includes('مستمرة') - ? NovelStatus.Ongoing - : NovelStatus.Completed; - break; - } - }); - - loadedCheerio('div.summary__content .code-block,script').remove(); - novel.summary = loadedCheerio('div.summary__content').text().trim(); - - - let html; - - if (false) { - const novelId = - loadedCheerio('.rating-post-id').attr('value') || - loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; - - const body = { - action: "manga_get_chapters", - manga: novelId, - } - html = await fetchApi( - baseUrl + 'wp-admin/admin-ajax.php', - { - method: 'POST', - body: JSON.stringify(body), - }) - .then(res => res.text()); - } else { - html = await fetchApi( - baseUrl + 'ajax/chapters/', - { method: 'POST' }) - .then(res => res.text()); - } - - if (html !== '0') { - loadedCheerio = parseHTML(html); - } - - const chapters: Chapter.Item[] = []; - loadedCheerio('.wp-manga-chapter').each(function () { - const chapterName = loadedCheerio(this).find('a').text().trim(); - - let releaseDate = null; - releaseDate = loadedCheerio(this) - .find('span.chapter-release-date') - .text() - .trim(); - - if (releaseDate) { - releaseDate = parseMadaraDate(releaseDate); + let url = this.site; + if (filters?.genres && this.options?.path?.genres) { + url += this.options?.path?.genres + filters.genres + '/'; } else { - /** - * Insert current date - */ - - releaseDate = dayjs().format('LL'); + url += this.options?.path?.novels ? this.options.path.novels : MadaraDefaultPath.novels; } + + url += '/page/' + pageNo + '/' + + '?m_orderby=' + (showLatestNovels ? 'latest' : (filters?.sort || 'rating')); + + const body = await fetchApi(url).then(res => res.text()); + + const loadedCheerio = parseHTML(body); + + loadedCheerio('.manga-title-badges').remove(); + + loadedCheerio('.page-item-detail').each(function () { + const novelName = loadedCheerio(this).find('.post-title').text().trim(); + let image = loadedCheerio(this).find('img'); + const novelCover = image.attr('data-src') || image.attr('src'); + + let novelUrl = loadedCheerio(this).find('.post-title') + .find('a') + .attr('href') || ''; + const novel: Plugin.NovelItem = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + + novels.push(novel); + }); + + return novels; + } + async parseNovelAndChapters(novelUrl: string): Promise { + const novel: Plugin.SourceNovel = { + url: novelUrl, + }; + + const body = await fetchApi(novelUrl).then(res => res.text()); + + let loadedCheerio = parseHTML(body); + + loadedCheerio('.manga-title-badges, #manga-title span').remove(); + novel.name = + loadedCheerio('.post-title h1').text().trim() || + loadedCheerio('#manga-title h1').text(); + + novel.cover = + loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || + loadedCheerio('.summary_image > a > img').attr('data-src') || + loadedCheerio('.summary_image > a > img').attr('src') || + defaultCover; + + loadedCheerio('.post-content_item, .post-content').each(function () { + const detailName = loadedCheerio(this).find('h5').text().trim(); + const detail = loadedCheerio(this).find('.summary-content').text().trim(); + + switch (detailName) { + case 'Genre(s)': + case 'التصنيفات': + novel.genres = detail.replace(/[\\t\\n]/g, ','); + break; + case 'Author(s)': + case 'المؤلف': + case 'المؤلف (ين)': + novel.author = detail; + break; + case 'Status': + case 'الحالة': + novel.status = + detail.includes('OnGoing') || detail.includes('مستمرة') + ? NovelStatus.Ongoing + : NovelStatus.Completed; + break; + } + }); + + loadedCheerio('div.summary__content .code-block,script').remove(); + novel.summary = + loadedCheerio('div.summary__content').text().trim() || + loadedCheerio('#tab-manga-about').text().trim() || + loadedCheerio('.post-content_item h5:contains("Summary")').next().text().trim(); + + let html; + + if (this.options?.useNewChapterEndpoint !== true) { + const novelId = + loadedCheerio('.rating-post-id').attr('value') || + loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; + + const formData = new FormData() + formData.append("action", "manga_get_chapters"); + formData.append("manga", novelId); - let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + html = await fetchApi( + this.site + 'wp-admin/admin-ajax.php', + { + method: 'POST', + body: formData, + }) + .then(res => res.text()); + } else { + html = await fetchApi( + novelUrl + 'ajax/chapters/', + { method: 'POST' }) + .then(res => res.text()); + } + + if (html !== '0') { + loadedCheerio = parseHTML(html); + } + + const chapters: Plugin.ChapterItem[] = []; + loadedCheerio('.wp-manga-chapter').each(function () { + const chapterName = loadedCheerio(this).find('a').text().trim(); + + let releaseDate = null; + releaseDate = loadedCheerio(this) + .find('span.chapter-release-date') + .text() + .trim(); + + if (releaseDate) { + releaseDate = parseMadaraDate(releaseDate); + } else { + /** + * Insert current date + */ + + releaseDate = dayjs().format('LL'); + } + + let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + + chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); + }); + + novel.chapters = chapters.reverse(); + return novel; + } + async parseChapter(chapterUrl: string): Promise { + const body = await fetchApi(chapterUrl).then(res => res.text()); - chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); - }); + const loadedCheerio = parseHTML(body); + const chapterText = + loadedCheerio('.text-left').html() || + loadedCheerio('.text-right').html() || + loadedCheerio('.entry-content').html() || ""; - novel.chapters = chapters.reverse(); - return novel; -}; - -export const parseChapter: Plugin.parseChapter = async (chapterUrl) => { - const url = baseUrl + "/" + "novel" + "/" + chapterUrl; - - const body = await fetchApi(chapterUrl).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - const chapterText = - loadedCheerio('.text-left').html() || - loadedCheerio('.text-right').html() || - loadedCheerio('.entry-content').html(); - - return chapterText; -}; - -export const searchNovels: Plugin.searchNovels = async (searchTerm) => { - const novels: Novel.Item[] = []; - const url = baseUrl + "?s=" + searchTerm + "&post_type=wp-manga"; - - const body = await fetchApi(url).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - - - loadedCheerio('.c-tabs-item__content').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - - let novelUrl = loadedCheerio(this) - .find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - - novels.push(novel); - }); - return novels; -}; - -export const fetchImage: Plugin.fetchImage = async (url) => { - return await fetchFile(url); -}; - -export const filters = [{"key":"sort","label":"Order by","values":[{"label":"Rating","value":"rating"},{"label":"A-Z","value":"alphabet"},{"label":"Latest","value":"latest"},{"label":"Most Views","value":"views"},{"label":"New","value":"new-manga"},{"label":"Trending","value":"trending"}],"inputType":FilterInputs.Picker},{"key":"genres","label":"GENRES","values":[{"label":"Action","value":"action"},{"label":"Adventure","value":"adventure"},{"label":"Comedy","value":"comedy"},{"label":"Dark Elf","value":"dark-elf"},{"label":"Drama","value":"drama"},{"label":"Ecchi","value":"ecchi"},{"label":"Fantasy","value":"fantasy"},{"label":"Harem","value":"harem"},{"label":"Horror","value":"horror"},{"label":"Isekai","value":"isekai"},{"label":"Mecha","value":"mecha"},{"label":"Mystery","value":"mystery"},{"label":"NTR","value":"ntr"},{"label":"Original Works","value":"original-works"},{"label":"Rom-Com","value":"rom-com"},{"label":"Romance","value":"romance"},{"label":"School","value":"school"},{"label":"Shoujo","value":"shoujo"},{"label":"Slice of Life","value":"slice-of-life"},{"label":"Villain","value":"villain"},{"label":"Yuri","value":"yuri"}],"inputType":FilterInputs.Picker}]; \ No newline at end of file + return chapterText; + } + async searchNovels(searchTerm: string, pageNo?: number | undefined): Promise { + const novels: Plugin.NovelItem[] = []; + const url = this.site + "?s=" + searchTerm + "&post_type=wp-manga"; + + const body = await fetchApi(url).then(res => res.text()); + + const loadedCheerio = parseHTML(body); + + + loadedCheerio('.c-tabs-item__content').each(function () { + const novelName = loadedCheerio(this).find('.post-title').text().trim(); + + let image = loadedCheerio(this).find('img'); + const novelCover = image.attr('data-src') || image.attr('src'); + + let novelUrl = loadedCheerio(this) + .find('.post-title') + .find('a') + .attr('href') || ''; + const novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + + novels.push(novel); + }); + return novels; + } + async fetchImage(url: string): Promise { + return await fetchFile(url, {}); + } +} +const plugin = new MadaraPlugin({"id":"zetroTL","sourceSite":"https://zetrotranslation.com/","sourceName":"Zetro Translation","filters":[{"key":"sort","label":"Order by","values":[{"label":"Rating","value":"rating"},{"label":"A-Z","value":"alphabet"},{"label":"Latest","value":"latest"},{"label":"Most Views","value":"views"},{"label":"New","value":"new-manga"},{"label":"Trending","value":"trending"}],"inputType":"Picker"},{"key":"genres","label":"GENRES","values":[{"label":"Action","value":"action"},{"label":"Adventure","value":"adventure"},{"label":"Comedy","value":"comedy"},{"label":"Dark Elf","value":"dark-elf"},{"label":"Drama","value":"drama"},{"label":"Ecchi","value":"ecchi"},{"label":"Fantasy","value":"fantasy"},{"label":"Harem","value":"harem"},{"label":"Horror","value":"horror"},{"label":"Isekai","value":"isekai"},{"label":"Mecha","value":"mecha"},{"label":"Mystery","value":"mystery"},{"label":"NTR","value":"ntr"},{"label":"Original Works","value":"original-works"},{"label":"Rom-Com","value":"rom-com"},{"label":"Romance","value":"romance"},{"label":"School","value":"school"},{"label":"Shoujo","value":"shoujo"},{"label":"Slice of Life","value":"slice-of-life"},{"label":"Villain","value":"villain"},{"label":"Yuri","value":"yuri"}],"inputType":"Picker"}],"options":{"path":{"genres":"genre"},"lang":"English"}}); +export default plugin; + \ No newline at end of file diff --git a/plugins/english/ZinnNovel[madara].ts b/plugins/english/ZinnNovel[madara].ts index 5d7b94c..d83f336 100644 --- a/plugins/english/ZinnNovel[madara].ts +++ b/plugins/english/ZinnNovel[madara].ts @@ -1,213 +1,252 @@ +import { fetchApi, fetchFile } from "@libs/fetch"; +import { Filter } from "@libs/filterInputs"; +import { Plugin } from '@typings/plugin' import { load as parseHTML } from "cheerio"; -import { fetchFile, fetchApi } from "@libs/fetch"; -import { Novel, Plugin, Chapter } from "@typings/plugin"; -import { FilterInputs } from "@libs/filterInputs"; import { defaultCover } from "@libs/defaultCover"; -import { NovelStatus } from "@libs/novelStatus" +import { NovelStatus } from "@libs/novelStatus"; import { parseMadaraDate } from "@libs/parseMadaraDate"; import dayjs from "dayjs"; -export const id = "zinnovel"; -export const name = "ZinnNovel [madara]"; -export const icon = "multisrc/madara/icons/zinnnovel.png"; -export const version = "1.0.0"; -export const site = "https://zinnovel.com/"; -const baseUrl = site; +interface MadaraOptionPath{ + genres?: string, + novels?: string, + novel?: string, + chapter?: string, +} -export const popularNovels: Plugin.popularNovels = async (pageNo, {filters, showLatestNovels}) => { - const novels: Novel.Item[] = []; +const MadaraDefaultPath: MadaraOptionPath = { + novels: 'novel', + novel: 'novel', + chapter: 'novel' +} - let url = site; +interface MadaraOptions { + useNewChapterEndpoint?: boolean, + path?: MadaraOptionPath, + lang?: string, + orderBy?: string +} - if (filters?.genres) { - url += "manga-genre/" + filters.genres + '/'; - } else { - url += "manga/"; +export interface MadaraMetadata { + id: string, + sourceSite: string, + sourceName: string, + options?: MadaraOptions, + filters?: Filter[], +} +class MadaraPlugin implements Plugin.PluginBase { + id: string; + name: string; + icon: string; + site: string; + version: string; + userAgent: string; + cookieString: string; + options?: MadaraOptions; + filter?: Filter[] | undefined; + + constructor(metadata: MadaraMetadata){ + this.id = metadata.id; + this.name = metadata.sourceName + "[madara]"; + const iconFileName = metadata.sourceName.replace(/\s+/g, "").toLowerCase(); + this.icon = `multisrc/madara/icons/${iconFileName}.png`; + this.site = metadata.sourceSite; + this.version = "1.0.0"; + this.userAgent = ""; + this.cookieString = ""; + this.options = metadata.options; + this.filter = metadata.filters; } + async popularNovels(pageNo: number, {filters, showLatestNovels}: Plugin.PopularNovelsOptions): Promise { + const novels: Plugin.NovelItem[] = []; - url += '/page/' + pageNo + '/' + - '?m_orderby=' + (showLatestNovels ? 'latest' : (filters?.sort || 'rating')); - - const body = await fetchApi(url).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - - loadedCheerio('.manga-title-badges').remove(); - - loadedCheerio('.page-item-detail').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - - let novelUrl = loadedCheerio(this).find('.post-title') - .find('a') - .attr('href') || ''; - const novel: Novel.Item = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - - novels.push(novel); - }); - - return novels; -}; - -export const parseNovelAndChapters: Plugin.parseNovelAndChapters = async ( - novelUrl -) => { - const novel: Novel.instance = { - url: novelUrl, - }; - - const body = await fetchApi(novelUrl).then(res => res.text()); - - let loadedCheerio = parseHTML(body); - - loadedCheerio('.manga-title-badges').remove(); - - novel.name = loadedCheerio('.post-title h1').text().trim(); - - novel.cover = - loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || - loadedCheerio('.summary_image > a > img').attr('data-src') || - loadedCheerio('.summary_image > a > img').attr('src') || - defaultCover; - - loadedCheerio('.post-content_item, .post-content').each(function () { - const detailName = loadedCheerio(this).find('h5').text().trim(); - const detail = loadedCheerio(this).find('.summary-content').text().trim(); - - switch (detailName) { - case 'Genre(s)': - case 'التصنيفات': - novel.genres = detail.replace(/[\t\n]/g, ','); - break; - case 'Author(s)': - case 'المؤلف': - case 'المؤلف (ين)': - novel.author = detail; - break; - case 'Status': - case 'الحالة': - novel.status = - detail.includes('OnGoing') || detail.includes('مستمرة') - ? NovelStatus.Ongoing - : NovelStatus.Completed; - break; - } - }); - - loadedCheerio('div.summary__content .code-block,script').remove(); - novel.summary = loadedCheerio('div.summary__content').text().trim(); - - - let html; - - if (false) { - const novelId = - loadedCheerio('.rating-post-id').attr('value') || - loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; - - const body = { - action: "manga_get_chapters", - manga: novelId, - } - html = await fetchApi( - baseUrl + 'wp-admin/admin-ajax.php', - { - method: 'POST', - body: JSON.stringify(body), - }) - .then(res => res.text()); - } else { - html = await fetchApi( - baseUrl + 'ajax/chapters/', - { method: 'POST' }) - .then(res => res.text()); - } - - if (html !== '0') { - loadedCheerio = parseHTML(html); - } - - const chapters: Chapter.Item[] = []; - loadedCheerio('.wp-manga-chapter').each(function () { - const chapterName = loadedCheerio(this).find('a').text().trim(); - - let releaseDate = null; - releaseDate = loadedCheerio(this) - .find('span.chapter-release-date') - .text() - .trim(); - - if (releaseDate) { - releaseDate = parseMadaraDate(releaseDate); + let url = this.site; + if (filters?.genres && this.options?.path?.genres) { + url += this.options?.path?.genres + filters.genres + '/'; } else { - /** - * Insert current date - */ - - releaseDate = dayjs().format('LL'); + url += this.options?.path?.novels ? this.options.path.novels : MadaraDefaultPath.novels; } + + url += '/page/' + pageNo + '/' + + '?m_orderby=' + (showLatestNovels ? 'latest' : (filters?.sort || 'rating')); + + const body = await fetchApi(url).then(res => res.text()); + + const loadedCheerio = parseHTML(body); + + loadedCheerio('.manga-title-badges').remove(); + + loadedCheerio('.page-item-detail').each(function () { + const novelName = loadedCheerio(this).find('.post-title').text().trim(); + let image = loadedCheerio(this).find('img'); + const novelCover = image.attr('data-src') || image.attr('src'); + + let novelUrl = loadedCheerio(this).find('.post-title') + .find('a') + .attr('href') || ''; + const novel: Plugin.NovelItem = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + + novels.push(novel); + }); + + return novels; + } + async parseNovelAndChapters(novelUrl: string): Promise { + const novel: Plugin.SourceNovel = { + url: novelUrl, + }; + + const body = await fetchApi(novelUrl).then(res => res.text()); + + let loadedCheerio = parseHTML(body); + + loadedCheerio('.manga-title-badges, #manga-title span').remove(); + novel.name = + loadedCheerio('.post-title h1').text().trim() || + loadedCheerio('#manga-title h1').text(); + + novel.cover = + loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || + loadedCheerio('.summary_image > a > img').attr('data-src') || + loadedCheerio('.summary_image > a > img').attr('src') || + defaultCover; + + loadedCheerio('.post-content_item, .post-content').each(function () { + const detailName = loadedCheerio(this).find('h5').text().trim(); + const detail = loadedCheerio(this).find('.summary-content').text().trim(); + + switch (detailName) { + case 'Genre(s)': + case 'التصنيفات': + novel.genres = detail.replace(/[\\t\\n]/g, ','); + break; + case 'Author(s)': + case 'المؤلف': + case 'المؤلف (ين)': + novel.author = detail; + break; + case 'Status': + case 'الحالة': + novel.status = + detail.includes('OnGoing') || detail.includes('مستمرة') + ? NovelStatus.Ongoing + : NovelStatus.Completed; + break; + } + }); + + loadedCheerio('div.summary__content .code-block,script').remove(); + novel.summary = + loadedCheerio('div.summary__content').text().trim() || + loadedCheerio('#tab-manga-about').text().trim() || + loadedCheerio('.post-content_item h5:contains("Summary")').next().text().trim(); + + let html; + + if (this.options?.useNewChapterEndpoint !== true) { + const novelId = + loadedCheerio('.rating-post-id').attr('value') || + loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; + + const formData = new FormData() + formData.append("action", "manga_get_chapters"); + formData.append("manga", novelId); - let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + html = await fetchApi( + this.site + 'wp-admin/admin-ajax.php', + { + method: 'POST', + body: formData, + }) + .then(res => res.text()); + } else { + html = await fetchApi( + novelUrl + 'ajax/chapters/', + { method: 'POST' }) + .then(res => res.text()); + } + + if (html !== '0') { + loadedCheerio = parseHTML(html); + } + + const chapters: Plugin.ChapterItem[] = []; + loadedCheerio('.wp-manga-chapter').each(function () { + const chapterName = loadedCheerio(this).find('a').text().trim(); + + let releaseDate = null; + releaseDate = loadedCheerio(this) + .find('span.chapter-release-date') + .text() + .trim(); + + if (releaseDate) { + releaseDate = parseMadaraDate(releaseDate); + } else { + /** + * Insert current date + */ + + releaseDate = dayjs().format('LL'); + } + + let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + + chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); + }); + + novel.chapters = chapters.reverse(); + return novel; + } + async parseChapter(chapterUrl: string): Promise { + const body = await fetchApi(chapterUrl).then(res => res.text()); - chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); - }); + const loadedCheerio = parseHTML(body); + const chapterText = + loadedCheerio('.text-left').html() || + loadedCheerio('.text-right').html() || + loadedCheerio('.entry-content').html() || ""; - novel.chapters = chapters.reverse(); - return novel; -}; - -export const parseChapter: Plugin.parseChapter = async (chapterUrl) => { - const url = baseUrl + "/" + "manga" + "/" + chapterUrl; - - const body = await fetchApi(chapterUrl).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - const chapterText = - loadedCheerio('.text-left').html() || - loadedCheerio('.text-right').html() || - loadedCheerio('.entry-content').html(); - - return chapterText; -}; - -export const searchNovels: Plugin.searchNovels = async (searchTerm) => { - const novels: Novel.Item[] = []; - const url = baseUrl + "?s=" + searchTerm + "&post_type=wp-manga"; - - const body = await fetchApi(url).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - - - loadedCheerio('.c-tabs-item__content').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - - let novelUrl = loadedCheerio(this) - .find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - - novels.push(novel); - }); - return novels; -}; - -export const fetchImage: Plugin.fetchImage = async (url) => { - return await fetchFile(url); -}; - -export const filters = [{"key":"sort","label":"Order by","values":[{"label":"Rating","value":"rating"},{"label":"A-Z","value":"alphabet"},{"label":"Latest","value":"latest"},{"label":"Most Views","value":"views"},{"label":"New","value":"new-manga"},{"label":"Trending","value":"trending"}],"inputType":FilterInputs.Picker},{"key":"genres","label":"GENRES","values":[{"label":"Action","value":"action"},{"label":"Adult","value":"adult"},{"label":"Adventure","value":"adventure"},{"label":"Anime","value":"anime"},{"label":"Cartoon","value":"cartoon"},{"label":"Comedy","value":"comedy"},{"label":"Comic","value":"comic"},{"label":"Cooking","value":"cooking"},{"label":"Detective","value":"detective"},{"label":"Doujinshi","value":"doujinshi"},{"label":"Drama","value":"drama"},{"label":"Ecchi","value":"ecchi"},{"label":"Fantasy","value":"fantasy"},{"label":"Game","value":"game"},{"label":"Gender Bender","value":"gender-bender"},{"label":"Harem","value":"harem"},{"label":"Historical","value":"historical"},{"label":"Horror","value":"horror"},{"label":"Isekai","value":"isekai"},{"label":"Josei","value":"josei"},{"label":"Live action","value":"live-action"},{"label":"Lolicon","value":"lolicon"},{"label":"Magical Realism","value":"magical-realism"},{"label":"Manga","value":"manga"},{"label":"Manhua","value":"manhua"},{"label":"Manhwa","value":"manhwa"},{"label":"Martial Arts","value":"martial-arts"},{"label":"Mature","value":"mature"},{"label":"Mecha","value":"mecha"},{"label":"Mystery","value":"mystery"},{"label":"One shot","value":"one-shot"},{"label":"Psychological","value":"psychological"},{"label":"Reincarnation","value":"reincarnation"},{"label":"Romance","value":"romance"},{"label":"School Life","value":"school-life"},{"label":"Sci-fi","value":"sci-fi"},{"label":"Seinen","value":"seinen"},{"label":"Shoujo","value":"shoujo"},{"label":"Shoujo Ai","value":"shoujo-ai"},{"label":"Shounen","value":"shounen"},{"label":"Shounen Ai","value":"shounen-ai"},{"label":"Slice of Life","value":"slice-of-life"},{"label":"Smut","value":"smut"},{"label":"Soft Yaoi","value":"soft-yaoi"},{"label":"Soft Yuri","value":"soft-yuri"},{"label":"Sports","value":"sports"},{"label":"Supernatural","value":"supernatural"},{"label":"Tragedy","value":"tragedy"},{"label":"Video Games","value":"video-games"},{"label":"Webtoon","value":"webtoon"},{"label":"Wuxia","value":"wuxia"},{"label":"Xianxia","value":"xianxia"},{"label":"Xuanhuan","value":"xuanhuan"},{"label":"Yaoi","value":"yaoi"},{"label":"Yuri","value":"yuri"}],"inputType":FilterInputs.Picker}]; \ No newline at end of file + return chapterText; + } + async searchNovels(searchTerm: string, pageNo?: number | undefined): Promise { + const novels: Plugin.NovelItem[] = []; + const url = this.site + "?s=" + searchTerm + "&post_type=wp-manga"; + + const body = await fetchApi(url).then(res => res.text()); + + const loadedCheerio = parseHTML(body); + + + loadedCheerio('.c-tabs-item__content').each(function () { + const novelName = loadedCheerio(this).find('.post-title').text().trim(); + + let image = loadedCheerio(this).find('img'); + const novelCover = image.attr('data-src') || image.attr('src'); + + let novelUrl = loadedCheerio(this) + .find('.post-title') + .find('a') + .attr('href') || ''; + const novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + + novels.push(novel); + }); + return novels; + } + async fetchImage(url: string): Promise { + return await fetchFile(url, {}); + } +} +const plugin = new MadaraPlugin({"id":"zinnovel","sourceSite":"https://zinnovel.com/","sourceName":"ZinnNovel","filters":[{"key":"sort","label":"Order by","values":[{"label":"Rating","value":"rating"},{"label":"A-Z","value":"alphabet"},{"label":"Latest","value":"latest"},{"label":"Most Views","value":"views"},{"label":"New","value":"new-manga"},{"label":"Trending","value":"trending"}],"inputType":"Picker"},{"key":"genres","label":"GENRES","values":[{"label":"Action","value":"action"},{"label":"Adult","value":"adult"},{"label":"Adventure","value":"adventure"},{"label":"Anime","value":"anime"},{"label":"Cartoon","value":"cartoon"},{"label":"Comedy","value":"comedy"},{"label":"Comic","value":"comic"},{"label":"Cooking","value":"cooking"},{"label":"Detective","value":"detective"},{"label":"Doujinshi","value":"doujinshi"},{"label":"Drama","value":"drama"},{"label":"Ecchi","value":"ecchi"},{"label":"Fantasy","value":"fantasy"},{"label":"Game","value":"game"},{"label":"Gender Bender","value":"gender-bender"},{"label":"Harem","value":"harem"},{"label":"Historical","value":"historical"},{"label":"Horror","value":"horror"},{"label":"Isekai","value":"isekai"},{"label":"Josei","value":"josei"},{"label":"Live action","value":"live-action"},{"label":"Lolicon","value":"lolicon"},{"label":"Magical Realism","value":"magical-realism"},{"label":"Manga","value":"manga"},{"label":"Manhua","value":"manhua"},{"label":"Manhwa","value":"manhwa"},{"label":"Martial Arts","value":"martial-arts"},{"label":"Mature","value":"mature"},{"label":"Mecha","value":"mecha"},{"label":"Mystery","value":"mystery"},{"label":"One shot","value":"one-shot"},{"label":"Psychological","value":"psychological"},{"label":"Reincarnation","value":"reincarnation"},{"label":"Romance","value":"romance"},{"label":"School Life","value":"school-life"},{"label":"Sci-fi","value":"sci-fi"},{"label":"Seinen","value":"seinen"},{"label":"Shoujo","value":"shoujo"},{"label":"Shoujo Ai","value":"shoujo-ai"},{"label":"Shounen","value":"shounen"},{"label":"Shounen Ai","value":"shounen-ai"},{"label":"Slice of Life","value":"slice-of-life"},{"label":"Smut","value":"smut"},{"label":"Soft Yaoi","value":"soft-yaoi"},{"label":"Soft Yuri","value":"soft-yuri"},{"label":"Sports","value":"sports"},{"label":"Supernatural","value":"supernatural"},{"label":"Tragedy","value":"tragedy"},{"label":"Video Games","value":"video-games"},{"label":"Webtoon","value":"webtoon"},{"label":"Wuxia","value":"wuxia"},{"label":"Xianxia","value":"xianxia"},{"label":"Xuanhuan","value":"xuanhuan"},{"label":"Yaoi","value":"yaoi"},{"label":"Yuri","value":"yuri"}],"inputType":"Picker"}],"options":{"path":{"novels":"manga","novel":"manga","chapter":"manga","genres":"manga-genre"},"lang":"English"}}); +export default plugin; + \ No newline at end of file diff --git a/plugins/english/allnovelfull.ts b/plugins/english/allnovelfull.broken.ts similarity index 100% rename from plugins/english/allnovelfull.ts rename to plugins/english/allnovelfull.broken.ts diff --git a/plugins/english/bestlightnovel.ts b/plugins/english/bestlightnovel.ts index ae3aa29..ec41219 100644 --- a/plugins/english/bestlightnovel.ts +++ b/plugins/english/bestlightnovel.ts @@ -1,59 +1,60 @@ import { load as cheerioload } from "cheerio"; -import { Chapter, Novel, Plugin } from "@typings/plugin"; +import { Plugin } from "@typings/plugin"; import { defaultCover } from "@libs/defaultCover"; -import { fetchApi, fetchFile } from "@libs/fetch"; +import { fetchFile } from "@libs/fetch"; import { NovelStatus } from "@libs/novelStatus"; +import { Filter } from "@libs/filterInputs"; -export const id = "BLN.com"; -export const name = "BestLightNovel"; -export const site = "https://bestlightnovel.com/"; -export const version = "1.0.0"; -export const icon = "src/en/bestlightnovel/icon.png"; +class BLN implements Plugin.PluginBase { + id = "BLN.com"; + name = "BestLightNovel"; + icon = "src/en/bestlightnovel/icon.png"; + site = "https://bestlightnovel.com/"; + filter?: Filter[] | undefined; + version = "1.0.0"; + userAgent = ""; + cookieString = ""; + async popularNovels(pageNo: number, options: Plugin.PopularNovelsOptions): Promise { + const url = this.site + "novel_list?type=topview&category=all&state=all&page=1" + pageNo; -export const popularNovels: Plugin.popularNovels = async function (page) { - const url = - site + "novel_list?type=topview&category=all&state=all&page=1" + page; - - const result = await fetchApi(url); - if (!result.ok) { - console.error(await result.text()); - // TODO: Cloudflare protection or other error - return []; - } - const body = await result.text(); - - const loadedCheerio = cheerioload(body); - - let novels: Novel.Item[] = []; - - loadedCheerio(".update_item.list_category").each(function () { - const novelName = loadedCheerio(this).find("h3 > a").text(); - const novelCover = loadedCheerio(this).find("img").attr("src"); - const novelUrl = loadedCheerio(this).find("h3 > a").attr("href"); - - if (!novelUrl) { - // TODO: Handle error - console.error("No novel url!"); - return; + const result = await fetch(url); + if (!result.ok) { + console.error(await result.text()); + // TODO: Cloudflare protection or other error + return []; } + const body = await result.text(); - const novel = { - name: novelName, - url: novelUrl, - cover: novelCover, - }; + const loadedCheerio = cheerioload(body); - novels.push(novel); - }); + let novels: Plugin.NovelItem[] = []; - return novels; -}; + loadedCheerio(".update_item.list_category").each(function () { + const novelName = loadedCheerio(this).find("h3 > a").text(); + const novelCover = loadedCheerio(this).find("img").attr("src"); + const novelUrl = loadedCheerio(this).find("h3 > a").attr("href"); -export const parseNovelAndChapters: Plugin.parseNovelAndChapters = - async function (novelUrl) { + if (!novelUrl) { + // TODO: Handle error + console.error("No novel url!"); + return; + } + + const novel = { + name: novelName, + url: novelUrl, + cover: novelCover, + }; + + novels.push(novel); + }); + + return novels; + } + async parseNovelAndChapters(novelUrl: string): Promise { const url = novelUrl; - const result = await fetchApi(url); + const result = await fetch(url); if (!result.ok) { console.error(await result.text()); // TODO: Cloudflare protection @@ -63,7 +64,7 @@ export const parseNovelAndChapters: Plugin.parseNovelAndChapters = let loadedCheerio = cheerioload(body); - let novel: Novel.instance = { + let novel: Plugin.SourceNovel = { url, name: "", cover: "", @@ -97,7 +98,7 @@ export const parseNovelAndChapters: Plugin.parseNovelAndChapters = ? NovelStatus.Completed : NovelStatus.Unknown; - let novelChapters: Chapter.Item[] = []; + let novelChapters: Plugin.ChapterItem[] = []; loadedCheerio(".chapter-list div.row").each(function () { const chapterName = loadedCheerio(this).find("a").text().trim(); @@ -123,50 +124,51 @@ export const parseNovelAndChapters: Plugin.parseNovelAndChapters = novel.chapters = novelChapters.reverse(); return novel; - }; + } + async parseChapter(chapterUrl: string): Promise { + const url = chapterUrl; -export const parseChapter: Plugin.parseChapter = async function (chapterUrl) { - const url = chapterUrl; + const result = await fetch(url); + const body = await result.text(); - const result = await fetchApi(url); - const body = await result.text(); + let loadedCheerio = cheerioload(body); - let loadedCheerio = cheerioload(body); + const chapterText = loadedCheerio("#vung_doc").html() || ""; - const chapterText = loadedCheerio("#vung_doc").html(); + return chapterText; + } + async searchNovels(searchTerm: string, pageNo?: number | undefined): Promise { + const url = `${this.site}search_novels/${searchTerm}`; - return chapterText; -}; - -export const searchNovels: Plugin.searchNovels = async function (searchTerm) { - const url = `${site}search_novels/${searchTerm}`; - - const result = await fetchApi(url); - const body = await result.text(); - - let loadedCheerio = cheerioload(body); - - let novels: Novel.Item[] = []; - - loadedCheerio(".update_item.list_category").each(function () { - const novelName = loadedCheerio(this).find("h3 > a").text(); - const novelCover = loadedCheerio(this).find("img").attr("src"); - const novelUrl = loadedCheerio(this).find("h3 > a").attr("href"); - - if (!novelUrl) { - // TODO: Handle error - console.error("No novel url!"); - return; - } - - const novel = { name: novelName, cover: novelCover, url: novelUrl }; - - novels.push(novel); - }); - - return novels; -}; - -export const fetchImage: Plugin.fetchImage = (...args) => fetchFile(...args); + const result = await fetch(url); + const body = await result.text(); + + let loadedCheerio = cheerioload(body); + + let novels: Plugin.NovelItem[] = []; + + loadedCheerio(".update_item.list_category").each(function () { + const novelName = loadedCheerio(this).find("h3 > a").text(); + const novelCover = loadedCheerio(this).find("img").attr("src"); + const novelUrl = loadedCheerio(this).find("h3 > a").attr("href"); + + if (!novelUrl) { + // TODO: Handle error + console.error("No novel url!"); + return; + } + + const novel = { name: novelName, cover: novelCover, url: novelUrl }; + + novels.push(novel); + }); + + return novels; + } + async fetchImage(url: string): Promise { + return await fetchFile(url); + } +} +export default new BLN(); diff --git a/plugins/english/comrademao.ts b/plugins/english/comrademao.broken.ts similarity index 100% rename from plugins/english/comrademao.ts rename to plugins/english/comrademao.broken.ts diff --git a/plugins/english/divinedaolibrary.ts b/plugins/english/divinedaolibrary.broken.ts similarity index 100% rename from plugins/english/divinedaolibrary.ts rename to plugins/english/divinedaolibrary.broken.ts diff --git a/plugins/english/earlynovel.ts b/plugins/english/earlynovel.broken.ts similarity index 100% rename from plugins/english/earlynovel.ts rename to plugins/english/earlynovel.broken.ts diff --git a/plugins/english/fastnovel.ts b/plugins/english/fastnovel.broken.ts similarity index 100% rename from plugins/english/fastnovel.ts rename to plugins/english/fastnovel.broken.ts diff --git a/plugins/english/foxaholic.ts b/plugins/english/foxaholic.broken.ts similarity index 100% rename from plugins/english/foxaholic.ts rename to plugins/english/foxaholic.broken.ts diff --git a/plugins/english/freenovelupdates.ts b/plugins/english/freenovelupdates.broken.ts similarity index 100% rename from plugins/english/freenovelupdates.ts rename to plugins/english/freenovelupdates.broken.ts diff --git a/plugins/english/freewebnovel.ts b/plugins/english/freewebnovel.broken.ts similarity index 100% rename from plugins/english/freewebnovel.ts rename to plugins/english/freewebnovel.broken.ts diff --git a/plugins/english/lightnovelpub.ts b/plugins/english/lightnovelpub.broken.ts similarity index 100% rename from plugins/english/lightnovelpub.ts rename to plugins/english/lightnovelpub.broken.ts diff --git a/plugins/english/mtlreader.ts b/plugins/english/mtlreader.broken.ts similarity index 100% rename from plugins/english/mtlreader.ts rename to plugins/english/mtlreader.broken.ts diff --git a/plugins/english/nitroscans.ts b/plugins/english/nitroscans.broken.ts similarity index 100% rename from plugins/english/nitroscans.ts rename to plugins/english/nitroscans.broken.ts diff --git a/plugins/english/nobleMTL.ts b/plugins/english/nobleMTL.ts index a370f79..b2eac9f 100644 --- a/plugins/english/nobleMTL.ts +++ b/plugins/english/nobleMTL.ts @@ -1,72 +1,76 @@ -import { load as cheerioload } from "cheerio"; +import { load as parseHTML } from "cheerio"; import { fetchApi, fetchFile } from "@libs/fetch"; -import { Novel, Plugin, Chapter } from "@typings/plugin"; import { Filter, FilterInputs } from "@libs/filterInputs"; +import { Plugin } from "@typings/plugin"; -export const id = "NobleMTL"; -export const name = "NobleMTL"; -export const version = "1.0.0"; -export const icon = "src/en/noblemtl/icon.png"; -export const site = "https://www.noblemtl.com/"; +class NobleMTL implements Plugin.PluginBase { + id = "noblemtl"; + name = "NobleMTL"; + icon = "src/en/noblemtl/icon.png"; + site = "https://noblemtl.com/"; + version = "1.0.0"; + userAgent = ""; + cookieString = ""; + async popularNovels(pageNo: number, {filters}: Plugin.PopularNovelsOptions): Promise { + let link = `${this.site}series/?page=${pageNo}`; + if (filters) { + if (Array.isArray(filters.genres) && filters.genres.length) { + link += filters.genres.map((i) => `&genre[]=${i}`).join(""); + } -export const popularNovels: Plugin.popularNovels = async function ( - page, - { filters } -) { - let link = `${site}series/?page=${page}`; + if (Array.isArray(filters.type) && filters.type.length) + link += filters.type.map((i) => `&lang[]=${i}`).join(""); + } + link += "&status=" + (filters?.status ? filters.status : ""); - if (filters?.genres?.length) { - if (Array.isArray(filters.genres)) - link += filters.genres.map((i) => `&genre[]=${i}`).join(""); - } + link += "&order=" + (filters?.order ? filters.order : "popular"); - if (filters?.type?.length) { - if (Array.isArray(filters.type)) - link += filters.type.map((i) => `&lang[]=${i}`).join(""); - } + const headers = new Headers(); + if(this.cookieString){ + headers.append("cookie", this.cookieString); + } + const body = await fetchApi(link, {headers}).then((result) => + result.text() + ); - link += "&status=" + (filters?.status ? filters?.status : ""); + const loadedCheerio = parseHTML(body); - link += "&order=" + (filters?.order ? filters?.order : "popular"); + const novels: Plugin.NovelItem[] = []; - const body = await fetchApi(link).then((result) => result.text()); + loadedCheerio("article.bs").each(function () { + const novelName = loadedCheerio(this).find(".ntitle").text().trim(); + let image = loadedCheerio(this).find("img"); + const novelCover = image.attr("data-src") || image.attr("src"); - const loadedCheerio = cheerioload(body); + const novelUrl = loadedCheerio(this).find("a").attr("href"); - const novels: Novel.Item[] = []; + if (!novelUrl) return; - loadedCheerio("article.bs").each(function () { - const novelName = loadedCheerio(this).find(".ntitle").text().trim(); - let image = loadedCheerio(this).find("img"); - const novelCover = image.attr("data-src") || image.attr("src"); + const novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; - const novelUrl = loadedCheerio(this).find("a").attr("href"); + novels.push(novel); + }); - if (!novelUrl) return; + return novels; + }; - const novel: Novel.Item = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - - novels.push(novel); - }); - - return novels; -}; - -export const parseNovelAndChapters: Plugin.parseNovelAndChapters = - async function parseNovelAndChapters(novelUrl) { + async parseNovelAndChapters(novelUrl: string): Promise { const url = novelUrl; - - const result = await fetchApi(url); + const headers = new Headers(); + if(this.cookieString){ + headers.append("cookie", this.cookieString); + } + const result = await fetchApi(url, {headers}); const body = await result.text(); - let loadedCheerio = cheerioload(body); + let loadedCheerio = parseHTML(body); - const novel: Novel.instance = { + const novel: Plugin.SourceNovel = { url, chapters: [], }; @@ -79,22 +83,13 @@ export const parseNovelAndChapters: Plugin.parseNovelAndChapters = loadedCheerio("div.spe > span").each(function () { const detailName = loadedCheerio(this).find("b").text().trim(); - const detail = loadedCheerio(this) - .find("b") - .remove() - .end() - .text() - .trim(); + const detail = loadedCheerio(this).find('b').remove().end().text().trim(); switch (detailName) { - case "المؤلف:": - case "Yazar:": - case "Autor:": case "Author:": novel.author = detail; break; case "Status:": - case "Seviye:": novel.status = detail; break; } @@ -112,7 +107,7 @@ export const parseNovelAndChapters: Plugin.parseNovelAndChapters = .end() .text(); - let chapter: Chapter.Item[] = []; + let chapter: Plugin.ChapterItem[] = []; loadedCheerio(".eplister") .find("li") @@ -141,276 +136,282 @@ export const parseNovelAndChapters: Plugin.parseNovelAndChapters = novel.chapters = chapter.reverse(); return novel; - }; + } + async parseChapter(chapterUrl: string): Promise { + const headers = new Headers(); + if(this.cookieString){ + headers.append("cookie", this.cookieString); + } + const result = await fetchApi(chapterUrl, {headers}); + const body = await result.text(); -export const parseChapter: Plugin.parseChapter = async function (chapterUrl) { - const result = await fetchApi(chapterUrl); - const body = await result.text(); + const loadedCheerio = parseHTML(body); - const loadedCheerio = cheerioload(body); + let chapterText = loadedCheerio(".epcontent").html() || ""; - let chapterText = loadedCheerio("div.epcontent").html(); + return chapterText; + } - return chapterText; -}; + async searchNovels(searchTerm: string, pageNo?: number | undefined): Promise { + const url = `${this.site}?s=${searchTerm}`; + const headers = new Headers(); + if(this.cookieString){ + headers.append("cookie", this.cookieString); + } + const result = await fetchApi(url, {headers}); + const body = await result.text(); -export const searchNovels: Plugin.searchNovels = async function (searchTerm) { - const url = `${site}?s=${searchTerm}`; + const loadedCheerio = parseHTML(body); - const result = await fetchApi(url); - const body = await result.text(); + const novels: Plugin.NovelItem[] = []; - const loadedCheerio = cheerioload(body); + loadedCheerio("article.bs").each(function () { + const novelName = loadedCheerio(this).find(".ntitle").text().trim(); + const novelCover = loadedCheerio(this).find("img").attr("src"); + const novelUrl = loadedCheerio(this).find("a").attr("href"); + if (!novelUrl) return; - const novels: Novel.Item[] = []; - - loadedCheerio("article.bs").each(function () { - const novelName = loadedCheerio(this).find(".ntitle").text().trim(); - const novelCover = loadedCheerio(this).find("img").attr("src"); - const novelUrl = loadedCheerio(this).find("a").attr("href"); - if (!novelUrl) return; - - novels.push({ - name: novelName, - url: novelUrl, - cover: novelCover, + novels.push({ + name: novelName, + url: novelUrl, + cover: novelCover, + }); }); - }); - return novels; -}; + return novels; + } + async fetchImage(url: string): Promise { + return await fetchFile(url); + } -export const fetchImage: Plugin.fetchImage = async function (url) { - const headers = { - Referer: site, - }; - return await fetchFile(url, { headers: headers }); -}; -export const filters: Filter[] = [ - { - key: "order", - label: "Sort By", - values: [ - { label: "Default", value: "" }, + filters = [ + { + key: "order", + label: "Sort By", + values: [ + { label: "Default", value: "" }, - { label: "A-Z", value: "title" }, + { label: "A-Z", value: "title" }, - { label: "Z-A", value: "titlereverse" }, + { label: "Z-A", value: "titlereverse" }, - { label: "Latest Update", value: "update" }, + { label: "Latest Update", value: "update" }, - { label: "Latest Added", value: "latest" }, + { label: "Latest Added", value: "latest" }, - { label: "Popular", value: "popular" }, - ], - inputType: FilterInputs.Picker, - }, - { - key: "status", - label: "Status", - values: [ - { label: "All", value: "" }, + { label: "Popular", value: "popular" }, + ], + inputType: FilterInputs.Picker, + }, + { + key: "status", + label: "Status", + values: [ + { label: "All", value: "" }, - { label: "Ongoing", value: "ongoing" }, + { label: "Ongoing", value: "ongoing" }, - { label: "Hiatus", value: "hiatus" }, + { label: "Hiatus", value: "hiatus" }, - { label: "Completed", value: "completed" }, - ], - inputType: FilterInputs.Picker, - }, - { - key: "type", - label: "Type", - values: [ - { label: "Chinese novel", value: "chinese-novel" }, + { label: "Completed", value: "completed" }, + ], + inputType: FilterInputs.Picker, + }, + { + key: "type", + label: "Type", + values: [ + { label: "Chinese novel", value: "chinese-novel" }, - { label: "habyeol", value: "habyeol" }, + { label: "habyeol", value: "habyeol" }, - { label: "korean novel", value: "korean-novel" }, + { label: "korean novel", value: "korean-novel" }, - { label: "Web Novel", value: "web-novel" }, + { label: "Web Novel", value: "web-novel" }, - { label: "삼심", value: "%ec%82%bc%ec%8b%ac" }, + { label: "삼심", value: "%ec%82%bc%ec%8b%ac" }, - { label: "호곡", value: "%ed%98%b8%ea%b3%a1" }, - ], - inputType: FilterInputs.Checkbox, - }, - { - key: "genres", - label: "Genres", - values: [ - { label: "A.I", value: "a.i" }, + { label: "호곡", value: "%ed%98%b8%ea%b3%a1" }, + ], + inputType: FilterInputs.Checkbox, + }, + { + key: "genres", + label: "Genres", + values: [ + { label: "A.I", value: "a.i" }, - { label: "Academy", value: "academy" }, + { label: "Academy", value: "academy" }, - { label: "Action", value: "action" }, + { label: "Action", value: "action" }, - { label: "Adult", value: "adult" }, + { label: "Adult", value: "adult" }, - { label: "Adventure", value: "adventure" }, + { label: "Adventure", value: "adventure" }, - { label: "Alternative History", value: "alternative-history" }, + { label: "Alternative History", value: "alternative-history" }, - { label: "Another World", value: "another-world" }, + { label: "Another World", value: "another-world" }, - { label: "Apocalypse", value: "apocalypse" }, + { label: "Apocalypse", value: "apocalypse" }, - { label: "Bromance", value: "bromance" }, + { label: "Bromance", value: "bromance" }, - { label: "Comedy", value: "comedy" }, + { label: "Comedy", value: "comedy" }, - { label: "Dark fantasy", value: "dark-fantasy" }, + { label: "Dark fantasy", value: "dark-fantasy" }, - { label: "Demons", value: "demons" }, + { label: "Demons", value: "demons" }, - { label: "Drama", value: "drama" }, + { label: "Drama", value: "drama" }, - { label: "Dystopia", value: "dystopia" }, + { label: "Dystopia", value: "dystopia" }, - { label: "Ecchi", value: "ecchi" }, + { label: "Ecchi", value: "ecchi" }, - { label: "Entertainment", value: "entertainment" }, + { label: "Entertainment", value: "entertainment" }, - { label: "Exhaustion", value: "exhaustion" }, + { label: "Exhaustion", value: "exhaustion" }, - { label: "Fanfiction", value: "fanfiction" }, + { label: "Fanfiction", value: "fanfiction" }, - { label: "fantasy", value: "fantasy" }, + { label: "fantasy", value: "fantasy" }, - { label: "finance", value: "finance" }, + { label: "finance", value: "finance" }, - { label: "Full color", value: "full-color" }, + { label: "Full color", value: "full-color" }, - { label: "Game", value: "game" }, + { label: "Game", value: "game" }, - { label: "Gender Bender", value: "gender-bender" }, + { label: "Gender Bender", value: "gender-bender" }, - { label: "Genius", value: "genius" }, + { label: "Genius", value: "genius" }, - { label: "Harem", value: "harem" }, + { label: "Harem", value: "harem" }, - { label: "Hero", value: "hero" }, + { label: "Hero", value: "hero" }, - { label: "Historical", value: "historical" }, + { label: "Historical", value: "historical" }, - { label: "Hunter", value: "hunter" }, + { label: "Hunter", value: "hunter" }, - { label: "korean novel", value: "korean-novel" }, + { label: "korean novel", value: "korean-novel" }, - { label: "Light Novel", value: "light-novel" }, + { label: "Light Novel", value: "light-novel" }, - { - label: "List Adventure Manga Genres", - value: "list-adventure-manga-genres", - }, + { + label: "List Adventure Manga Genres", + value: "list-adventure-manga-genres", + }, - { label: "Long Strip", value: "long-strip" }, + { label: "Long Strip", value: "long-strip" }, - { label: "Love comedy", value: "love-comedy" }, + { label: "Love comedy", value: "love-comedy" }, - { label: "magic", value: "magic" }, + { label: "magic", value: "magic" }, - { label: "Manhua", value: "manhua" }, + { label: "Manhua", value: "manhua" }, - { label: "Martial Arts", value: "martial-arts" }, + { label: "Martial Arts", value: "martial-arts" }, - { label: "Mature", value: "mature" }, + { label: "Mature", value: "mature" }, - { label: "Medieval", value: "medieval" }, + { label: "Medieval", value: "medieval" }, - { label: "Misunderstanding", value: "misunderstanding" }, + { label: "Misunderstanding", value: "misunderstanding" }, - { label: "Modern", value: "modern" }, + { label: "Modern", value: "modern" }, - { label: "modern fantasy", value: "modern-fantasy" }, + { label: "modern fantasy", value: "modern-fantasy" }, - { label: "music", value: "music" }, + { label: "music", value: "music" }, - { label: "Mystery", value: "mystery" }, + { label: "Mystery", value: "mystery" }, - { label: "Necromancy", value: "necromancy" }, + { label: "Necromancy", value: "necromancy" }, - { label: "No Romance", value: "no-romance" }, + { label: "No Romance", value: "no-romance" }, - { label: "NTL", value: "ntl" }, + { label: "NTL", value: "ntl" }, - { label: "o", value: "o" }, + { label: "o", value: "o" }, - { label: "Obsession", value: "obsession" }, + { label: "Obsession", value: "obsession" }, - { label: "Politics", value: "politics" }, + { label: "Politics", value: "politics" }, - { label: "Possession", value: "possession" }, + { label: "Possession", value: "possession" }, - { label: "Programming", value: "programming" }, + { label: "Programming", value: "programming" }, - { label: "Psychological", value: "psychological" }, + { label: "Psychological", value: "psychological" }, - { label: "Pure Love", value: "pure-love" }, + { label: "Pure Love", value: "pure-love" }, - { label: "Redemption", value: "redemption" }, + { label: "Redemption", value: "redemption" }, - { label: "Regression", value: "regression" }, + { label: "Regression", value: "regression" }, - { label: "Regret", value: "regret" }, + { label: "Regret", value: "regret" }, - { label: "Reincarnation", value: "reincarnation" }, + { label: "Reincarnation", value: "reincarnation" }, - { label: "Revenge", value: "revenge" }, + { label: "Revenge", value: "revenge" }, - { label: "Romance", value: "romance" }, + { label: "Romance", value: "romance" }, - { label: "Romance Fanrasy", value: "romance-fanrasy" }, + { label: "Romance Fanrasy", value: "romance-fanrasy" }, - { label: "Salvation", value: "salvation" }, + { label: "Salvation", value: "salvation" }, - { label: "School Life", value: "school-life" }, + { label: "School Life", value: "school-life" }, - { label: "Sci-fi", value: "sci-fi" }, + { label: "Sci-fi", value: "sci-fi" }, - { label: "Science fiction", value: "science-fiction" }, + { label: "Science fiction", value: "science-fiction" }, - { label: "Seinen", value: "seinen" }, + { label: "Seinen", value: "seinen" }, - { label: "Shounen", value: "shounen" }, + { label: "Shounen", value: "shounen" }, - { label: "Slice of Life", value: "slice-of-life" }, + { label: "Slice of Life", value: "slice-of-life" }, - { label: "Soft yandere", value: "soft-yandere" }, + { label: "Soft yandere", value: "soft-yandere" }, - { label: "Sports", value: "sports" }, + { label: "Sports", value: "sports" }, - { label: "Supernatural", value: "supernatural" }, + { label: "Supernatural", value: "supernatural" }, - { label: "Survival", value: "survival" }, + { label: "Survival", value: "survival" }, - { label: "system", value: "system" }, + { label: "system", value: "system" }, - { label: "Time limit", value: "time-limit" }, + { label: "Time limit", value: "time-limit" }, - { label: "Tragedy", value: "tragedy" }, + { label: "Tragedy", value: "tragedy" }, - { label: "Transmigration", value: "transmigration" }, + { label: "Transmigration", value: "transmigration" }, - { label: "TS", value: "ts" }, + { label: "TS", value: "ts" }, - { label: "Tsundere", value: "tsundere" }, + { label: "Tsundere", value: "tsundere" }, - { label: "Unique", value: "unique" }, + { label: "Unique", value: "unique" }, - { label: "Wholesome", value: "wholesome" }, + { label: "Wholesome", value: "wholesome" }, - { label: "Wuxia", value: "wuxia" }, + { label: "Wuxia", value: "wuxia" }, - { label: "Xuanhuan", value: "xuanhuan" }, + { label: "Xuanhuan", value: "xuanhuan" }, - { label: "Yandere", value: "yandere" }, + { label: "Yandere", value: "yandere" }, - { label: "Yuri", value: "yuri" }, - ], - inputType: FilterInputs.Checkbox, - }, -]; + { label: "Yuri", value: "yuri" }, + ], + inputType: FilterInputs.Checkbox, + }, + ]; +} + +export default new NobleMTL(); \ No newline at end of file diff --git a/plugins/english/novelforest.ts b/plugins/english/novelforest.broken.ts similarity index 100% rename from plugins/english/novelforest.ts rename to plugins/english/novelforest.broken.ts diff --git a/plugins/english/novelfull.ts b/plugins/english/novelfull.broken.ts similarity index 100% rename from plugins/english/novelfull.ts rename to plugins/english/novelfull.broken.ts diff --git a/plugins/english/novelhold.ts b/plugins/english/novelhold.broken.ts similarity index 100% rename from plugins/english/novelhold.ts rename to plugins/english/novelhold.broken.ts diff --git a/plugins/english/novelpub.ts b/plugins/english/novelpub.broken.ts similarity index 100% rename from plugins/english/novelpub.ts rename to plugins/english/novelpub.broken.ts diff --git a/plugins/english/pandaMTL.ts b/plugins/english/pandaMTL.ts index 4057bfc..06f8282 100644 --- a/plugins/english/pandaMTL.ts +++ b/plugins/english/pandaMTL.ts @@ -1,76 +1,74 @@ import { load as parseHTML } from "cheerio"; import { fetchApi, fetchFile } from "@libs/fetch"; -import { FilterInputs } from "@libs/filterInputs"; -import { Chapter, Novel, Plugin } from "@typings/plugin"; +import { Filter, FilterInputs } from "@libs/filterInputs"; +import { Plugin } from "@typings/plugin"; -export const id = "PandaMTL"; -export const name = "PandaMTL"; -export const version = "1.0.0"; -export const icon = "src/en/wordpress/icon.png"; -export const site = "https://www.pandamtl.com/"; +class PandaMTL implements Plugin.PluginBase { + id = "pandamtl"; + name = "PandaMTL"; + icon = "src/en/wordpress/icon.png"; + site = "https://pandamtl.com/"; + version = "1.0.0"; + userAgent = ""; + cookieString = ""; + async popularNovels(pageNo: number, {filters}: Plugin.PopularNovelsOptions): Promise { + let link = `${this.site}series/?page=${pageNo}`; + if (filters) { + if (Array.isArray(filters.genres) && filters.genres.length) { + link += filters.genres.map((i) => `&genre[]=${i}`).join(""); + } -const pluginId = id; -const baseUrl = site; - -export const popularNovels: Plugin.popularNovels = async function ( - page, - { filters } -) { - let link = `${baseUrl}series/?page=${page}`; - - if (filters) { - if (Array.isArray(filters.genres) && filters.genres.length) { - link += filters.genres.map((i) => `&genre[]=${i}`).join(""); + if (Array.isArray(filters.type) && filters.type.length) + link += filters.type.map((i) => `&lang[]=${i}`).join(""); } + link += "&status=" + (filters?.status ? filters.status : ""); - if (Array.isArray(filters.type) && filters.type.length) { - link += filters.type.map((i) => `&lang[]=${i}`).join(""); + link += "&order=" + (filters?.order ? filters.order : "popular"); + + const headers = new Headers(); + if(this.cookieString){ + headers.append("cookie", this.cookieString); } + const body = await fetchApi(link, {headers}).then((result) => + result.text() + ); + + const loadedCheerio = parseHTML(body); + + const novels: Plugin.NovelItem[] = []; + + loadedCheerio("article.maindet").each(function () { + const novelName = loadedCheerio(this).find("h2").text(); + let image = loadedCheerio(this).find("img"); + const novelCover = image.attr("data-src") || image.attr("src"); + const novelUrl = loadedCheerio(this).find("h2 a").attr("href"); + + if (!novelUrl) return; + + const novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + + novels.push(novel); + }); + + return novels; } - - link += "&status=" + (filters?.status ? filters?.status : ""); - - link += "&order=" + (filters?.order ? filters?.order : "popular"); - - const body = await fetchApi(link, {}, pluginId).then((result) => - result.text() - ); - - const loadedCheerio = parseHTML(body); - - const novels: Novel.Item[] = []; - - loadedCheerio("article.maindet").each(function () { - const novelName = loadedCheerio(this).find("h2").text(); - let image = loadedCheerio(this).find("img"); - const novelCover = image.attr("data-src") || image.attr("src"); - const novelUrl = loadedCheerio(this).find("h2 a").attr("href"); - - if (!novelUrl) return; - - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - - novels.push(novel); - }); - - return novels; -}; - -export const parseNovelAndChapters: Plugin.parseNovelAndChapters = - async function (novelUrl) { + async parseNovelAndChapters(novelUrl: string): Promise { const url = novelUrl; - - const result = await fetchApi(url, {}, pluginId); + const headers = new Headers(); + if(this.cookieString){ + headers.append("cookie", this.cookieString); + } + const result = await fetchApi(url, {headers}); const body = await result.text(); let loadedCheerio = parseHTML(body); - const novel: Novel.instance = { + const novel: Plugin.SourceNovel = { url, chapters: [], }; @@ -81,19 +79,18 @@ export const parseNovelAndChapters: Plugin.parseNovelAndChapters = loadedCheerio("img.wp-post-image").attr("data-src") || loadedCheerio("img.wp-post-image").attr("src"); - loadedCheerio("div.serl:nth-child(3) > span").each(function () { + loadedCheerio(".serl:nth-child(3) > span").each(function () { const detailName = loadedCheerio(this).text().trim(); const detail = loadedCheerio(this).next().text().trim(); switch (detailName) { - case "الكاتب": case "Author": novel.author = detail; break; } }); - novel.status = loadedCheerio("div.sertostat > span").attr("class"); + novel.status = loadedCheerio(".sertostat > span").attr("class"); novel.genres = loadedCheerio(".sertogenre") .children("a") @@ -107,7 +104,7 @@ export const parseNovelAndChapters: Plugin.parseNovelAndChapters = .end() .text(); - let chapter: Chapter.Item[] = []; + let chapter: Plugin.ChapterItem[] = []; loadedCheerio(".eplister") .find("li") @@ -136,139 +133,144 @@ export const parseNovelAndChapters: Plugin.parseNovelAndChapters = novel.chapters = chapter.reverse(); return novel; - }; + } + async parseChapter(chapterUrl: string): Promise { + const headers = new Headers(); + if(this.cookieString){ + headers.append("cookie", this.cookieString); + } + const result = await fetchApi(chapterUrl, {headers}); + const body = await result.text(); -export const parseChapter: Plugin.parseChapter = async function (chapterUrl) { - const result = await fetchApi(chapterUrl, {}, pluginId); - const body = await result.text(); + const loadedCheerio = parseHTML(body); - const loadedCheerio = parseHTML(body); + let chapterText = loadedCheerio(".epcontent").html() || ""; - let chapterText = loadedCheerio(".epcontent").html(); + return chapterText; + } + async searchNovels(searchTerm: string, pageNo?: number | undefined): Promise { + const url = `${this.site}?s=${searchTerm}`; + const headers = new Headers(); + if(this.cookieString){ + headers.append("cookie", this.cookieString); + } + const result = await fetchApi(url, {headers}); + const body = await result.text(); - return chapterText; -}; + const loadedCheerio = parseHTML(body); -export const searchNovels: Plugin.searchNovels = async function (searchTerm) { - const url = `${baseUrl}?s=${searchTerm}`; + const novels: Plugin.NovelItem[] = []; - const result = await fetchApi(url, {}, pluginId); - const body = await result.text(); + loadedCheerio("article.maindet").each(function () { + const novelName = loadedCheerio(this).find("h2").text(); + let image = loadedCheerio(this).find("img"); + const novelCover = image.attr("data-src") || image.attr("src"); + const novelUrl = loadedCheerio(this).find("h2 a").attr("href"); - const loadedCheerio = parseHTML(body); + if (!novelUrl) return; - const novels: Novel.Item[] = []; - - loadedCheerio("article.maindet").each(function () { - const novelName = loadedCheerio(this).find("h2").text(); - let image = loadedCheerio(this).find("img"); - const novelCover = image.attr("data-src") || image.attr("src"); - const novelUrl = loadedCheerio(this).find("h2 a").attr("href"); - - if (!novelUrl) return; - - novels.push({ - name: novelName, - url: novelUrl, - cover: novelCover, + novels.push({ + name: novelName, + url: novelUrl, + cover: novelCover, + }); }); - }); - return novels; -}; + return novels; + } + async fetchImage(url: string): Promise { + return await fetchFile(url); + } -export const fetchImage: Plugin.fetchImage = async function (url) { - const headers = { - Referer: baseUrl, - }; - return await fetchFile(url, { headers: headers }); -}; -export const filters = [ - { - key: "order", - label: "Sort By", - values: [ - { label: "Default", value: "" }, + filters = [ + { + key: "order", + label: "Sort By", + values: [ + { label: "Default", value: "" }, - { label: "A-Z", value: "title" }, + { label: "A-Z", value: "title" }, - { label: "Z-A", value: "titlereverse" }, + { label: "Z-A", value: "titlereverse" }, - { label: "Latest Update", value: "update" }, + { label: "Latest Update", value: "update" }, - { label: "Latest Added", value: "latest" }, + { label: "Latest Added", value: "latest" }, - { label: "Popular", value: "popular" }, - ], - inputType: FilterInputs.Picker, - }, - { - key: "status", - label: "Status", - values: [ - { label: "All", value: "" }, + { label: "Popular", value: "popular" }, + ], + inputType: FilterInputs.Picker, + }, + { + key: "status", + label: "Status", + values: [ + { label: "All", value: "" }, - { label: "Ongoing", value: "ongoing" }, + { label: "Ongoing", value: "ongoing" }, - { label: "Hiatus", value: "hiatus" }, + { label: "Hiatus", value: "hiatus" }, - { label: "Completed", value: "completed" }, - ], - inputType: FilterInputs.Picker, - }, - { - key: "type", - label: "Type", - values: [ - { label: "Light Novel (KR)", value: "light-novel-kr" }, + { label: "Completed", value: "completed" }, + ], + inputType: FilterInputs.Picker, + }, + { + key: "type", + label: "Type", + values: [ + { label: "Light Novel (KR)", value: "light-novel-kr" }, - { label: "Web Novel", value: "web-novel" }, - ], - inputType: FilterInputs.Checkbox, - }, - { - key: "genres", - label: "Genres", - values: [ - { label: "Action", value: "action" }, + { label: "Web Novel", value: "web-novel" }, + ], + inputType: FilterInputs.Checkbox, + }, + { + key: "genres", + label: "Genres", + values: [ + { label: "Action", value: "action" }, - { label: "Adult", value: "adult" }, + { label: "Adult", value: "adult" }, - { label: "Adventure", value: "adventure" }, + { label: "Adventure", value: "adventure" }, - { label: "Comedy", value: "comedy" }, + { label: "Comedy", value: "comedy" }, - { label: "Ecchi", value: "ecchi" }, + { label: "Ecchi", value: "ecchi" }, - { label: "Fantasy", value: "fantasy" }, + { label: "Fantasy", value: "fantasy" }, - { label: "Harem", value: "harem" }, + { label: "Harem", value: "harem" }, - { label: "Josei", value: "josei" }, + { label: "Josei", value: "josei" }, - { label: "Martial Arts", value: "martial-arts" }, + { label: "Martial Arts", value: "martial-arts" }, - { label: "Mature", value: "mature" }, + { label: "Mature", value: "mature" }, - { label: "Romance", value: "romance" }, + { label: "Romance", value: "romance" }, - { label: "School Life", value: "school-life" }, + { label: "School Life", value: "school-life" }, - { label: "Sci-fi", value: "sci-fi" }, + { label: "Sci-fi", value: "sci-fi" }, - { label: "Seinen", value: "seinen" }, + { label: "Seinen", value: "seinen" }, - { label: "Slice of Life", value: "slice-of-life" }, + { label: "Slice of Life", value: "slice-of-life" }, - { label: "Smut", value: "smut" }, + { label: "Smut", value: "smut" }, - { label: "Sports", value: "sports" }, + { label: "Sports", value: "sports" }, - { label: "Supernatural", value: "supernatural" }, + { label: "Supernatural", value: "supernatural" }, - { label: "Tragedy", value: "tragedy" }, - ], - inputType: FilterInputs.Checkbox, - }, -]; + { label: "Tragedy", value: "tragedy" }, + ], + inputType: FilterInputs.Checkbox, + }, + ]; +} + +export default new PandaMTL(); \ No newline at end of file diff --git a/plugins/french/.french b/plugins/french/.french deleted file mode 100644 index e69de29..0000000 diff --git a/plugins/french/chireads.ts b/plugins/french/chireads.broken.ts similarity index 100% rename from plugins/french/chireads.ts rename to plugins/french/chireads.broken.ts diff --git a/plugins/indonesian/.indonesian b/plugins/indonesian/.indonesian deleted file mode 100644 index e69de29..0000000 diff --git a/plugins/indonesian/MeioNovel[madara].ts b/plugins/indonesian/MeioNovel[madara].ts index 8811f0d..6c3eb8c 100644 --- a/plugins/indonesian/MeioNovel[madara].ts +++ b/plugins/indonesian/MeioNovel[madara].ts @@ -1,213 +1,252 @@ +import { fetchApi, fetchFile } from "@libs/fetch"; +import { Filter } from "@libs/filterInputs"; +import { Plugin } from '@typings/plugin' import { load as parseHTML } from "cheerio"; -import { fetchFile, fetchApi } from "@libs/fetch"; -import { Novel, Plugin, Chapter } from "@typings/plugin"; -import { FilterInputs } from "@libs/filterInputs"; import { defaultCover } from "@libs/defaultCover"; -import { NovelStatus } from "@libs/novelStatus" +import { NovelStatus } from "@libs/novelStatus"; import { parseMadaraDate } from "@libs/parseMadaraDate"; import dayjs from "dayjs"; -export const id = "meionovel"; -export const name = "MeioNovel [madara]"; -export const icon = "multisrc/madara/icons/meionovel.png"; -export const version = "1.0.0"; -export const site = "https://meionovel.id/"; -const baseUrl = site; +interface MadaraOptionPath{ + genres?: string, + novels?: string, + novel?: string, + chapter?: string, +} -export const popularNovels: Plugin.popularNovels = async (pageNo, {filters, showLatestNovels}) => { - const novels: Novel.Item[] = []; +const MadaraDefaultPath: MadaraOptionPath = { + novels: 'novel', + novel: 'novel', + chapter: 'novel' +} - let url = site; +interface MadaraOptions { + useNewChapterEndpoint?: boolean, + path?: MadaraOptionPath, + lang?: string, + orderBy?: string +} - if (filters?.genres) { - url += "novel-genre/" + filters.genres + '/'; - } else { - url += "novel/"; +export interface MadaraMetadata { + id: string, + sourceSite: string, + sourceName: string, + options?: MadaraOptions, + filters?: Filter[], +} +class MadaraPlugin implements Plugin.PluginBase { + id: string; + name: string; + icon: string; + site: string; + version: string; + userAgent: string; + cookieString: string; + options?: MadaraOptions; + filter?: Filter[] | undefined; + + constructor(metadata: MadaraMetadata){ + this.id = metadata.id; + this.name = metadata.sourceName + "[madara]"; + const iconFileName = metadata.sourceName.replace(/\s+/g, "").toLowerCase(); + this.icon = `multisrc/madara/icons/${iconFileName}.png`; + this.site = metadata.sourceSite; + this.version = "1.0.0"; + this.userAgent = ""; + this.cookieString = ""; + this.options = metadata.options; + this.filter = metadata.filters; } + async popularNovels(pageNo: number, {filters, showLatestNovels}: Plugin.PopularNovelsOptions): Promise { + const novels: Plugin.NovelItem[] = []; - url += '/page/' + pageNo + '/' + - '?m_orderby=' + (showLatestNovels ? 'latest' : (filters?.sort || 'rating')); - - const body = await fetchApi(url).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - - loadedCheerio('.manga-title-badges').remove(); - - loadedCheerio('.page-item-detail').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - - let novelUrl = loadedCheerio(this).find('.post-title') - .find('a') - .attr('href') || ''; - const novel: Novel.Item = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - - novels.push(novel); - }); - - return novels; -}; - -export const parseNovelAndChapters: Plugin.parseNovelAndChapters = async ( - novelUrl -) => { - const novel: Novel.instance = { - url: novelUrl, - }; - - const body = await fetchApi(novelUrl).then(res => res.text()); - - let loadedCheerio = parseHTML(body); - - loadedCheerio('.manga-title-badges').remove(); - - novel.name = loadedCheerio('.post-title h1').text().trim(); - - novel.cover = - loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || - loadedCheerio('.summary_image > a > img').attr('data-src') || - loadedCheerio('.summary_image > a > img').attr('src') || - defaultCover; - - loadedCheerio('.post-content_item, .post-content').each(function () { - const detailName = loadedCheerio(this).find('h5').text().trim(); - const detail = loadedCheerio(this).find('.summary-content').text().trim(); - - switch (detailName) { - case 'Genre(s)': - case 'التصنيفات': - novel.genres = detail.replace(/[\t\n]/g, ','); - break; - case 'Author(s)': - case 'المؤلف': - case 'المؤلف (ين)': - novel.author = detail; - break; - case 'Status': - case 'الحالة': - novel.status = - detail.includes('OnGoing') || detail.includes('مستمرة') - ? NovelStatus.Ongoing - : NovelStatus.Completed; - break; - } - }); - - loadedCheerio('div.summary__content .code-block,script').remove(); - novel.summary = loadedCheerio('div.summary__content').text().trim(); - - - let html; - - if (true) { - const novelId = - loadedCheerio('.rating-post-id').attr('value') || - loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; - - const body = { - action: "manga_get_chapters", - manga: novelId, - } - html = await fetchApi( - baseUrl + 'wp-admin/admin-ajax.php', - { - method: 'POST', - body: JSON.stringify(body), - }) - .then(res => res.text()); - } else { - html = await fetchApi( - baseUrl + 'ajax/chapters/', - { method: 'POST' }) - .then(res => res.text()); - } - - if (html !== '0') { - loadedCheerio = parseHTML(html); - } - - const chapters: Chapter.Item[] = []; - loadedCheerio('.wp-manga-chapter').each(function () { - const chapterName = loadedCheerio(this).find('a').text().trim(); - - let releaseDate = null; - releaseDate = loadedCheerio(this) - .find('span.chapter-release-date') - .text() - .trim(); - - if (releaseDate) { - releaseDate = parseMadaraDate(releaseDate); + let url = this.site; + if (filters?.genres && this.options?.path?.genres) { + url += this.options?.path?.genres + filters.genres + '/'; } else { - /** - * Insert current date - */ - - releaseDate = dayjs().format('LL'); + url += this.options?.path?.novels ? this.options.path.novels : MadaraDefaultPath.novels; } + + url += '/page/' + pageNo + '/' + + '?m_orderby=' + (showLatestNovels ? 'latest' : (filters?.sort || 'rating')); + + const body = await fetchApi(url).then(res => res.text()); + + const loadedCheerio = parseHTML(body); + + loadedCheerio('.manga-title-badges').remove(); + + loadedCheerio('.page-item-detail').each(function () { + const novelName = loadedCheerio(this).find('.post-title').text().trim(); + let image = loadedCheerio(this).find('img'); + const novelCover = image.attr('data-src') || image.attr('src'); + + let novelUrl = loadedCheerio(this).find('.post-title') + .find('a') + .attr('href') || ''; + const novel: Plugin.NovelItem = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + + novels.push(novel); + }); + + return novels; + } + async parseNovelAndChapters(novelUrl: string): Promise { + const novel: Plugin.SourceNovel = { + url: novelUrl, + }; + + const body = await fetchApi(novelUrl).then(res => res.text()); + + let loadedCheerio = parseHTML(body); + + loadedCheerio('.manga-title-badges, #manga-title span').remove(); + novel.name = + loadedCheerio('.post-title h1').text().trim() || + loadedCheerio('#manga-title h1').text(); + + novel.cover = + loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || + loadedCheerio('.summary_image > a > img').attr('data-src') || + loadedCheerio('.summary_image > a > img').attr('src') || + defaultCover; + + loadedCheerio('.post-content_item, .post-content').each(function () { + const detailName = loadedCheerio(this).find('h5').text().trim(); + const detail = loadedCheerio(this).find('.summary-content').text().trim(); + + switch (detailName) { + case 'Genre(s)': + case 'التصنيفات': + novel.genres = detail.replace(/[\\t\\n]/g, ','); + break; + case 'Author(s)': + case 'المؤلف': + case 'المؤلف (ين)': + novel.author = detail; + break; + case 'Status': + case 'الحالة': + novel.status = + detail.includes('OnGoing') || detail.includes('مستمرة') + ? NovelStatus.Ongoing + : NovelStatus.Completed; + break; + } + }); + + loadedCheerio('div.summary__content .code-block,script').remove(); + novel.summary = + loadedCheerio('div.summary__content').text().trim() || + loadedCheerio('#tab-manga-about').text().trim() || + loadedCheerio('.post-content_item h5:contains("Summary")').next().text().trim(); + + let html; + + if (this.options?.useNewChapterEndpoint !== true) { + const novelId = + loadedCheerio('.rating-post-id').attr('value') || + loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; + + const formData = new FormData() + formData.append("action", "manga_get_chapters"); + formData.append("manga", novelId); - let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + html = await fetchApi( + this.site + 'wp-admin/admin-ajax.php', + { + method: 'POST', + body: formData, + }) + .then(res => res.text()); + } else { + html = await fetchApi( + novelUrl + 'ajax/chapters/', + { method: 'POST' }) + .then(res => res.text()); + } + + if (html !== '0') { + loadedCheerio = parseHTML(html); + } + + const chapters: Plugin.ChapterItem[] = []; + loadedCheerio('.wp-manga-chapter').each(function () { + const chapterName = loadedCheerio(this).find('a').text().trim(); + + let releaseDate = null; + releaseDate = loadedCheerio(this) + .find('span.chapter-release-date') + .text() + .trim(); + + if (releaseDate) { + releaseDate = parseMadaraDate(releaseDate); + } else { + /** + * Insert current date + */ + + releaseDate = dayjs().format('LL'); + } + + let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + + chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); + }); + + novel.chapters = chapters.reverse(); + return novel; + } + async parseChapter(chapterUrl: string): Promise { + const body = await fetchApi(chapterUrl).then(res => res.text()); - chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); - }); + const loadedCheerio = parseHTML(body); + const chapterText = + loadedCheerio('.text-left').html() || + loadedCheerio('.text-right').html() || + loadedCheerio('.entry-content').html() || ""; - novel.chapters = chapters.reverse(); - return novel; -}; - -export const parseChapter: Plugin.parseChapter = async (chapterUrl) => { - const url = baseUrl + "/" + "novel" + "/" + chapterUrl; - - const body = await fetchApi(chapterUrl).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - const chapterText = - loadedCheerio('.text-left').html() || - loadedCheerio('.text-right').html() || - loadedCheerio('.entry-content').html(); - - return chapterText; -}; - -export const searchNovels: Plugin.searchNovels = async (searchTerm) => { - const novels: Novel.Item[] = []; - const url = baseUrl + "?s=" + searchTerm + "&post_type=wp-manga"; - - const body = await fetchApi(url).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - - - loadedCheerio('.c-tabs-item__content').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - - let novelUrl = loadedCheerio(this) - .find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - - novels.push(novel); - }); - return novels; -}; - -export const fetchImage: Plugin.fetchImage = async (url) => { - return await fetchFile(url); -}; - -export const filters = [{"key":"sort","label":"Order by","values":[{"label":"Rating","value":"rating"},{"label":"A-Z","value":"alphabet"},{"label":"Latest","value":"latest"},{"label":"Most Views","value":"views"},{"label":"New","value":"new-manga"},{"label":"Trending","value":"trending"}],"inputType":FilterInputs.Picker},{"key":"genres","label":"GENRES","values":[{"label":"Action","value":"action"},{"label":"Adventure","value":"adventure"},{"label":"Comedy","value":"comedy"},{"label":"Cooking","value":"cooking"},{"label":"Drama","value":"drama"},{"label":"Ecchi","value":"ecchi"},{"label":"Fanfiction","value":"fanfiction"},{"label":"Fantasy","value":"fantasy"},{"label":"Gender Bender","value":"gender-bender"},{"label":"Harem","value":"harem"},{"label":"Historical","value":"historical"},{"label":"Horror","value":"horror"},{"label":"Isekai","value":"isekai"},{"label":"Josei","value":"josei"},{"label":"Magic","value":"magic"},{"label":"Martial Arts","value":"martial-arts"},{"label":"Mature","value":"mature"},{"label":"Mecha","value":"mecha"},{"label":"Mystery","value":"mystery"},{"label":"One shot","value":"one-shot"},{"label":"Psychological","value":"psychological"},{"label":"Reverse Harem","value":"reverse-harem"},{"label":"Romance","value":"romance"},{"label":"School Life","value":"school-life"},{"label":"Sci-fi","value":"sci-fi"},{"label":"Seinen","value":"seinen"},{"label":"Shoujo","value":"shoujo"},{"label":"Shoujo Ai","value":"shoujo-ai"},{"label":"Shounen","value":"shounen"},{"label":"Shounen Ai","value":"shounen-ai"},{"label":"Slice of Life","value":"slice-of-life"},{"label":"Smut","value":"smut"},{"label":"Sports","value":"sports"},{"label":"Supernatural","value":"supernatural"},{"label":"Tragedy","value":"tragedy"},{"label":"Virtual Reality","value":"virtual-reality"},{"label":"Wuxia","value":"wuxia"},{"label":"Xianxia","value":"xianxia"},{"label":"Xuanhuan","value":"xuanhuan"},{"label":"Yuri","value":"yuri"}],"inputType":FilterInputs.Picker}]; \ No newline at end of file + return chapterText; + } + async searchNovels(searchTerm: string, pageNo?: number | undefined): Promise { + const novels: Plugin.NovelItem[] = []; + const url = this.site + "?s=" + searchTerm + "&post_type=wp-manga"; + + const body = await fetchApi(url).then(res => res.text()); + + const loadedCheerio = parseHTML(body); + + + loadedCheerio('.c-tabs-item__content').each(function () { + const novelName = loadedCheerio(this).find('.post-title').text().trim(); + + let image = loadedCheerio(this).find('img'); + const novelCover = image.attr('data-src') || image.attr('src'); + + let novelUrl = loadedCheerio(this) + .find('.post-title') + .find('a') + .attr('href') || ''; + const novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + + novels.push(novel); + }); + return novels; + } + async fetchImage(url: string): Promise { + return await fetchFile(url, {}); + } +} +const plugin = new MadaraPlugin({"id":"meionovel","sourceSite":"https://meionovel.id/","sourceName":"MeioNovel","filters":[{"key":"sort","label":"Order by","values":[{"label":"Rating","value":"rating"},{"label":"A-Z","value":"alphabet"},{"label":"Latest","value":"latest"},{"label":"Most Views","value":"views"},{"label":"New","value":"new-manga"},{"label":"Trending","value":"trending"}],"inputType":"Picker"},{"key":"genres","label":"GENRES","values":[{"label":"Action","value":"action"},{"label":"Adventure","value":"adventure"},{"label":"Comedy","value":"comedy"},{"label":"Cooking","value":"cooking"},{"label":"Drama","value":"drama"},{"label":"Ecchi","value":"ecchi"},{"label":"Fanfiction","value":"fanfiction"},{"label":"Fantasy","value":"fantasy"},{"label":"Gender Bender","value":"gender-bender"},{"label":"Harem","value":"harem"},{"label":"Historical","value":"historical"},{"label":"Horror","value":"horror"},{"label":"Isekai","value":"isekai"},{"label":"Josei","value":"josei"},{"label":"Magic","value":"magic"},{"label":"Martial Arts","value":"martial-arts"},{"label":"Mature","value":"mature"},{"label":"Mecha","value":"mecha"},{"label":"Mystery","value":"mystery"},{"label":"One shot","value":"one-shot"},{"label":"Psychological","value":"psychological"},{"label":"Reverse Harem","value":"reverse-harem"},{"label":"Romance","value":"romance"},{"label":"School Life","value":"school-life"},{"label":"Sci-fi","value":"sci-fi"},{"label":"Seinen","value":"seinen"},{"label":"Shoujo","value":"shoujo"},{"label":"Shoujo Ai","value":"shoujo-ai"},{"label":"Shounen","value":"shounen"},{"label":"Shounen Ai","value":"shounen-ai"},{"label":"Slice of Life","value":"slice-of-life"},{"label":"Smut","value":"smut"},{"label":"Sports","value":"sports"},{"label":"Supernatural","value":"supernatural"},{"label":"Tragedy","value":"tragedy"},{"label":"Virtual Reality","value":"virtual-reality"},{"label":"Wuxia","value":"wuxia"},{"label":"Xianxia","value":"xianxia"},{"label":"Xuanhuan","value":"xuanhuan"},{"label":"Yuri","value":"yuri"}],"inputType":"Picker"}],"options":{"useNewChapterEndpoint":true,"lang":"Indonesian"}}); +export default plugin; + \ No newline at end of file diff --git a/plugins/indonesian/MoreNovel[madara].ts b/plugins/indonesian/MoreNovel[madara].ts index 87d0394..924c6c1 100644 --- a/plugins/indonesian/MoreNovel[madara].ts +++ b/plugins/indonesian/MoreNovel[madara].ts @@ -1,213 +1,252 @@ +import { fetchApi, fetchFile } from "@libs/fetch"; +import { Filter } from "@libs/filterInputs"; +import { Plugin } from '@typings/plugin' import { load as parseHTML } from "cheerio"; -import { fetchFile, fetchApi } from "@libs/fetch"; -import { Novel, Plugin, Chapter } from "@typings/plugin"; -import { FilterInputs } from "@libs/filterInputs"; import { defaultCover } from "@libs/defaultCover"; -import { NovelStatus } from "@libs/novelStatus" +import { NovelStatus } from "@libs/novelStatus"; import { parseMadaraDate } from "@libs/parseMadaraDate"; import dayjs from "dayjs"; -export const id = "morenovel"; -export const name = "MoreNovel [madara]"; -export const icon = "multisrc/madara/icons/morenovel.png"; -export const version = "1.0.0"; -export const site = "https://morenovel.net/"; -const baseUrl = site; +interface MadaraOptionPath{ + genres?: string, + novels?: string, + novel?: string, + chapter?: string, +} -export const popularNovels: Plugin.popularNovels = async (pageNo, {filters, showLatestNovels}) => { - const novels: Novel.Item[] = []; +const MadaraDefaultPath: MadaraOptionPath = { + novels: 'novel', + novel: 'novel', + chapter: 'novel' +} - let url = site; +interface MadaraOptions { + useNewChapterEndpoint?: boolean, + path?: MadaraOptionPath, + lang?: string, + orderBy?: string +} - if (filters?.genres) { - url += "novel-genre/" + filters.genres + '/'; - } else { - url += "novel/"; +export interface MadaraMetadata { + id: string, + sourceSite: string, + sourceName: string, + options?: MadaraOptions, + filters?: Filter[], +} +class MadaraPlugin implements Plugin.PluginBase { + id: string; + name: string; + icon: string; + site: string; + version: string; + userAgent: string; + cookieString: string; + options?: MadaraOptions; + filter?: Filter[] | undefined; + + constructor(metadata: MadaraMetadata){ + this.id = metadata.id; + this.name = metadata.sourceName + "[madara]"; + const iconFileName = metadata.sourceName.replace(/\s+/g, "").toLowerCase(); + this.icon = `multisrc/madara/icons/${iconFileName}.png`; + this.site = metadata.sourceSite; + this.version = "1.0.0"; + this.userAgent = ""; + this.cookieString = ""; + this.options = metadata.options; + this.filter = metadata.filters; } + async popularNovels(pageNo: number, {filters, showLatestNovels}: Plugin.PopularNovelsOptions): Promise { + const novels: Plugin.NovelItem[] = []; - url += '/page/' + pageNo + '/' + - '?m_orderby=' + (showLatestNovels ? 'latest' : (filters?.sort || 'rating')); - - const body = await fetchApi(url).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - - loadedCheerio('.manga-title-badges').remove(); - - loadedCheerio('.page-item-detail').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - - let novelUrl = loadedCheerio(this).find('.post-title') - .find('a') - .attr('href') || ''; - const novel: Novel.Item = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - - novels.push(novel); - }); - - return novels; -}; - -export const parseNovelAndChapters: Plugin.parseNovelAndChapters = async ( - novelUrl -) => { - const novel: Novel.instance = { - url: novelUrl, - }; - - const body = await fetchApi(novelUrl).then(res => res.text()); - - let loadedCheerio = parseHTML(body); - - loadedCheerio('.manga-title-badges').remove(); - - novel.name = loadedCheerio('.post-title h1').text().trim(); - - novel.cover = - loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || - loadedCheerio('.summary_image > a > img').attr('data-src') || - loadedCheerio('.summary_image > a > img').attr('src') || - defaultCover; - - loadedCheerio('.post-content_item, .post-content').each(function () { - const detailName = loadedCheerio(this).find('h5').text().trim(); - const detail = loadedCheerio(this).find('.summary-content').text().trim(); - - switch (detailName) { - case 'Genre(s)': - case 'التصنيفات': - novel.genres = detail.replace(/[\t\n]/g, ','); - break; - case 'Author(s)': - case 'المؤلف': - case 'المؤلف (ين)': - novel.author = detail; - break; - case 'Status': - case 'الحالة': - novel.status = - detail.includes('OnGoing') || detail.includes('مستمرة') - ? NovelStatus.Ongoing - : NovelStatus.Completed; - break; - } - }); - - loadedCheerio('div.summary__content .code-block,script').remove(); - novel.summary = loadedCheerio('div.summary__content').text().trim(); - - - let html; - - if (true) { - const novelId = - loadedCheerio('.rating-post-id').attr('value') || - loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; - - const body = { - action: "manga_get_chapters", - manga: novelId, - } - html = await fetchApi( - baseUrl + 'wp-admin/admin-ajax.php', - { - method: 'POST', - body: JSON.stringify(body), - }) - .then(res => res.text()); - } else { - html = await fetchApi( - baseUrl + 'ajax/chapters/', - { method: 'POST' }) - .then(res => res.text()); - } - - if (html !== '0') { - loadedCheerio = parseHTML(html); - } - - const chapters: Chapter.Item[] = []; - loadedCheerio('.wp-manga-chapter').each(function () { - const chapterName = loadedCheerio(this).find('a').text().trim(); - - let releaseDate = null; - releaseDate = loadedCheerio(this) - .find('span.chapter-release-date') - .text() - .trim(); - - if (releaseDate) { - releaseDate = parseMadaraDate(releaseDate); + let url = this.site; + if (filters?.genres && this.options?.path?.genres) { + url += this.options?.path?.genres + filters.genres + '/'; } else { - /** - * Insert current date - */ - - releaseDate = dayjs().format('LL'); + url += this.options?.path?.novels ? this.options.path.novels : MadaraDefaultPath.novels; } + + url += '/page/' + pageNo + '/' + + '?m_orderby=' + (showLatestNovels ? 'latest' : (filters?.sort || 'rating')); + + const body = await fetchApi(url).then(res => res.text()); + + const loadedCheerio = parseHTML(body); + + loadedCheerio('.manga-title-badges').remove(); + + loadedCheerio('.page-item-detail').each(function () { + const novelName = loadedCheerio(this).find('.post-title').text().trim(); + let image = loadedCheerio(this).find('img'); + const novelCover = image.attr('data-src') || image.attr('src'); + + let novelUrl = loadedCheerio(this).find('.post-title') + .find('a') + .attr('href') || ''; + const novel: Plugin.NovelItem = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + + novels.push(novel); + }); + + return novels; + } + async parseNovelAndChapters(novelUrl: string): Promise { + const novel: Plugin.SourceNovel = { + url: novelUrl, + }; + + const body = await fetchApi(novelUrl).then(res => res.text()); + + let loadedCheerio = parseHTML(body); + + loadedCheerio('.manga-title-badges, #manga-title span').remove(); + novel.name = + loadedCheerio('.post-title h1').text().trim() || + loadedCheerio('#manga-title h1').text(); + + novel.cover = + loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || + loadedCheerio('.summary_image > a > img').attr('data-src') || + loadedCheerio('.summary_image > a > img').attr('src') || + defaultCover; + + loadedCheerio('.post-content_item, .post-content').each(function () { + const detailName = loadedCheerio(this).find('h5').text().trim(); + const detail = loadedCheerio(this).find('.summary-content').text().trim(); + + switch (detailName) { + case 'Genre(s)': + case 'التصنيفات': + novel.genres = detail.replace(/[\\t\\n]/g, ','); + break; + case 'Author(s)': + case 'المؤلف': + case 'المؤلف (ين)': + novel.author = detail; + break; + case 'Status': + case 'الحالة': + novel.status = + detail.includes('OnGoing') || detail.includes('مستمرة') + ? NovelStatus.Ongoing + : NovelStatus.Completed; + break; + } + }); + + loadedCheerio('div.summary__content .code-block,script').remove(); + novel.summary = + loadedCheerio('div.summary__content').text().trim() || + loadedCheerio('#tab-manga-about').text().trim() || + loadedCheerio('.post-content_item h5:contains("Summary")').next().text().trim(); + + let html; + + if (this.options?.useNewChapterEndpoint !== true) { + const novelId = + loadedCheerio('.rating-post-id').attr('value') || + loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; + + const formData = new FormData() + formData.append("action", "manga_get_chapters"); + formData.append("manga", novelId); - let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + html = await fetchApi( + this.site + 'wp-admin/admin-ajax.php', + { + method: 'POST', + body: formData, + }) + .then(res => res.text()); + } else { + html = await fetchApi( + novelUrl + 'ajax/chapters/', + { method: 'POST' }) + .then(res => res.text()); + } + + if (html !== '0') { + loadedCheerio = parseHTML(html); + } + + const chapters: Plugin.ChapterItem[] = []; + loadedCheerio('.wp-manga-chapter').each(function () { + const chapterName = loadedCheerio(this).find('a').text().trim(); + + let releaseDate = null; + releaseDate = loadedCheerio(this) + .find('span.chapter-release-date') + .text() + .trim(); + + if (releaseDate) { + releaseDate = parseMadaraDate(releaseDate); + } else { + /** + * Insert current date + */ + + releaseDate = dayjs().format('LL'); + } + + let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + + chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); + }); + + novel.chapters = chapters.reverse(); + return novel; + } + async parseChapter(chapterUrl: string): Promise { + const body = await fetchApi(chapterUrl).then(res => res.text()); - chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); - }); + const loadedCheerio = parseHTML(body); + const chapterText = + loadedCheerio('.text-left').html() || + loadedCheerio('.text-right').html() || + loadedCheerio('.entry-content').html() || ""; - novel.chapters = chapters.reverse(); - return novel; -}; - -export const parseChapter: Plugin.parseChapter = async (chapterUrl) => { - const url = baseUrl + "/" + "novel" + "/" + chapterUrl; - - const body = await fetchApi(chapterUrl).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - const chapterText = - loadedCheerio('.text-left').html() || - loadedCheerio('.text-right').html() || - loadedCheerio('.entry-content').html(); - - return chapterText; -}; - -export const searchNovels: Plugin.searchNovels = async (searchTerm) => { - const novels: Novel.Item[] = []; - const url = baseUrl + "?s=" + searchTerm + "&post_type=wp-manga"; - - const body = await fetchApi(url).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - - - loadedCheerio('.c-tabs-item__content').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - - let novelUrl = loadedCheerio(this) - .find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - - novels.push(novel); - }); - return novels; -}; - -export const fetchImage: Plugin.fetchImage = async (url) => { - return await fetchFile(url); -}; - -export const filters = [{"key":"sort","label":"Order by","values":[{"label":"Rating","value":"rating"},{"label":"A-Z","value":"alphabet"},{"label":"Latest","value":"latest"},{"label":"Most Views","value":"views"},{"label":"New","value":"new-manga"},{"label":"Trending","value":"trending"}],"inputType":FilterInputs.Picker},{"key":"genres","label":"GENRES","values":[{"label":"Action","value":"action"},{"label":"Adventure","value":"adventure"},{"label":"Comedy","value":"comedy"},{"label":"Drama","value":"drama"},{"label":"Ecchi","value":"ecchi"},{"label":"Fantasy","value":"fantasy"},{"label":"Gender Bender","value":"gender-bender"},{"label":"Harem","value":"harem"},{"label":"Historical","value":"historical"},{"label":"Horror","value":"horror"},{"label":"Josei","value":"josei"},{"label":"Martial Arts","value":"martial-arts"},{"label":"Mature","value":"mature"},{"label":"Mecha","value":"mecha"},{"label":"Mystery","value":"mystery"},{"label":"Psychological","value":"psychological"},{"label":"Romance","value":"romance"},{"label":"School Life","value":"school-life"},{"label":"Sci-fi","value":"sci-fi"},{"label":"Seinen","value":"seinen"},{"label":"Shoujo","value":"shoujo"},{"label":"Shoujo Ai","value":"shoujo-ai"},{"label":"Shounen","value":"shounen"},{"label":"Shounen Ai","value":"shounen-ai"},{"label":"Slice of Life","value":"slice-of-life"},{"label":"Sports","value":"sports"},{"label":"Supernatural","value":"supernatural"},{"label":"Tragedy","value":"tragedy"},{"label":"Wuxia","value":"wuxia"},{"label":"Xianxia","value":"xianxia"},{"label":"Xuanhuan","value":"xuanhuan"},{"label":"Yaoi","value":"yaoi"},{"label":"Yuri","value":"yuri"}],"inputType":FilterInputs.Picker}]; \ No newline at end of file + return chapterText; + } + async searchNovels(searchTerm: string, pageNo?: number | undefined): Promise { + const novels: Plugin.NovelItem[] = []; + const url = this.site + "?s=" + searchTerm + "&post_type=wp-manga"; + + const body = await fetchApi(url).then(res => res.text()); + + const loadedCheerio = parseHTML(body); + + + loadedCheerio('.c-tabs-item__content').each(function () { + const novelName = loadedCheerio(this).find('.post-title').text().trim(); + + let image = loadedCheerio(this).find('img'); + const novelCover = image.attr('data-src') || image.attr('src'); + + let novelUrl = loadedCheerio(this) + .find('.post-title') + .find('a') + .attr('href') || ''; + const novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + + novels.push(novel); + }); + return novels; + } + async fetchImage(url: string): Promise { + return await fetchFile(url, {}); + } +} +const plugin = new MadaraPlugin({"id":"morenovel","sourceSite":"https://morenovel.net/","sourceName":"MoreNovel","filters":[{"key":"sort","label":"Order by","values":[{"label":"Rating","value":"rating"},{"label":"A-Z","value":"alphabet"},{"label":"Latest","value":"latest"},{"label":"Most Views","value":"views"},{"label":"New","value":"new-manga"},{"label":"Trending","value":"trending"}],"inputType":"Picker"},{"key":"genres","label":"GENRES","values":[{"label":"Action","value":"action"},{"label":"Adventure","value":"adventure"},{"label":"Comedy","value":"comedy"},{"label":"Drama","value":"drama"},{"label":"Ecchi","value":"ecchi"},{"label":"Fantasy","value":"fantasy"},{"label":"Gender Bender","value":"gender-bender"},{"label":"Harem","value":"harem"},{"label":"Historical","value":"historical"},{"label":"Horror","value":"horror"},{"label":"Josei","value":"josei"},{"label":"Martial Arts","value":"martial-arts"},{"label":"Mature","value":"mature"},{"label":"Mecha","value":"mecha"},{"label":"Mystery","value":"mystery"},{"label":"Psychological","value":"psychological"},{"label":"Romance","value":"romance"},{"label":"School Life","value":"school-life"},{"label":"Sci-fi","value":"sci-fi"},{"label":"Seinen","value":"seinen"},{"label":"Shoujo","value":"shoujo"},{"label":"Shoujo Ai","value":"shoujo-ai"},{"label":"Shounen","value":"shounen"},{"label":"Shounen Ai","value":"shounen-ai"},{"label":"Slice of Life","value":"slice-of-life"},{"label":"Sports","value":"sports"},{"label":"Supernatural","value":"supernatural"},{"label":"Tragedy","value":"tragedy"},{"label":"Wuxia","value":"wuxia"},{"label":"Xianxia","value":"xianxia"},{"label":"Xuanhuan","value":"xuanhuan"},{"label":"Yaoi","value":"yaoi"},{"label":"Yuri","value":"yuri"}],"inputType":"Picker"}],"options":{"useNewChapterEndpoint":true,"lang":"Indonesian"}}); +export default plugin; + \ No newline at end of file diff --git a/plugins/indonesian/WBNovel[madara].ts b/plugins/indonesian/WBNovel[madara].ts index 6151eb0..f7493fb 100644 --- a/plugins/indonesian/WBNovel[madara].ts +++ b/plugins/indonesian/WBNovel[madara].ts @@ -1,213 +1,252 @@ +import { fetchApi, fetchFile } from "@libs/fetch"; +import { Filter } from "@libs/filterInputs"; +import { Plugin } from '@typings/plugin' import { load as parseHTML } from "cheerio"; -import { fetchFile, fetchApi } from "@libs/fetch"; -import { Novel, Plugin, Chapter } from "@typings/plugin"; -import { FilterInputs } from "@libs/filterInputs"; import { defaultCover } from "@libs/defaultCover"; -import { NovelStatus } from "@libs/novelStatus" +import { NovelStatus } from "@libs/novelStatus"; import { parseMadaraDate } from "@libs/parseMadaraDate"; import dayjs from "dayjs"; -export const id = "wbnovel"; -export const name = "WBNovel [madara]"; -export const icon = "multisrc/madara/icons/wbnovel.png"; -export const version = "1.0.0"; -export const site = "https://wbnovel.com/"; -const baseUrl = site; +interface MadaraOptionPath{ + genres?: string, + novels?: string, + novel?: string, + chapter?: string, +} -export const popularNovels: Plugin.popularNovels = async (pageNo, {filters, showLatestNovels}) => { - const novels: Novel.Item[] = []; +const MadaraDefaultPath: MadaraOptionPath = { + novels: 'novel', + novel: 'novel', + chapter: 'novel' +} - let url = site; +interface MadaraOptions { + useNewChapterEndpoint?: boolean, + path?: MadaraOptionPath, + lang?: string, + orderBy?: string +} - if (filters?.genres) { - url += "novel-genre/" + filters.genres + '/'; - } else { - url += "novel/"; +export interface MadaraMetadata { + id: string, + sourceSite: string, + sourceName: string, + options?: MadaraOptions, + filters?: Filter[], +} +class MadaraPlugin implements Plugin.PluginBase { + id: string; + name: string; + icon: string; + site: string; + version: string; + userAgent: string; + cookieString: string; + options?: MadaraOptions; + filter?: Filter[] | undefined; + + constructor(metadata: MadaraMetadata){ + this.id = metadata.id; + this.name = metadata.sourceName + "[madara]"; + const iconFileName = metadata.sourceName.replace(/\s+/g, "").toLowerCase(); + this.icon = `multisrc/madara/icons/${iconFileName}.png`; + this.site = metadata.sourceSite; + this.version = "1.0.0"; + this.userAgent = ""; + this.cookieString = ""; + this.options = metadata.options; + this.filter = metadata.filters; } + async popularNovels(pageNo: number, {filters, showLatestNovels}: Plugin.PopularNovelsOptions): Promise { + const novels: Plugin.NovelItem[] = []; - url += '/page/' + pageNo + '/' + - '?m_orderby=' + (showLatestNovels ? 'latest' : (filters?.sort || 'rating')); - - const body = await fetchApi(url).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - - loadedCheerio('.manga-title-badges').remove(); - - loadedCheerio('.page-item-detail').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - - let novelUrl = loadedCheerio(this).find('.post-title') - .find('a') - .attr('href') || ''; - const novel: Novel.Item = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - - novels.push(novel); - }); - - return novels; -}; - -export const parseNovelAndChapters: Plugin.parseNovelAndChapters = async ( - novelUrl -) => { - const novel: Novel.instance = { - url: novelUrl, - }; - - const body = await fetchApi(novelUrl).then(res => res.text()); - - let loadedCheerio = parseHTML(body); - - loadedCheerio('.manga-title-badges').remove(); - - novel.name = loadedCheerio('.post-title h1').text().trim(); - - novel.cover = - loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || - loadedCheerio('.summary_image > a > img').attr('data-src') || - loadedCheerio('.summary_image > a > img').attr('src') || - defaultCover; - - loadedCheerio('.post-content_item, .post-content').each(function () { - const detailName = loadedCheerio(this).find('h5').text().trim(); - const detail = loadedCheerio(this).find('.summary-content').text().trim(); - - switch (detailName) { - case 'Genre(s)': - case 'التصنيفات': - novel.genres = detail.replace(/[\t\n]/g, ','); - break; - case 'Author(s)': - case 'المؤلف': - case 'المؤلف (ين)': - novel.author = detail; - break; - case 'Status': - case 'الحالة': - novel.status = - detail.includes('OnGoing') || detail.includes('مستمرة') - ? NovelStatus.Ongoing - : NovelStatus.Completed; - break; - } - }); - - loadedCheerio('div.summary__content .code-block,script').remove(); - novel.summary = loadedCheerio('div.summary__content').text().trim(); - - - let html; - - if (false) { - const novelId = - loadedCheerio('.rating-post-id').attr('value') || - loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; - - const body = { - action: "manga_get_chapters", - manga: novelId, - } - html = await fetchApi( - baseUrl + 'wp-admin/admin-ajax.php', - { - method: 'POST', - body: JSON.stringify(body), - }) - .then(res => res.text()); - } else { - html = await fetchApi( - baseUrl + 'ajax/chapters/', - { method: 'POST' }) - .then(res => res.text()); - } - - if (html !== '0') { - loadedCheerio = parseHTML(html); - } - - const chapters: Chapter.Item[] = []; - loadedCheerio('.wp-manga-chapter').each(function () { - const chapterName = loadedCheerio(this).find('a').text().trim(); - - let releaseDate = null; - releaseDate = loadedCheerio(this) - .find('span.chapter-release-date') - .text() - .trim(); - - if (releaseDate) { - releaseDate = parseMadaraDate(releaseDate); + let url = this.site; + if (filters?.genres && this.options?.path?.genres) { + url += this.options?.path?.genres + filters.genres + '/'; } else { - /** - * Insert current date - */ - - releaseDate = dayjs().format('LL'); + url += this.options?.path?.novels ? this.options.path.novels : MadaraDefaultPath.novels; } + + url += '/page/' + pageNo + '/' + + '?m_orderby=' + (showLatestNovels ? 'latest' : (filters?.sort || 'rating')); + + const body = await fetchApi(url).then(res => res.text()); + + const loadedCheerio = parseHTML(body); + + loadedCheerio('.manga-title-badges').remove(); + + loadedCheerio('.page-item-detail').each(function () { + const novelName = loadedCheerio(this).find('.post-title').text().trim(); + let image = loadedCheerio(this).find('img'); + const novelCover = image.attr('data-src') || image.attr('src'); + + let novelUrl = loadedCheerio(this).find('.post-title') + .find('a') + .attr('href') || ''; + const novel: Plugin.NovelItem = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + + novels.push(novel); + }); + + return novels; + } + async parseNovelAndChapters(novelUrl: string): Promise { + const novel: Plugin.SourceNovel = { + url: novelUrl, + }; + + const body = await fetchApi(novelUrl).then(res => res.text()); + + let loadedCheerio = parseHTML(body); + + loadedCheerio('.manga-title-badges, #manga-title span').remove(); + novel.name = + loadedCheerio('.post-title h1').text().trim() || + loadedCheerio('#manga-title h1').text(); + + novel.cover = + loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || + loadedCheerio('.summary_image > a > img').attr('data-src') || + loadedCheerio('.summary_image > a > img').attr('src') || + defaultCover; + + loadedCheerio('.post-content_item, .post-content').each(function () { + const detailName = loadedCheerio(this).find('h5').text().trim(); + const detail = loadedCheerio(this).find('.summary-content').text().trim(); + + switch (detailName) { + case 'Genre(s)': + case 'التصنيفات': + novel.genres = detail.replace(/[\\t\\n]/g, ','); + break; + case 'Author(s)': + case 'المؤلف': + case 'المؤلف (ين)': + novel.author = detail; + break; + case 'Status': + case 'الحالة': + novel.status = + detail.includes('OnGoing') || detail.includes('مستمرة') + ? NovelStatus.Ongoing + : NovelStatus.Completed; + break; + } + }); + + loadedCheerio('div.summary__content .code-block,script').remove(); + novel.summary = + loadedCheerio('div.summary__content').text().trim() || + loadedCheerio('#tab-manga-about').text().trim() || + loadedCheerio('.post-content_item h5:contains("Summary")').next().text().trim(); + + let html; + + if (this.options?.useNewChapterEndpoint !== true) { + const novelId = + loadedCheerio('.rating-post-id').attr('value') || + loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; + + const formData = new FormData() + formData.append("action", "manga_get_chapters"); + formData.append("manga", novelId); - let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + html = await fetchApi( + this.site + 'wp-admin/admin-ajax.php', + { + method: 'POST', + body: formData, + }) + .then(res => res.text()); + } else { + html = await fetchApi( + novelUrl + 'ajax/chapters/', + { method: 'POST' }) + .then(res => res.text()); + } + + if (html !== '0') { + loadedCheerio = parseHTML(html); + } + + const chapters: Plugin.ChapterItem[] = []; + loadedCheerio('.wp-manga-chapter').each(function () { + const chapterName = loadedCheerio(this).find('a').text().trim(); + + let releaseDate = null; + releaseDate = loadedCheerio(this) + .find('span.chapter-release-date') + .text() + .trim(); + + if (releaseDate) { + releaseDate = parseMadaraDate(releaseDate); + } else { + /** + * Insert current date + */ + + releaseDate = dayjs().format('LL'); + } + + let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + + chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); + }); + + novel.chapters = chapters.reverse(); + return novel; + } + async parseChapter(chapterUrl: string): Promise { + const body = await fetchApi(chapterUrl).then(res => res.text()); - chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); - }); + const loadedCheerio = parseHTML(body); + const chapterText = + loadedCheerio('.text-left').html() || + loadedCheerio('.text-right').html() || + loadedCheerio('.entry-content').html() || ""; - novel.chapters = chapters.reverse(); - return novel; -}; - -export const parseChapter: Plugin.parseChapter = async (chapterUrl) => { - const url = baseUrl + "/" + "novel" + "/" + chapterUrl; - - const body = await fetchApi(chapterUrl).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - const chapterText = - loadedCheerio('.text-left').html() || - loadedCheerio('.text-right').html() || - loadedCheerio('.entry-content').html(); - - return chapterText; -}; - -export const searchNovels: Plugin.searchNovels = async (searchTerm) => { - const novels: Novel.Item[] = []; - const url = baseUrl + "?s=" + searchTerm + "&post_type=wp-manga"; - - const body = await fetchApi(url).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - - - loadedCheerio('.c-tabs-item__content').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - - let novelUrl = loadedCheerio(this) - .find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - - novels.push(novel); - }); - return novels; -}; - -export const fetchImage: Plugin.fetchImage = async (url) => { - return await fetchFile(url); -}; - -export const filters = [{"key":"sort","label":"Order by","values":[{"label":"Rating","value":"rating"},{"label":"A-Z","value":"alphabet"},{"label":"Latest","value":"latest"},{"label":"Most Views","value":"views"},{"label":"New","value":"new-manga"},{"label":"Trending","value":"trending"}],"inputType":FilterInputs.Picker},{"key":"genres","label":"GENRES","values":[{"label":"Action","value":"action"},{"label":"Adventure","value":"adventure"},{"label":"Alchemy","value":"alchemy"},{"label":"Comedy","value":"comedy"},{"label":"Crafting","value":"crafting"},{"label":"Cultivation","value":"cultivation"},{"label":"Drama","value":"drama"},{"label":"Dungeon Crawling","value":"dungeon-crawling"},{"label":"Eci","value":"eci"},{"label":"Fantasy","value":"fantasy"},{"label":"Game","value":"game"},{"label":"Harem","value":"harem"},{"label":"Horror","value":"horror"},{"label":"Josei","value":"josei"},{"label":"Kingdom Building","value":"kingdom-building"},{"label":"Martial Arts","value":"martial-arts"},{"label":"Mature","value":"mature"},{"label":"Mecha","value":"mecha"},{"label":"Modern Setting","value":"modern-setting"},{"label":"Mystery","value":"mystery"},{"label":"Pets","value":"pets"},{"label":"Psychological","value":"psychological"},{"label":"Reincarnator","value":"reincarnator"},{"label":"Romance","value":"romance"},{"label":"School Life","value":"school-life"},{"label":"Sci-fi","value":"sci-fi"},{"label":"Seinen","value":"seinen"},{"label":"Shounen","value":"shounen"},{"label":"Slice of Life","value":"slice-of-life"},{"label":"Sports","value":"sports"},{"label":"Supernatural","value":"supernatural"},{"label":"Tragedy","value":"tragedy"},{"label":"Transmigration","value":"transmigration"},{"label":"Virtual Reality","value":"virtual-reality"},{"label":"Wuxia","value":"wuxia"},{"label":"Xianxia","value":"xianxia"},{"label":"Xuanhuan","value":"xuanhuan"}],"inputType":FilterInputs.Picker}]; \ No newline at end of file + return chapterText; + } + async searchNovels(searchTerm: string, pageNo?: number | undefined): Promise { + const novels: Plugin.NovelItem[] = []; + const url = this.site + "?s=" + searchTerm + "&post_type=wp-manga"; + + const body = await fetchApi(url).then(res => res.text()); + + const loadedCheerio = parseHTML(body); + + + loadedCheerio('.c-tabs-item__content').each(function () { + const novelName = loadedCheerio(this).find('.post-title').text().trim(); + + let image = loadedCheerio(this).find('img'); + const novelCover = image.attr('data-src') || image.attr('src'); + + let novelUrl = loadedCheerio(this) + .find('.post-title') + .find('a') + .attr('href') || ''; + const novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + + novels.push(novel); + }); + return novels; + } + async fetchImage(url: string): Promise { + return await fetchFile(url, {}); + } +} +const plugin = new MadaraPlugin({"id":"wbnovel","sourceSite":"https://wbnovel.com/","sourceName":"WBNovel","filters":[{"key":"sort","label":"Order by","values":[{"label":"Rating","value":"rating"},{"label":"A-Z","value":"alphabet"},{"label":"Latest","value":"latest"},{"label":"Most Views","value":"views"},{"label":"New","value":"new-manga"},{"label":"Trending","value":"trending"}],"inputType":"Picker"},{"key":"genres","label":"GENRES","values":[{"label":"Action","value":"action"},{"label":"Adventure","value":"adventure"},{"label":"Alchemy","value":"alchemy"},{"label":"Comedy","value":"comedy"},{"label":"Crafting","value":"crafting"},{"label":"Cultivation","value":"cultivation"},{"label":"Drama","value":"drama"},{"label":"Dungeon Crawling","value":"dungeon-crawling"},{"label":"Eci","value":"eci"},{"label":"Fantasy","value":"fantasy"},{"label":"Game","value":"game"},{"label":"Harem","value":"harem"},{"label":"Horror","value":"horror"},{"label":"Josei","value":"josei"},{"label":"Kingdom Building","value":"kingdom-building"},{"label":"Martial Arts","value":"martial-arts"},{"label":"Mature","value":"mature"},{"label":"Mecha","value":"mecha"},{"label":"Modern Setting","value":"modern-setting"},{"label":"Mystery","value":"mystery"},{"label":"Pets","value":"pets"},{"label":"Psychological","value":"psychological"},{"label":"Reincarnator","value":"reincarnator"},{"label":"Romance","value":"romance"},{"label":"School Life","value":"school-life"},{"label":"Sci-fi","value":"sci-fi"},{"label":"Seinen","value":"seinen"},{"label":"Shounen","value":"shounen"},{"label":"Slice of Life","value":"slice-of-life"},{"label":"Sports","value":"sports"},{"label":"Supernatural","value":"supernatural"},{"label":"Tragedy","value":"tragedy"},{"label":"Transmigration","value":"transmigration"},{"label":"Virtual Reality","value":"virtual-reality"},{"label":"Wuxia","value":"wuxia"},{"label":"Xianxia","value":"xianxia"},{"label":"Xuanhuan","value":"xuanhuan"}],"inputType":"Picker"}],"options":{"lang":"Indonesian"}}); +export default plugin; + \ No newline at end of file diff --git a/plugins/indonesian/indowebnovel.ts b/plugins/indonesian/indowebnovel.broken.ts similarity index 100% rename from plugins/indonesian/indowebnovel.ts rename to plugins/indonesian/indowebnovel.broken.ts diff --git a/plugins/indonesian/novelringan.ts b/plugins/indonesian/novelringan.broken.ts similarity index 100% rename from plugins/indonesian/novelringan.ts rename to plugins/indonesian/novelringan.broken.ts diff --git a/plugins/indonesian/sakuranovel.ts b/plugins/indonesian/sakuranovel.broken.ts similarity index 100% rename from plugins/indonesian/sakuranovel.ts rename to plugins/indonesian/sakuranovel.broken.ts diff --git a/plugins/japanese/.japanese b/plugins/japanese/.japanese deleted file mode 100644 index e69de29..0000000 diff --git a/plugins/japanese/Syosetu.ts b/plugins/japanese/Syosetu.broken.ts similarity index 100% rename from plugins/japanese/Syosetu.ts rename to plugins/japanese/Syosetu.broken.ts diff --git a/plugins/korean/Agitoon.ts b/plugins/korean/Agitoon.broken.ts similarity index 100% rename from plugins/korean/Agitoon.ts rename to plugins/korean/Agitoon.broken.ts diff --git a/plugins/portuguese/.portuguese b/plugins/portuguese/.portuguese deleted file mode 100644 index e69de29..0000000 diff --git a/plugins/portuguese/lightnovelbrasil.ts b/plugins/portuguese/lightnovelbrasil.ts index e978bc9..1c675a0 100644 --- a/plugins/portuguese/lightnovelbrasil.ts +++ b/plugins/portuguese/lightnovelbrasil.ts @@ -1,77 +1,76 @@ import { load as parseHTML } from "cheerio"; import { fetchApi, fetchFile } from "@libs/fetch"; -import { FilterInputs } from "@libs/filterInputs"; -import { Chapter, Novel, Plugin } from "@typings/plugin"; +import { Filter, FilterInputs } from "@libs/filterInputs"; +import { Plugin } from "@typings/plugin"; -export const id = "lightnovelbrasil"; -export const name = "Light Novel Brasil"; -export const version = "1.0.0"; -export const icon = "multisrc/wpmangastream/icons/lightnovelbrasil.png"; -export const site = "https://lightnovelbrasil.com/"; +class LightNovelBrasil implements Plugin.PluginBase { + id = "lightnovelbrasil"; + name = "Light Novel Brasil"; + icon = "multisrc/wpmangastream/icons/lightnovelbrasil.png"; + site = "https://lightnovelbrasil.com/"; + version = "1.0.0"; + userAgent = ""; + cookieString = ""; + async popularNovels(pageNo: number, {filters}: Plugin.PopularNovelsOptions): Promise { + let link = `${this.site}series/?page=${pageNo}`; + if (filters) { + if (Array.isArray(filters.genres) && filters.genres.length) { + link += filters.genres.map((i) => `&genre[]=${i}`).join(""); + } -const pluginId = id; -const baseUrl = site; - -export const popularNovels: Plugin.popularNovels = async function ( - page, - { filters } -) { - let link = `${baseUrl}series/?page=${page}`; - - if (filters) { - if (Array.isArray(filters.genres) && filters.genres.length) { - link += filters.genres.map((i) => `&genre[]=${i}`).join(""); + if (Array.isArray(filters.type) && filters.type.length) + link += filters.type.map((i) => `&lang[]=${i}`).join(""); } + link += "&status=" + (filters?.status ? filters.status : ""); - if (Array.isArray(filters.type) && filters.type.length) { - link += filters.type.map((i) => `&lang[]=${i}`).join(""); + link += "&order=" + (filters?.order ? filters.order : "popular"); + + const headers = new Headers(); + if(this.cookieString){ + headers.append("cookie", this.cookieString); } - } + const body = await fetchApi(link, {headers}).then((result) => + result.text() + ); - link += "&status=" + (filters?.status ? filters?.status : ""); + const loadedCheerio = parseHTML(body); - link += "&order=" + (filters?.order ? filters?.order : "popular"); + const novels: Plugin.NovelItem[] = []; - const body = await fetchApi(link, {}, pluginId).then((result) => - result.text() - ); + loadedCheerio("article.bs").each(function () { + const novelName = loadedCheerio(this).find(".ntitle").text().trim(); + let image = loadedCheerio(this).find("img"); + const novelCover = image.attr("data-src") || image.attr("src"); - const loadedCheerio = parseHTML(body); + const novelUrl = loadedCheerio(this).find("a").attr("href"); - const novels: Novel.Item[] = []; + if (!novelUrl) return; - loadedCheerio("article.bs").each(function () { - const novelName = loadedCheerio(this).find(".ntitle").text().trim(); - let image = loadedCheerio(this).find("img"); - const novelCover = image.attr("data-src") || image.attr("src"); + const novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; - const novelUrl = loadedCheerio(this).find("a").attr("href"); + novels.push(novel); + }); - if (!novelUrl) return; + return novels; + }; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - - novels.push(novel); - }); - - return novels; -}; - -export const parseNovelAndChapters: Plugin.parseNovelAndChapters = - async function (novelUrl) { + async parseNovelAndChapters(novelUrl: string): Promise { const url = novelUrl; - - const result = await fetchApi(url, {}, pluginId); + const headers = new Headers(); + if(this.cookieString){ + headers.append("cookie", this.cookieString); + } + const result = await fetchApi(url, {headers}); const body = await result.text(); let loadedCheerio = parseHTML(body); - const novel: Novel.instance = { + const novel: Plugin.SourceNovel = { url, chapters: [], }; @@ -84,22 +83,14 @@ export const parseNovelAndChapters: Plugin.parseNovelAndChapters = loadedCheerio("div.spe > span").each(function () { const detailName = loadedCheerio(this).find("b").text().trim(); - const detail = loadedCheerio(this) - .find("b") - .remove() - .end() - .text() - .trim(); + const detail = loadedCheerio(this).find('b').remove().end().text().trim(); switch (detailName) { - case "المؤلف:": - case "Yazar:": case "Autor:": case "Author:": novel.author = detail; break; case "Status:": - case "Seviye:": novel.status = detail; break; } @@ -117,7 +108,7 @@ export const parseNovelAndChapters: Plugin.parseNovelAndChapters = .end() .text(); - let chapter: Chapter.Item[] = []; + let chapter: Plugin.ChapterItem[] = []; loadedCheerio(".eplister") .find("li") @@ -146,276 +137,282 @@ export const parseNovelAndChapters: Plugin.parseNovelAndChapters = novel.chapters = chapter.reverse(); return novel; - }; + } + async parseChapter(chapterUrl: string): Promise { + const headers = new Headers(); + if(this.cookieString){ + headers.append("cookie", this.cookieString); + } + const result = await fetchApi(chapterUrl, {headers}); + const body = await result.text(); -export const parseChapter: Plugin.parseChapter = async function (chapterUrl) { - const result = await fetchApi(chapterUrl, {}, pluginId); - const body = await result.text(); + const loadedCheerio = parseHTML(body); - const loadedCheerio = parseHTML(body); + let chapterText = loadedCheerio(".epcontent").html() || ""; - let chapterText = loadedCheerio("div.epcontent").html(); + return chapterText; + } - return chapterText; -}; + async searchNovels(searchTerm: string, pageNo?: number | undefined): Promise { + const url = `${this.site}?s=${searchTerm}`; + const headers = new Headers(); + if(this.cookieString){ + headers.append("cookie", this.cookieString); + } + const result = await fetchApi(url, {headers}); + const body = await result.text(); -export const searchNovels: Plugin.searchNovels = async function (searchTerm) { - const url = `${baseUrl}?s=${searchTerm}`; + const loadedCheerio = parseHTML(body); - const result = await fetchApi(url, {}, pluginId); - const body = await result.text(); + const novels: Plugin.NovelItem[] = []; - const loadedCheerio = parseHTML(body); + loadedCheerio("article.bs").each(function () { + const novelName = loadedCheerio(this).find(".ntitle").text().trim(); + const novelCover = loadedCheerio(this).find("img").attr("src"); + const novelUrl = loadedCheerio(this).find("a").attr("href"); + if (!novelUrl) return; - const novels: Novel.Item[] = []; - - loadedCheerio("article.bs").each(function () { - const novelName = loadedCheerio(this).find(".ntitle").text().trim(); - const novelCover = loadedCheerio(this).find("img").attr("src"); - const novelUrl = loadedCheerio(this).find("a").attr("href"); - - if (!novelUrl) return; - novels.push({ - name: novelName, - url: novelUrl, - cover: novelCover, + novels.push({ + name: novelName, + url: novelUrl, + cover: novelCover, + }); }); - }); - return novels; -}; + return novels; + } + async fetchImage(url: string): Promise { + return await fetchFile(url); + } -export const fetchImage: Plugin.fetchImage = async function (url) { - const headers = { - Referer: baseUrl, - }; - return await fetchFile(url, { headers: headers }); -}; -export const filters = [ - { - key: "order", - label: "Sort By", - values: [ - { label: "Default", value: "" }, + filters = [ + { + key: "order", + label: "Sort By", + values: [ + { label: "Default", value: "" }, - { label: "A-Z", value: "title" }, + { label: "A-Z", value: "title" }, - { label: "Z-A", value: "titlereverse" }, + { label: "Z-A", value: "titlereverse" }, - { label: "Latest Update", value: "update" }, + { label: "Latest Update", value: "update" }, - { label: "Latest Added", value: "latest" }, + { label: "Latest Added", value: "latest" }, - { label: "Popular", value: "popular" }, - ], - inputType: FilterInputs.Picker, - }, - { - key: "status", - label: "Status", - values: [ - { label: "All", value: "" }, + { label: "Popular", value: "popular" }, + ], + inputType: FilterInputs.Picker, + }, + { + key: "status", + label: "Status", + values: [ + { label: "All", value: "" }, - { label: "Ongoing", value: "ongoing" }, + { label: "Ongoing", value: "ongoing" }, - { label: "Hiatus", value: "hiatus" }, + { label: "Hiatus", value: "hiatus" }, - { label: "Completed", value: "completed" }, - ], - inputType: FilterInputs.Picker, - }, - { - key: "type", - label: "Type", - values: [ - { label: "Chinese novel", value: "chinese-novel" }, + { label: "Completed", value: "completed" }, + ], + inputType: FilterInputs.Picker, + }, + { + key: "type", + label: "Type", + values: [ + { label: "Chinese novel", value: "chinese-novel" }, - { label: "habyeol", value: "habyeol" }, + { label: "habyeol", value: "habyeol" }, - { label: "korean novel", value: "korean-novel" }, + { label: "korean novel", value: "korean-novel" }, - { label: "Web Novel", value: "web-novel" }, + { label: "Web Novel", value: "web-novel" }, - { label: "삼심", value: "%ec%82%bc%ec%8b%ac" }, + { label: "삼심", value: "%ec%82%bc%ec%8b%ac" }, - { label: "호곡", value: "%ed%98%b8%ea%b3%a1" }, - ], - inputType: FilterInputs.Checkbox, - }, - { - key: "genres", - label: "Genres", - values: [ - { label: "A.I", value: "a.i" }, + { label: "호곡", value: "%ed%98%b8%ea%b3%a1" }, + ], + inputType: FilterInputs.Checkbox, + }, + { + key: "genres", + label: "Genres", + values: [ + { label: "A.I", value: "a.i" }, - { label: "Academy", value: "academy" }, + { label: "Academy", value: "academy" }, - { label: "Action", value: "action" }, + { label: "Action", value: "action" }, - { label: "Adult", value: "adult" }, + { label: "Adult", value: "adult" }, - { label: "Adventure", value: "adventure" }, + { label: "Adventure", value: "adventure" }, - { label: "Alternative History", value: "alternative-history" }, + { label: "Alternative History", value: "alternative-history" }, - { label: "Another World", value: "another-world" }, + { label: "Another World", value: "another-world" }, - { label: "Apocalypse", value: "apocalypse" }, + { label: "Apocalypse", value: "apocalypse" }, - { label: "Bromance", value: "bromance" }, + { label: "Bromance", value: "bromance" }, - { label: "Comedy", value: "comedy" }, + { label: "Comedy", value: "comedy" }, - { label: "Dark fantasy", value: "dark-fantasy" }, + { label: "Dark fantasy", value: "dark-fantasy" }, - { label: "Demons", value: "demons" }, + { label: "Demons", value: "demons" }, - { label: "Drama", value: "drama" }, + { label: "Drama", value: "drama" }, - { label: "Dystopia", value: "dystopia" }, + { label: "Dystopia", value: "dystopia" }, - { label: "Ecchi", value: "ecchi" }, + { label: "Ecchi", value: "ecchi" }, - { label: "Entertainment", value: "entertainment" }, + { label: "Entertainment", value: "entertainment" }, - { label: "Exhaustion", value: "exhaustion" }, + { label: "Exhaustion", value: "exhaustion" }, - { label: "Fanfiction", value: "fanfiction" }, + { label: "Fanfiction", value: "fanfiction" }, - { label: "fantasy", value: "fantasy" }, + { label: "fantasy", value: "fantasy" }, - { label: "finance", value: "finance" }, + { label: "finance", value: "finance" }, - { label: "Full color", value: "full-color" }, + { label: "Full color", value: "full-color" }, - { label: "Game", value: "game" }, + { label: "Game", value: "game" }, - { label: "Gender Bender", value: "gender-bender" }, + { label: "Gender Bender", value: "gender-bender" }, - { label: "Genius", value: "genius" }, + { label: "Genius", value: "genius" }, - { label: "Harem", value: "harem" }, + { label: "Harem", value: "harem" }, - { label: "Hero", value: "hero" }, + { label: "Hero", value: "hero" }, - { label: "Historical", value: "historical" }, + { label: "Historical", value: "historical" }, - { label: "Hunter", value: "hunter" }, + { label: "Hunter", value: "hunter" }, - { label: "korean novel", value: "korean-novel" }, + { label: "korean novel", value: "korean-novel" }, - { label: "Light Novel", value: "light-novel" }, + { label: "Light Novel", value: "light-novel" }, - { - label: "List Adventure Manga Genres", - value: "list-adventure-manga-genres", - }, + { + label: "List Adventure Manga Genres", + value: "list-adventure-manga-genres", + }, - { label: "Long Strip", value: "long-strip" }, + { label: "Long Strip", value: "long-strip" }, - { label: "Love comedy", value: "love-comedy" }, + { label: "Love comedy", value: "love-comedy" }, - { label: "magic", value: "magic" }, + { label: "magic", value: "magic" }, - { label: "Manhua", value: "manhua" }, + { label: "Manhua", value: "manhua" }, - { label: "Martial Arts", value: "martial-arts" }, + { label: "Martial Arts", value: "martial-arts" }, - { label: "Mature", value: "mature" }, + { label: "Mature", value: "mature" }, - { label: "Medieval", value: "medieval" }, + { label: "Medieval", value: "medieval" }, - { label: "Misunderstanding", value: "misunderstanding" }, + { label: "Misunderstanding", value: "misunderstanding" }, - { label: "Modern", value: "modern" }, + { label: "Modern", value: "modern" }, - { label: "modern fantasy", value: "modern-fantasy" }, + { label: "modern fantasy", value: "modern-fantasy" }, - { label: "music", value: "music" }, + { label: "music", value: "music" }, - { label: "Mystery", value: "mystery" }, + { label: "Mystery", value: "mystery" }, - { label: "Necromancy", value: "necromancy" }, + { label: "Necromancy", value: "necromancy" }, - { label: "No Romance", value: "no-romance" }, + { label: "No Romance", value: "no-romance" }, - { label: "NTL", value: "ntl" }, + { label: "NTL", value: "ntl" }, - { label: "o", value: "o" }, + { label: "o", value: "o" }, - { label: "Obsession", value: "obsession" }, + { label: "Obsession", value: "obsession" }, - { label: "Politics", value: "politics" }, + { label: "Politics", value: "politics" }, - { label: "Possession", value: "possession" }, + { label: "Possession", value: "possession" }, - { label: "Programming", value: "programming" }, + { label: "Programming", value: "programming" }, - { label: "Psychological", value: "psychological" }, + { label: "Psychological", value: "psychological" }, - { label: "Pure Love", value: "pure-love" }, + { label: "Pure Love", value: "pure-love" }, - { label: "Redemption", value: "redemption" }, + { label: "Redemption", value: "redemption" }, - { label: "Regression", value: "regression" }, + { label: "Regression", value: "regression" }, - { label: "Regret", value: "regret" }, + { label: "Regret", value: "regret" }, - { label: "Reincarnation", value: "reincarnation" }, + { label: "Reincarnation", value: "reincarnation" }, - { label: "Revenge", value: "revenge" }, + { label: "Revenge", value: "revenge" }, - { label: "Romance", value: "romance" }, + { label: "Romance", value: "romance" }, - { label: "Romance Fanrasy", value: "romance-fanrasy" }, + { label: "Romance Fanrasy", value: "romance-fanrasy" }, - { label: "Salvation", value: "salvation" }, + { label: "Salvation", value: "salvation" }, - { label: "School Life", value: "school-life" }, + { label: "School Life", value: "school-life" }, - { label: "Sci-fi", value: "sci-fi" }, + { label: "Sci-fi", value: "sci-fi" }, - { label: "Science fiction", value: "science-fiction" }, + { label: "Science fiction", value: "science-fiction" }, - { label: "Seinen", value: "seinen" }, + { label: "Seinen", value: "seinen" }, - { label: "Shounen", value: "shounen" }, + { label: "Shounen", value: "shounen" }, - { label: "Slice of Life", value: "slice-of-life" }, + { label: "Slice of Life", value: "slice-of-life" }, - { label: "Soft yandere", value: "soft-yandere" }, + { label: "Soft yandere", value: "soft-yandere" }, - { label: "Sports", value: "sports" }, + { label: "Sports", value: "sports" }, - { label: "Supernatural", value: "supernatural" }, + { label: "Supernatural", value: "supernatural" }, - { label: "Survival", value: "survival" }, + { label: "Survival", value: "survival" }, - { label: "system", value: "system" }, + { label: "system", value: "system" }, - { label: "Time limit", value: "time-limit" }, + { label: "Time limit", value: "time-limit" }, - { label: "Tragedy", value: "tragedy" }, + { label: "Tragedy", value: "tragedy" }, - { label: "Transmigration", value: "transmigration" }, + { label: "Transmigration", value: "transmigration" }, - { label: "TS", value: "ts" }, + { label: "TS", value: "ts" }, - { label: "Tsundere", value: "tsundere" }, + { label: "Tsundere", value: "tsundere" }, - { label: "Unique", value: "unique" }, + { label: "Unique", value: "unique" }, - { label: "Wholesome", value: "wholesome" }, + { label: "Wholesome", value: "wholesome" }, - { label: "Wuxia", value: "wuxia" }, + { label: "Wuxia", value: "wuxia" }, - { label: "Xuanhuan", value: "xuanhuan" }, + { label: "Xuanhuan", value: "xuanhuan" }, - { label: "Yandere", value: "yandere" }, + { label: "Yandere", value: "yandere" }, - { label: "Yuri", value: "yuri" }, - ], - inputType: FilterInputs.Checkbox, - }, -]; + { label: "Yuri", value: "yuri" }, + ], + inputType: FilterInputs.Checkbox, + }, + ]; +} + +export default new LightNovelBrasil(); \ No newline at end of file diff --git a/plugins/russian/.russian b/plugins/russian/.russian deleted file mode 100644 index e69de29..0000000 diff --git a/plugins/russian/Erolate[rulate].ts b/plugins/russian/Erolate[rulate].ts deleted file mode 100644 index 623633f..0000000 --- a/plugins/russian/Erolate[rulate].ts +++ /dev/null @@ -1,226 +0,0 @@ - -import { load as parseHTML } from "cheerio"; -// import dayjs from 'dayjs'; -import { fetchFile, fetchApi } from "@libs/fetch"; -import { Novel, Plugin, Chapter } from "@typings/plugin"; -// import { parseMadaraDate } from "@libs/parseMadaraDate"; -// import { isUrlAbsolute } from '@libs/isAbsoluteUrl'; -// import { showToast } from "@libs/showToast"; -import { FilterInputs } from "@libs/filterInputs"; -import { NovelStatus } from '@libs/novelStatus'; -// import { defaultCover } from "@libs/defaultCover"; - -export const id = "erolate"; -export const name = "Erolate"; -export const icon = "multisrc/rulate/icons/erolate.png"; -export const version = "1.0.0"; -export const site = "https://erolate.com"; - -export const popularNovels: Plugin.popularNovels = async function ( - page, - { filters, showLatestNovels } -) { - let url = site + '/search?t='; - url += '&cat=' + (filters?.cat || '0'); - url += '&s_lang=' + (filters?.s_lang || '0'); - url += '&t_lang=' + (filters?.t_lang || '0'); - url += '&type=' + (filters?.type || '0'); - url += '&sort=' + (showLatestNovels ? '4' : (filters?.sort || '6')); - url += '&atmosphere=' + (filters?.atmosphere || '0'); - url += '&adult=' + (filters?.adult || '0'); - - if (filters?.genres instanceof Array) { - url += filters.genres.map(i => '&genres[]=' + i).join(''); - } - - if (filters?.genres_ex instanceof Array) { - url += filters.genres_ex.map(i => '&genres_ex[]=' + i).join(''); - } - - if (filters?.tags instanceof Array) { - url += filters.tags.map(i => '&tags[]=' + i).join(''); - } - - if (filters?.tags_ex instanceof Array) { - url += filters.tags_ex.map(i => '&tags_ex[]=' + i).join(''); - } - - if (filters?.fandoms instanceof Array) { - url += filters.fandoms.map(i => '&fandoms[]=' + i).join(''); - } - - if (filters?.fandoms_ex instanceof Array) { - url += filters.fandoms_ex.map(i => '&fandoms_ex[]=' + i).join(''); - } - - if (filters?.trash instanceof Array) { - url += filters.trash.map(i => '&' + i + '=1').join(''); - } - - url += '&Book_page=' + page; - - const result = await fetchApi(url); - const body = await result.text(); - const loadedCheerio = parseHTML(body); - - const novels: Novel.Item[] = []; - - loadedCheerio( - 'ul[class="search-results"] > li:not([class="ad_type_catalog"])', - ).each(function () { - novels.push({ - name: loadedCheerio(this).find('p > a').text(), - cover: site + loadedCheerio(this).find('img').attr('src'), - url: site + loadedCheerio(this).find('p > a').attr('href') || '', - }); - }); - - return novels; -}; - - -export const parseNovelAndChapters: Plugin.parseNovelAndChapters = - async function (novelUrl) { - const novel: Novel.instance = { - url: novelUrl, - chapters: [], - }; - let result = await fetchApi(novelUrl); - if (result.url.includes('mature?path=')) { - const formData = new FormData(); - formData.append('path', novelUrl); - formData.append('ok', 'Да'); - - await fetchApi(result.url, { - method: 'POST', - body: formData, - }); - - result = await fetchApi(novelUrl); - } - const body = await result.text(); - const loadedCheerio = parseHTML(body); - - novel.name = loadedCheerio('div[class="container"] > div > div > h1, div.span8:nth-child(1) > h1:nth-child(2)') - .text() - .trim(); - novel.cover = - site + loadedCheerio('div[class="images"] > div img').attr('src'); - novel.summary = loadedCheerio('#Info > div:nth-child(3), .book-description').text(); - novel.author = loadedCheerio('.book-stats-icons_author > span:nth-child(2) > a:nth-child(1)').text() - let genres: string[] = []; - - loadedCheerio('div.span5 > p, .span5 > div:nth-child(2) > p').each(function () { - switch (loadedCheerio(this).find('strong').text()) { - case 'Автор:': - novel.author = loadedCheerio(this).find('em > a').text().trim(); - break; - case 'Выпуск:': - novel.status = - loadedCheerio(this).find('em').text().trim() === 'продолжается' - ? NovelStatus.Ongoing - : NovelStatus.Completed; - break; - case 'Тэги:': - loadedCheerio(this) - .find('em > a') - .each(function () { - genres.push(loadedCheerio(this).text()); - }); - break; - case 'Жанры:': - loadedCheerio(this) - .find('em > a') - .each(function () { - genres.push(loadedCheerio(this).text()); - }); - break; - } - }); - - if (genres.length > 0) { - novel.genres = genres.reverse().join(','); - } - - const chapters: Chapter.Item[] = []; - loadedCheerio('table > tbody > tr.chapter_row').each(function () { - const chapterName = loadedCheerio(this) - .find('td[class="t"] > a') - .text() - .trim(); - const releaseDate = loadedCheerio(this) - .find('td > span') - .attr('title') - ?.trim(); - const chapterUrl = site + loadedCheerio(this) - .find('td[class="t"] > a') - .attr('href'); - - if ( - loadedCheerio(this).find('td > span[class="disabled"]').length < 1 && - releaseDate - ) { - chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); - } - }); - - novel.chapters = chapters; - return novel; - }; - -export const parseChapter: Plugin.parseChapter = async function (chapterUrl) { - let result = await fetchApi(chapterUrl); - if (result.url.includes('mature?path=')) { - const formData = new FormData(); - formData.append('ok', 'Да'); - - await fetchApi(result.url, { - method: 'POST', - body: formData, - }); - - result = await fetchApi(chapterUrl); - } - const body = await result.text(); - const loadedCheerio = parseHTML(body); - - loadedCheerio('.content-text img').each(function () { - if (!loadedCheerio(this).attr('src')?.startsWith('http')) { - const src = loadedCheerio(this).attr('src'); - loadedCheerio(this).attr('src', site + src); - } - }); - - const chapterText = loadedCheerio('.content-text').html(); - return chapterText; -}; - -export const searchNovels: Plugin.searchNovels = async (searchTerm) => { - const novels: Novel.Item[] = []; - const result = await fetchApi( - site + '/search/autocomplete?query=' + searchTerm, - ); - let json = await result.json() as response[]; - - json.forEach((item) => { - const novelName = item.title_one + ' / ' + item.title_two; - const novelCover = site + item.img; - const novelUrl = site + item.url; - - novels.push({ name: novelName, cover: novelCover, url: novelUrl }); - }); - - return novels; -}; - -interface response { - id: number; - title_one: string; - title_two: string; - url: string; - img: string; -}; - -export const fetchImage: Plugin.fetchImage = fetchFile; - -export const filters = [{"key":"cat","label":"Из раздела каталога:","values":[{"label":"Неважно","value":"0"},{"label":"Авторские","value":"12"},{"label":"Авторские","value":"35"},{"label":"Английские","value":"34"},{"label":"Игры 18+","value":"3"},{"label":"Китайские","value":"31"},{"label":"Комиксы","value":"29"},{"label":"Корейские","value":"33"},{"label":"Манга для взрослых","value":"30"},{"label":"Машинный перевод","value":"38"},{"label":"Переводы","value":"15"},{"label":"Фанфики","value":"16"},{"label":"Эротические рассказы","value":"2"}],"inputType":FilterInputs.Picker},{"key":"s_lang","label":"Язык оригинала:","values":[{"label":"Неважно","value":"0"},{"label":"Абхазский","value":"20"},{"label":"Аварский","value":"21"},{"label":"Азербайджанский","value":"22"},{"label":"Аймара","value":"23"},{"label":"Акан","value":"24"},{"label":"Албанский","value":"25"},{"label":"Амхарский","value":"26"},{"label":"Английский","value":"2"},{"label":"Арабский","value":"27"},{"label":"Арагонский","value":"28"},{"label":"Арберешский","value":"29"},{"label":"Армянский","value":"30"},{"label":"Ассамский","value":"31"},{"label":"Астурийский","value":"32"},{"label":"Афарский","value":"33"},{"label":"Африкаанс","value":"34"},{"label":"Ацтекский","value":"35"},{"label":"Баварский","value":"36"},{"label":"Бамбарийский","value":"37"},{"label":"Баскский","value":"39"},{"label":"Башкирский","value":"40"},{"label":"Белорусский","value":"10"},{"label":"Бенгальский","value":"41"},{"label":"Бирманский","value":"42"},{"label":"Бислама","value":"43"},{"label":"Бихари","value":"44"},{"label":"Болгарский","value":"45"},{"label":"Боснийский","value":"234"},{"label":"Бретонский","value":"47"},{"label":"Валенсийский","value":"48"},{"label":"Валлийский","value":"49"},{"label":"Валлонский","value":"50"},{"label":"Венгерский","value":"51"},{"label":"Венда","value":"52"},{"label":"Венетский","value":"53"},{"label":"Верхнелужицкий","value":"54"},{"label":"Волоф","value":"55"},{"label":"Вьетнамский","value":"57"},{"label":"Гавайский","value":"58"},{"label":"Гаитянский","value":"59"},{"label":"Галисийский","value":"60"},{"label":"Гереро","value":"61"},{"label":"Голландский","value":"62"},{"label":"Греческий","value":"63"},{"label":"Грузинский","value":"64"},{"label":"Гуарани","value":"65"},{"label":"Гуджарати","value":"66"},{"label":"Датский","value":"19"},{"label":"Дзонг-кэ","value":"68"},{"label":"Древнегреческий","value":"69"},{"label":"Западно-фламандский","value":"70"},{"label":"Зулу","value":"71"},{"label":"Иврит","value":"15"},{"label":"Игбо","value":"72"},{"label":"Идиш","value":"73"},{"label":"Илоко","value":"74"},{"label":"Индонезийский","value":"75"},{"label":"Интерлингва","value":"76"},{"label":"Инуктитут","value":"77"},{"label":"Инупиак","value":"78"},{"label":"Ирландский","value":"79"},{"label":"Исландский","value":"80"},{"label":"Испанский","value":"6"},{"label":"Итальянский","value":"5"},{"label":"Йоруба","value":"81"},{"label":"Кабильский","value":"82"},{"label":"Казахский","value":"83"},{"label":"Калмыцкий","value":"235"},{"label":"Каннада","value":"84"},{"label":"Кантонский юэ","value":"85"},{"label":"Канури","value":"86"},{"label":"Каталанский","value":"87"},{"label":"Кашмири","value":"88"},{"label":"Кечуа","value":"90"},{"label":"Кикуйю","value":"91"},{"label":"Киньяруанда","value":"92"},{"label":"Киргизский","value":"93"},{"label":"Китайский","value":"7"},{"label":"Клингонский","value":"94"},{"label":"Коми","value":"95"},{"label":"Конго","value":"96"},{"label":"Конкани","value":"97"},{"label":"Корейский","value":"98"},{"label":"Корсиканский","value":"100"},{"label":"Котава","value":"101"},{"label":"Кри","value":"102"},{"label":"Курдский","value":"105"},{"label":"Кхмерский","value":"107"},{"label":"Лакский","value":"233"},{"label":"Лаосский","value":"109"},{"label":"Латынь","value":"110"},{"label":"Латышский","value":"111"},{"label":"Лезгинский","value":"112"},{"label":"Лимбургский","value":"113"},{"label":"Лингала","value":"114"},{"label":"Литовский","value":"115"},{"label":"Луба","value":"118"},{"label":"Луганда","value":"119"},{"label":"Люксембургский","value":"120"},{"label":"Македонский","value":"121"},{"label":"Малагасийский","value":"122"},{"label":"Малайский","value":"123"},{"label":"Мальдивский","value":"125"},{"label":"Мальтийский","value":"126"},{"label":"Маори","value":"127"},{"label":"Марийский","value":"232"},{"label":"Маршалльский","value":"130"},{"label":"Молдавский","value":"11"},{"label":"Монгольский","value":"133"},{"label":"Мяо (хмонг)","value":"209"},{"label":"Навахо","value":"135"},{"label":"Неаполитанский","value":"139"},{"label":"Немецкий","value":"3"},{"label":"Непальский","value":"140"},{"label":"Норвежский","value":"18"},{"label":"Осетинский","value":"147"},{"label":"Пакистанский","value":"230"},{"label":"Пенджабский","value":"149"},{"label":"Персидский","value":"151"},{"label":"Польский","value":"152"},{"label":"Португальский","value":"153"},{"label":"Румынский","value":"158"},{"label":"Русский","value":"1"},{"label":"Санскрит","value":"163"},{"label":"Сардинский","value":"164"},{"label":"Сербохорватский","value":"166"},{"label":"Словацкий","value":"170"},{"label":"Словенский","value":"171"},{"label":"Сомали","value":"172"},{"label":"Старотурецкий","value":"174"},{"label":"Суахили","value":"175"},{"label":"Сунданский","value":"176"},{"label":"Тагальский","value":"177"},{"label":"Таджикский","value":"178"},{"label":"Таитянский","value":"179"},{"label":"Тайваньский","value":"180"},{"label":"Тайский","value":"181"},{"label":"Тамильский","value":"182"},{"label":"Татарский","value":"12"},{"label":"Телугу","value":"184"},{"label":"Тибетский","value":"185"},{"label":"Тигринья","value":"186"},{"label":"Ток-писин","value":"187"},{"label":"Токи пона","value":"188"},{"label":"Тонганский","value":"189"},{"label":"Тсвана","value":"191"},{"label":"Тсонга","value":"192"},{"label":"Турецкий","value":"193"},{"label":"Туркменский","value":"194"},{"label":"Удмуртский","value":"196"},{"label":"Узбекский","value":"197"},{"label":"Уйгурский","value":"198"},{"label":"Украинский","value":"9"},{"label":"Фиджийский","value":"201"},{"label":"Филиппинский","value":"229"},{"label":"Финский","value":"17"},{"label":"Французский","value":"4"},{"label":"Фризский","value":"203"},{"label":"Фулах","value":"204"},{"label":"Хауса","value":"206"},{"label":"Хинди","value":"207"},{"label":"Хири-моту","value":"208"},{"label":"Чеченский","value":"213"},{"label":"Чешский","value":"13"},{"label":"Чувашский","value":"217"},{"label":"Шведский","value":"16"},{"label":"Швейцарский немецкий","value":"218"},{"label":"Шона","value":"219"},{"label":"Шотландский","value":"67"},{"label":"Эве","value":"221"},{"label":"Эскимосский","value":"223"},{"label":"Эсперанто","value":"14"},{"label":"Эстонский","value":"224"},{"label":"Южно-корейский","value":"231"},{"label":"Юкатекский","value":"225"},{"label":"Яванский","value":"227"},{"label":"Японский","value":"8"}],"inputType":FilterInputs.Picker},{"key":"t_lang","label":"Язык перевода:","values":[{"label":"Неважно","value":"0"},{"label":"Абхазский","value":"20"},{"label":"Аварский","value":"21"},{"label":"Азербайджанский","value":"22"},{"label":"Аймара","value":"23"},{"label":"Акан","value":"24"},{"label":"Албанский","value":"25"},{"label":"Амхарский","value":"26"},{"label":"Английский","value":"2"},{"label":"Арабский","value":"27"},{"label":"Арагонский","value":"28"},{"label":"Арберешский","value":"29"},{"label":"Армянский","value":"30"},{"label":"Ассамский","value":"31"},{"label":"Астурийский","value":"32"},{"label":"Афарский","value":"33"},{"label":"Африкаанс","value":"34"},{"label":"Ацтекский","value":"35"},{"label":"Баварский","value":"36"},{"label":"Бамбарийский","value":"37"},{"label":"Баскский","value":"39"},{"label":"Башкирский","value":"40"},{"label":"Белорусский","value":"10"},{"label":"Бенгальский","value":"41"},{"label":"Бирманский","value":"42"},{"label":"Бислама","value":"43"},{"label":"Бихари","value":"44"},{"label":"Болгарский","value":"45"},{"label":"Боснийский","value":"234"},{"label":"Бретонский","value":"47"},{"label":"Валенсийский","value":"48"},{"label":"Валлийский","value":"49"},{"label":"Валлонский","value":"50"},{"label":"Венгерский","value":"51"},{"label":"Венда","value":"52"},{"label":"Венетский","value":"53"},{"label":"Верхнелужицкий","value":"54"},{"label":"Волоф","value":"55"},{"label":"Вьетнамский","value":"57"},{"label":"Гавайский","value":"58"},{"label":"Гаитянский","value":"59"},{"label":"Галисийский","value":"60"},{"label":"Гереро","value":"61"},{"label":"Голландский","value":"62"},{"label":"Греческий","value":"63"},{"label":"Грузинский","value":"64"},{"label":"Гуарани","value":"65"},{"label":"Гуджарати","value":"66"},{"label":"Датский","value":"19"},{"label":"Дзонг-кэ","value":"68"},{"label":"Древнегреческий","value":"69"},{"label":"Западно-фламандский","value":"70"},{"label":"Зулу","value":"71"},{"label":"Иврит","value":"15"},{"label":"Игбо","value":"72"},{"label":"Идиш","value":"73"},{"label":"Илоко","value":"74"},{"label":"Индонезийский","value":"75"},{"label":"Интерлингва","value":"76"},{"label":"Инуктитут","value":"77"},{"label":"Инупиак","value":"78"},{"label":"Ирландский","value":"79"},{"label":"Исландский","value":"80"},{"label":"Испанский","value":"6"},{"label":"Итальянский","value":"5"},{"label":"Йоруба","value":"81"},{"label":"Кабильский","value":"82"},{"label":"Казахский","value":"83"},{"label":"Калмыцкий","value":"235"},{"label":"Каннада","value":"84"},{"label":"Кантонский юэ","value":"85"},{"label":"Канури","value":"86"},{"label":"Каталанский","value":"87"},{"label":"Кашмири","value":"88"},{"label":"Кечуа","value":"90"},{"label":"Кикуйю","value":"91"},{"label":"Киньяруанда","value":"92"},{"label":"Киргизский","value":"93"},{"label":"Китайский","value":"7"},{"label":"Клингонский","value":"94"},{"label":"Коми","value":"95"},{"label":"Конго","value":"96"},{"label":"Конкани","value":"97"},{"label":"Корейский","value":"98"},{"label":"Корсиканский","value":"100"},{"label":"Котава","value":"101"},{"label":"Кри","value":"102"},{"label":"Курдский","value":"105"},{"label":"Кхмерский","value":"107"},{"label":"Лакский","value":"233"},{"label":"Лаосский","value":"109"},{"label":"Латынь","value":"110"},{"label":"Латышский","value":"111"},{"label":"Лезгинский","value":"112"},{"label":"Лимбургский","value":"113"},{"label":"Лингала","value":"114"},{"label":"Литовский","value":"115"},{"label":"Луба","value":"118"},{"label":"Луганда","value":"119"},{"label":"Люксембургский","value":"120"},{"label":"Македонский","value":"121"},{"label":"Малагасийский","value":"122"},{"label":"Малайский","value":"123"},{"label":"Мальдивский","value":"125"},{"label":"Мальтийский","value":"126"},{"label":"Маори","value":"127"},{"label":"Марийский","value":"232"},{"label":"Маршалльский","value":"130"},{"label":"Молдавский","value":"11"},{"label":"Монгольский","value":"133"},{"label":"Мяо (хмонг)","value":"209"},{"label":"Навахо","value":"135"},{"label":"Неаполитанский","value":"139"},{"label":"Немецкий","value":"3"},{"label":"Непальский","value":"140"},{"label":"Норвежский","value":"18"},{"label":"Осетинский","value":"147"},{"label":"Пакистанский","value":"230"},{"label":"Пенджабский","value":"149"},{"label":"Персидский","value":"151"},{"label":"Польский","value":"152"},{"label":"Португальский","value":"153"},{"label":"Румынский","value":"158"},{"label":"Русский","value":"1"},{"label":"Санскрит","value":"163"},{"label":"Сардинский","value":"164"},{"label":"Сербохорватский","value":"166"},{"label":"Словацкий","value":"170"},{"label":"Словенский","value":"171"},{"label":"Сомали","value":"172"},{"label":"Старотурецкий","value":"174"},{"label":"Суахили","value":"175"},{"label":"Сунданский","value":"176"},{"label":"Тагальский","value":"177"},{"label":"Таджикский","value":"178"},{"label":"Таитянский","value":"179"},{"label":"Тайваньский","value":"180"},{"label":"Тайский","value":"181"},{"label":"Тамильский","value":"182"},{"label":"Татарский","value":"12"},{"label":"Телугу","value":"184"},{"label":"Тибетский","value":"185"},{"label":"Тигринья","value":"186"},{"label":"Ток-писин","value":"187"},{"label":"Токи пона","value":"188"},{"label":"Тонганский","value":"189"},{"label":"Тсвана","value":"191"},{"label":"Тсонга","value":"192"},{"label":"Турецкий","value":"193"},{"label":"Туркменский","value":"194"},{"label":"Удмуртский","value":"196"},{"label":"Узбекский","value":"197"},{"label":"Уйгурский","value":"198"},{"label":"Украинский","value":"9"},{"label":"Фиджийский","value":"201"},{"label":"Филиппинский","value":"229"},{"label":"Финский","value":"17"},{"label":"Французский","value":"4"},{"label":"Фризский","value":"203"},{"label":"Фулах","value":"204"},{"label":"Хауса","value":"206"},{"label":"Хинди","value":"207"},{"label":"Хири-моту","value":"208"},{"label":"Чеченский","value":"213"},{"label":"Чешский","value":"13"},{"label":"Чувашский","value":"217"},{"label":"Шведский","value":"16"},{"label":"Швейцарский немецкий","value":"218"},{"label":"Шона","value":"219"},{"label":"Шотландский","value":"67"},{"label":"Эве","value":"221"},{"label":"Эскимосский","value":"223"},{"label":"Эсперанто","value":"14"},{"label":"Эстонский","value":"224"},{"label":"Южно-корейский","value":"231"},{"label":"Юкатекский","value":"225"},{"label":"Яванский","value":"227"},{"label":"Японский","value":"8"}],"inputType":FilterInputs.Picker},{"key":"type","label":"Тип:","values":[{"label":"Неважно","value":"0"},{"label":"Только авторские","value":"2"},{"label":"Только переводы","value":"1"}],"inputType":FilterInputs.Picker},{"key":"trash","label":"Другое:","values":[{"label":"Без фэндомов","value":"fandoms_ex_all"},{"label":"Готовые на 100%","value":"ready"},{"label":"Доступные для перевода","value":"tr"},{"label":"Доступные для скачивания","value":"gen"},{"label":"Завершённые проекты","value":"wealth"},{"label":"Распродажа","value":"discount"},{"label":"Только онгоинги","value":"ongoings"},{"label":"Убрать машинный","value":"remove_machinelate"}],"inputType":FilterInputs.Checkbox},{"key":"sort","label":"Сортировка:","values":[{"label":"По рейтингу","value":"6"},{"label":"По дате последней активности","value":"4"},{"label":"По дате создания","value":"3"},{"label":"По кол-ву бесплатных глав","value":"11"},{"label":"По кол-ву в закладках","value":"13"},{"label":"По кол-ву в избранном","value":"14"},{"label":"По кол-ву лайков","value":"8"},{"label":"По кол-ву переведённых глав","value":"7"},{"label":"По кол-ву рецензий","value":"12"},{"label":"По кол-ву страниц","value":"10"},{"label":"По названию на языке оригинала","value":"1"},{"label":"По названию на языке перевода","value":"2"},{"label":"По просмотрам","value":"5"},{"label":"По степени готовности","value":"0"},{"label":"Случайно","value":"9"}],"inputType":FilterInputs.Picker},{"key":"genres","label":"Жанры:","values":[{"label":"Анал","value":"2"},{"label":"Бдсм","value":"3"},{"label":"Большая грудь","value":"5"},{"label":"Большая попка","value":"6"},{"label":"Большой член","value":"7"},{"label":"Бондаж","value":"8"},{"label":"В первый раз","value":"9"},{"label":"В цвете","value":"10"},{"label":"Гарем","value":"11"},{"label":"Гендарная интрига","value":"12"},{"label":"Групповой секс","value":"13"},{"label":"Детектив","value":"39"},{"label":"Драма","value":"14"},{"label":"Зрелые женщины (milf)","value":"15"},{"label":"Измена","value":"16"},{"label":"Изнасилование","value":"17"},{"label":"Инцест","value":"18"},{"label":"Исторический","value":"19"},{"label":"Комедия","value":"20"},{"label":"Контроль над разумом","value":"35"},{"label":"Маленькая грудь","value":"21"},{"label":"Мистика","value":"40"},{"label":"Научная фантастика","value":"22"},{"label":"Нетораре","value":"23"},{"label":"Оральный секс","value":"24"},{"label":"Повседневность","value":"41"},{"label":"Приключения","value":"38"},{"label":"Публичный секс","value":"33"},{"label":"Романтика","value":"25"},{"label":"С изображениями","value":"36"},{"label":"Сверхъестественное","value":"34"},{"label":"Смат","value":"37"},{"label":"Тентакли","value":"26"},{"label":"Трагедия","value":"27"},{"label":"Ужасы","value":"28"},{"label":"Фантастика","value":"32"},{"label":"Фэнтези","value":"29"},{"label":"Чикан","value":"30"},{"label":"Этти","value":"31"},{"label":"Ahegao","value":"1"}],"inputType":FilterInputs.Checkbox},{"key":"tags","label":"Тэги:","values":[{"label":"+18","value":"141"},{"label":"18+","value":"200"},{"label":"21+","value":"334"},{"label":"Адекватные главные герои","value":"253"},{"label":"Азартные игры","value":"210"},{"label":"Айдолы","value":"364"},{"label":"Акула","value":"53"},{"label":"Альтернативное развитие событий","value":"338"},{"label":"Аморальный главный герой","value":"219"},{"label":"Анал","value":"7"},{"label":"Анальный секс","value":"67"},{"label":"Ангелы","value":"114"},{"label":"Антигерой","value":"226"},{"label":"Аристократия","value":"260"},{"label":"Артефакт","value":"379"},{"label":"Афродизиак","value":"276"},{"label":"Ахегао","value":"240"},{"label":"Бабушка беременна от внука","value":"393"},{"label":"Бабушка и внук","value":"380"},{"label":"Бдсм","value":"131"},{"label":"Беременность","value":"148"},{"label":"Бесплатно","value":"79"},{"label":"Бесстрашные персонажи","value":"339"},{"label":"Библиотека","value":"265"},{"label":"Бистиалити","value":"391"},{"label":"Битва за трон","value":"404"},{"label":"Близнецы","value":"198"},{"label":"Блондинка","value":"91"},{"label":"Богатые персонажи","value":"248"},{"label":"Боги","value":"115"},{"label":"Боевик","value":"252"},{"label":"Большая грудь","value":"33"},{"label":"Большая попка","value":"328"},{"label":"Большой член","value":"76"},{"label":"Большой член сына","value":"396"},{"label":"Босс и подчиненный","value":"330"},{"label":"Брак","value":"182"},{"label":"Брак по расчёту","value":"346"},{"label":"Брат","value":"29"},{"label":"Брат и сестра","value":"30"},{"label":"Брюнетка","value":"28"},{"label":"Бэтмен","value":"369"},{"label":"Бэтмен","value":"170"},{"label":"В первый раз","value":"179"},{"label":"Вагинальный секс","value":"57"},{"label":"Вагинальный секс","value":"171"},{"label":"Вайурист","value":"9"},{"label":"Вампиры","value":"133"},{"label":"Ван-пис","value":"335"},{"label":"Веб камера","value":"289"},{"label":"Ведьмы","value":"232"},{"label":"Викинги","value":"307"},{"label":"Виртуальная реальность","value":"382"},{"label":"Вирус","value":"203"},{"label":"Внучка","value":"189"},{"label":"Война","value":"387"},{"label":"Воспоминания из прошлого","value":"405"},{"label":"Враги становятся любовниками","value":"410"},{"label":"Время","value":"81"},{"label":"Второй шанс","value":"244"},{"label":"Вуайеризм","value":"62"},{"label":"Выживание","value":"135"},{"label":"Гарем","value":"107"},{"label":"Гарри поттер","value":"97"},{"label":"Гвен","value":"402"},{"label":"Гг имба","value":"87"},{"label":"Генетические модификации","value":"314"},{"label":"Гипноз","value":"143"},{"label":"Главная героиня девушка","value":"147"},{"label":"Главный герой женщина","value":"213"},{"label":"Главный герой извращенец","value":"116"},{"label":"Главный герой мужчина","value":"117"},{"label":"Глубокое горло","value":"94"},{"label":"Гоблины","value":"230"},{"label":"Город","value":"139"},{"label":"Городское фэнтези","value":"297"},{"label":"Грудное молоко","value":"225"},{"label":"Групповой секс","value":"72"},{"label":"Гэнг-бэнг","value":"235"},{"label":"Гяру","value":"222"},{"label":"Двойное проникновение","value":"42"},{"label":"Двойной анал","value":"47"},{"label":"Дворяне","value":"246"},{"label":"Деамоны старший школы","value":"291"},{"label":"Девственница","value":"119"},{"label":"Девушки-монстры","value":"223"},{"label":"Демоны","value":"98"},{"label":"Детектив","value":"249"},{"label":"Дзёсэй","value":"259"},{"label":"Доктор","value":"326"},{"label":"Дом","value":"138"},{"label":"Доминирование","value":"18"},{"label":"Дочь","value":"153"},{"label":"Дочь беременна от отца","value":"348"},{"label":"Древние времена","value":"383"},{"label":"Древний китай","value":"261"},{"label":"Другой мир","value":"365"},{"label":"Дружба","value":"325"},{"label":"Друзья детства","value":"183"},{"label":"Дядя","value":"160"},{"label":"Жена","value":"70"},{"label":"Жена и муж","value":"99"},{"label":"Жена шлюха","value":"236"},{"label":"Женское доминирование","value":"100"},{"label":"Жесткий секс","value":"283"},{"label":"Жёсткий секс","value":"101"},{"label":"Жестокие персонажи","value":"254"},{"label":"Жестокий мир","value":"336"},{"label":"Жестокость","value":"123"},{"label":"Заботливый главный герой","value":"340"},{"label":"Зависимость","value":"370"},{"label":"Заключение","value":"196"},{"label":"Заключённые","value":"384"},{"label":"Замок","value":"140"},{"label":"Запретная любовь","value":"273"},{"label":"Заражение","value":"206"},{"label":"Звёздные войны","value":"120"},{"label":"Зверодевочки","value":"158"},{"label":"Зло","value":"343"},{"label":"Золовка","value":"77"},{"label":"Золотой дождь","value":"146"},{"label":"Зомби апокалипсис","value":"241"},{"label":"Зоофилия","value":"144"},{"label":"Зрелые женщины","value":"398"},{"label":"Игровые элементы","value":"385"},{"label":"Извращения","value":"192"},{"label":"Измена","value":"71"},{"label":"Изменения внешности","value":"315"},{"label":"Изменения личности","value":"316"},{"label":"Изнасилование","value":"275"},{"label":"Изуку мидория","value":"337"},{"label":"Ино","value":"127"},{"label":"Инопланетяне","value":"304"},{"label":"Интересный сюжет","value":"349"},{"label":"Интимные сцены","value":"322"},{"label":"Интриги и заговоры","value":"262"},{"label":"Интроверт","value":"38"},{"label":"Инфекция","value":"207"},{"label":"Инцест","value":"35"},{"label":"Исторический роман","value":"406"},{"label":"Камера","value":"92"},{"label":"Колледж","value":"82"},{"label":"Комикс","value":"286"},{"label":"Контроль","value":"19"},{"label":"Контроль над разумом","value":"181"},{"label":"Контроль разума","value":"65"},{"label":"Кончил внутрь","value":"221"},{"label":"Королевская семья","value":"358"},{"label":"Коррупция","value":"49"},{"label":"Космос","value":"204"},{"label":"Красивая главная героиня","value":"255"},{"label":"Красивые женщины","value":"321"},{"label":"Красивый главный герой","value":"266"},{"label":"Ксенофилия","value":"386"},{"label":"Кулинария","value":"362"},{"label":"Культвация","value":"86"},{"label":"Кунилингус","value":"152"},{"label":"Кушина","value":"399"},{"label":"Лактация","value":"11"},{"label":"Лесби","value":"408"},{"label":"Лишение девственности","value":"212"},{"label":"Лоли","value":"218"},{"label":"Лунатизм","value":"279"},{"label":"Любовь","value":"89"},{"label":"Магический мир","value":"357"},{"label":"Магия","value":"80"},{"label":"Мама","value":"3"},{"label":"Мама беременна от сына","value":"274"},{"label":"Мама и дочь","value":"163"},{"label":"Мама и сын","value":"1"},{"label":"Мама супермена","value":"39"},{"label":"Манипуляция временем","value":"292"},{"label":"Марвел","value":"290"},{"label":"Марвел","value":"173"},{"label":"Марти стью","value":"102"},{"label":"Массаж","value":"224"},{"label":"Мастурбация","value":"63"},{"label":"Мать","value":"239"},{"label":"Мать и дочь","value":"381"},{"label":"Мать и сын","value":"237"},{"label":"Мафия","value":"256"},{"label":"Мачеха","value":"197"},{"label":"Мачеха беременна от сына","value":"395"},{"label":"Мачеха и сын","value":"394"},{"label":"Медсестра","value":"341"},{"label":"Межрассовый","value":"54"},{"label":"Месть","value":"306"},{"label":"Меха","value":"268"},{"label":"Ми","value":"243"},{"label":"Милф","value":"34"},{"label":"Милф","value":"180"},{"label":"Минет","value":"52"},{"label":"Мистика","value":"250"},{"label":"Младшая сестра","value":"154"},{"label":"Много спермы","value":"409"},{"label":"Модель","value":"324"},{"label":"Монстры","value":"333"},{"label":"Мошеничество","value":"44"},{"label":"Мужская беременность","value":"363"},{"label":"Мужчина протагонист","value":"108"},{"label":"Музыка","value":"331"},{"label":"Мэри съюха","value":"309"},{"label":"Наруко","value":"400"},{"label":"Наруто","value":"46"},{"label":"Насилие","value":"128"},{"label":"Насилие и жестокость","value":"193"},{"label":"Научный эксперимент","value":"313"},{"label":"Нежить","value":"373"},{"label":"Некромантия","value":"298"},{"label":"Ненормативная лексика","value":"124"},{"label":"Нетораре","value":"69"},{"label":"Нетори","value":"284"},{"label":"Нижнее бельё","value":"392"},{"label":"Ниндзя","value":"296"},{"label":"Ношеные трусики","value":"166"},{"label":"Нудизм","value":"156"},{"label":"Няня","value":"88"},{"label":"Обмен женами","value":"78"},{"label":"Оборотни","value":"136"},{"label":"Обратный гарем","value":"214"},{"label":"Одержимость","value":"345"},{"label":"Омегаверс","value":"368"},{"label":"Оплодотворение","value":"157"},{"label":"Оральный секс","value":"10"},{"label":"Оргия","value":"356"},{"label":"Орки","value":"388"},{"label":"От слабого к сильному","value":"351"},{"label":"Отец","value":"2"},{"label":"Отец делится с сыном","value":"6"},{"label":"Отец и дочь","value":"205"},{"label":"Отец куколд","value":"272"},{"label":"Офис","value":"234"},{"label":"Падчерица","value":"271"},{"label":"Пайзури","value":"195"},{"label":"Папа и дочь","value":"360"},{"label":"Паразиты","value":"208"},{"label":"Параллельный мир","value":"320"},{"label":"Пародия","value":"371"},{"label":"Первый раз","value":"159"},{"label":"Перемещение в другой мир","value":"347"},{"label":"Перемещение во времени","value":"245"},{"label":"Перерождение","value":"109"},{"label":"Перерождение в злодея","value":"202"},{"label":"Пирсинг","value":"145"},{"label":"Писатель","value":"267"},{"label":"Планомерное развитие событий","value":"350"},{"label":"Повседневность","value":"247"},{"label":"Подглядывание","value":"280"},{"label":"Подчинение","value":"106"},{"label":"Подчинение и унижение","value":"211"},{"label":"Поедание киски","value":"26"},{"label":"Покемоны","value":"132"},{"label":"Покорная","value":"8"},{"label":"Полигамия","value":"352"},{"label":"Половое воспитание","value":"37"},{"label":"Полулюди","value":"231"},{"label":"Попаданец","value":"103"},{"label":"Попадание в книгу","value":"361"},{"label":"Порка","value":"20"},{"label":"Порно","value":"278"},{"label":"Постапокалипсис","value":"332"},{"label":"Потеря девственности","value":"142"},{"label":"Похищение","value":"161"},{"label":"Преданные любовный интерес","value":"407"},{"label":"Призраки","value":"412"},{"label":"Приключения","value":"134"},{"label":"Принуждение","value":"66"},{"label":"Психология","value":"238"},{"label":"Публично","value":"85"},{"label":"Публичный секс","value":"233"},{"label":"Раб","value":"353"},{"label":"Рабы","value":"308"},{"label":"Разват","value":"58"},{"label":"Разврат","value":"64"},{"label":"Райзен","value":"95"},{"label":"Раса инопланетных космических лесбиянок","value":"294"},{"label":"Религия","value":"403"},{"label":"Рестленг","value":"84"},{"label":"Риас гремори","value":"389"},{"label":"Романтика","value":"178"},{"label":"Рыжий","value":"90"},{"label":"С","value":"413"},{"label":"Сакура","value":"126"},{"label":"Самолет","value":"93"},{"label":"Санса старк","value":"277"},{"label":"Санта","value":"372"},{"label":"Свадьба","value":"73"},{"label":"Сверхсила","value":"228"},{"label":"Сверхъестественное","value":"319"},{"label":"Свингеры","value":"201"},{"label":"Свободные отношения","value":"186"},{"label":"Связывание","value":"137"},{"label":"Сёдзе","value":"264"},{"label":"Секс","value":"21"},{"label":"Секс без проникновения","value":"68"},{"label":"Секс втроем","value":"43"},{"label":"Секс игрушки","value":"59"},{"label":"Секс рабыня","value":"55"},{"label":"Секс с монстрами","value":"56"},{"label":"Секс с учителем","value":"184"},{"label":"Секса будет много","value":"151"},{"label":"Сексуальное желание","value":"209"},{"label":"Селфцест","value":"397"},{"label":"Семья","value":"5"},{"label":"Сестра","value":"31"},{"label":"Сестра беременна от брата","value":"355"},{"label":"Сильный с самого начала","value":"112"},{"label":"Симбиоз","value":"50"},{"label":"Сирена","value":"51"},{"label":"Система","value":"104"},{"label":"Сиськи","value":"285"},{"label":"Сквирт","value":"164"},{"label":"Скрытый секс","value":"287"},{"label":"Служанка","value":"215"},{"label":"Соб","value":"281"},{"label":"Соблазнение","value":"162"},{"label":"Современность","value":"217"},{"label":"Соколиный Глаз","value":"176"},{"label":"Соперничество","value":"216"},{"label":"Соседи","value":"61"},{"label":"Соседка","value":"312"},{"label":"Сперма","value":"229"},{"label":"Сперма на лицо","value":"199"},{"label":"Спящие","value":"187"},{"label":"Старшая сестра","value":"311"},{"label":"Стеб","value":"111"},{"label":"Студенты","value":"177"},{"label":"Суккуб","value":"390"},{"label":"Супергерои","value":"305"},{"label":"Суперспособности","value":"300"},{"label":"Сын","value":"4"},{"label":"Твинцест","value":"188"},{"label":"Темное фэнтези","value":"293"},{"label":"Тентакли","value":"303"},{"label":"Тетя","value":"113"},{"label":"Тетя беременна от племянника","value":"376"},{"label":"Тетя и племянник","value":"377"},{"label":"Техника","value":"302"},{"label":"Технологии","value":"301"},{"label":"Тёща","value":"270"},{"label":"Тиран","value":"310"},{"label":"Трагическое прошлое","value":"251"},{"label":"Трансмиграция","value":"269"},{"label":"Трансформация","value":"317"},{"label":"Триллер","value":"344"},{"label":"Трусики","value":"165"},{"label":"Убийства","value":"258"},{"label":"Удача","value":"299"},{"label":"Ужасы","value":"375"},{"label":"Улучшение тела","value":"288"},{"label":"Умная главная героиня","value":"242"},{"label":"Умные персонажи","value":"257"},{"label":"Умный главный герой","value":"354"},{"label":"Университет","value":"323"},{"label":"Ученик","value":"83"},{"label":"Ф","value":"149"},{"label":"Фанатичная любовь","value":"366"},{"label":"Фанаты","value":"367"},{"label":"Фантастика","value":"295"},{"label":"Фанфик","value":"40"},{"label":"Фелляция","value":"22"},{"label":"Ферма","value":"191"},{"label":"Фетиш","value":"60"},{"label":"Флэш","value":"121"},{"label":"Футанария","value":"150"},{"label":"Фэнтези","value":"359"},{"label":"Хентай","value":"75"},{"label":"Хината","value":"110"},{"label":"Холодная главная героиня","value":"263"},{"label":"Черная вдова","value":"220"},{"label":"Черная Вдова","value":"175"},{"label":"Черный юмор","value":"374"},{"label":"Читерство","value":"45"},{"label":"Чтение мыслей","value":"227"},{"label":"Чудовища","value":"378"},{"label":"Шантаж","value":"129"},{"label":"Школа","value":"118"},{"label":"Школьная жизнь","value":"318"},{"label":"Шлюха","value":"32"},{"label":"Шоу-бизнес","value":"329"},{"label":"Шоу-бизнес","value":"172"},{"label":"Эксгибиционизм","value":"74"},{"label":"Элементы бдсм","value":"185"},{"label":"Эмма уотсон","value":"342"},{"label":"Эмма Уотсон","value":"169"},{"label":"Эротика","value":"36"},{"label":"Этти","value":"327"},{"label":"Юмор","value":"105"},{"label":"Яндере","value":"155"},{"label":"Bl","value":"125"},{"label":"Dc","value":"411"},{"label":"Gl","value":"96"},{"label":"Harry potter","value":"190"},{"label":"Harry potter","value":"168"},{"label":"Hentai","value":"282"},{"label":"Marvel","value":"194"},{"label":"Marvel","value":"174"},{"label":"Milf","value":"167"},{"label":"Mj","value":"401"}],"inputType":FilterInputs.Checkbox},{"key":"fandoms","label":"Фэндом:","values":[{"label":"Аватар: Легенда о Корре / Avatar legend of Korra","value":"46"},{"label":"Аватар: Легенда об Аанге / Avatar: The Legend of Aang / Avatar: The Last Airbender","value":"45"},{"label":"Аладдин / Aladdin","value":"86"},{"label":"Алиса в Стране чудес / Alice in Wonderland","value":"90"},{"label":"Американский папаша / American Dad","value":"85"},{"label":"Атака титанов / Атака на титанов / Attack on Titan","value":"41"},{"label":"Блич / Bleach","value":"58"},{"label":"Боевой континент","value":"101"},{"label":"Большой куш / One Piece","value":"18"},{"label":"Боруто: Новое поколение Наруто / Boruto: Naruto Next Generations","value":"9"},{"label":"Бэтмен / The Batman","value":"36"},{"label":"Ведьмак / The Witcher","value":"53"},{"label":"Военная хроника маленькой девочки","value":"100"},{"label":"Волейбол / Haikyu!!","value":"37"},{"label":"Вселенная Марвел / Marvel Universe","value":"7"},{"label":"Вселенная Марвел / Marvel Universe / Marvel Comics","value":"52"},{"label":"Вселенная Стивена","value":"61"},{"label":"Вселенная DC / DC Universe / DC Comics","value":"48"},{"label":"Гарри Поттер / Harry Potter","value":"4"},{"label":"Гоэтия / Гоетия / Yοητεία / Ars Goetia","value":"77"},{"label":"Демоны старшей школы / High School DxD","value":"10"},{"label":"День сурка / Groundhog Day","value":"3"},{"label":"Джессика Джонс / Marvel's Jessica Jones","value":"42"},{"label":"Дисней / The Walt Disney Company","value":"74"},{"label":"Древние свитки: Скайрим / TES: Skyrim","value":"15"},{"label":"Дэдпул / Deadpool","value":"22"},{"label":"Дэнни-призрак / Danny Phantom","value":"51"},{"label":"Железный человек / Iron Man","value":"19"},{"label":"Звёздная принцесса и силы зла / Стар против сил зла / Star vs. The Forces of Evil","value":"50"},{"label":"Звездные Войны / Star Wars","value":"43"},{"label":"Звёздные Войны / Star Wars","value":"16"},{"label":"Игра престолов","value":"78"},{"label":"Касльвания / Castlevania","value":"29"},{"label":"Киберпанк 2077 / Cyberpunk 2077","value":"6"},{"label":"Код Гиас / Code Geass","value":"84"},{"label":"Кольцо Элдена","value":"60"},{"label":"Королевства Сердец / Kingdom Hearts","value":"93"},{"label":"Красавица и чудовище / Beauty and the Beast","value":"91"},{"label":"Красный, Белый, Черный, Желтый / RWBY","value":"32"},{"label":"Кунг фу панда","value":"81"},{"label":"Лига Легенд / League of Legends","value":"5"},{"label":"Люди Икс / X-Men","value":"25"},{"label":"Маг на полную ставку / Quanzhi Fashi","value":"30"},{"label":"Мастера меча онлайн / Sword Art Online / SAO","value":"47"},{"label":"Мир Тьмы / World of Darkness","value":"28"},{"label":"Мой маленький пони / My Little Pony","value":"72"},{"label":"Мой маленький пони: Дружба — это чудо / My Little Pony: Friendship is Magic","value":"71"},{"label":"Моя геройская академия / Boku no Hero Academia","value":"8"},{"label":"Мстители / The Avengers","value":"20"},{"label":"Мстители. Эра Альтрона / The Avengers. Age of Ultron","value":"24"},{"label":"Мулан / Mulan","value":"94"},{"label":"Наруто / Naruto","value":"2"},{"label":"Овервотч","value":"79"},{"label":"Поднятие уровня в одиночку","value":"87"},{"label":"Порновселенная / Porn Universe","value":"31"},{"label":"Прототип / Prototype","value":"44"},{"label":"Рапунцель: Запутанная история / Tangled","value":"96"},{"label":"Розовая пора моей школьной жизни сплошной обман / Yahari Ore no Seishun Love Come wa Machigatteiru","value":"14"},{"label":"Русалочка / The Little Mermaid","value":"97"},{"label":"Сага о Винланде","value":"66"},{"label":"Светлячок / Firefly","value":"76"},{"label":"Сильнейший в истории ученик Кэнити / Shijou Saikyou no Deshi Kenichi","value":"13"},{"label":"Симпсоны / The Simpsons","value":"73"},{"label":"Судьба: Великий Приказ / Fate: Grand Order","value":"54"},{"label":"Супергёрл(телесериал, 2015) / Supergirl","value":"95"},{"label":"Супермен / Superman","value":"1"},{"label":"Теория большого взрыва / The Big Bang Theory","value":"75"},{"label":"Тор / Thor","value":"27"},{"label":"У Коми-сан проблемы с общением / 古見さんは、コミュ症です / Komi Can't Communicate","value":"11"},{"label":"Убийца Акаме / Akame ga Kill","value":"40"},{"label":"Уэнздей / Wednesday","value":"26"},{"label":"Фантастическая четвёрка / Fantastic Four","value":"21"},{"label":"Флэш / The Flash","value":"17"},{"label":"Хвост Феи / Fairy Tail","value":"59"},{"label":"Холодное сердце / Frozen","value":"92"},{"label":"Человек одного удара / Ванпанчмен / One Punch-Man","value":"39"},{"label":"Человек-паук / Spider-Man","value":"23"},{"label":"Чёрный зверь / Чёрный Пёс / Kuroinu","value":"35"},{"label":"Чёрный зверь: Развращение Благородных Воительниц / Black Beast: Corruption of the Noble Warriors","value":"34"},{"label":"Школа мертвецов","value":"67"},{"label":"Школа строгого режима / Prison School","value":"12"},{"label":"Эффект Массы / Mass Effect","value":"57"},{"label":"Юные Титаны / Teen Titans","value":"49"},{"label":"Ars Goetia | Gods and Demons","value":"69"},{"label":"Biohazard","value":"99"},{"label":"CL","value":"70"},{"label":"Daraku Reijou Hakoiri Ojou-sama Netorare Choukyou Kiroku","value":"55"},{"label":"Doom","value":"64"},{"label":"Granblue fantasy","value":"88"},{"label":"Halo","value":"80"},{"label":"Highschool of the Dead/Школа мертвецов","value":"68"},{"label":"JK Bitch ni Shiboraretai","value":"56"},{"label":"Monogatari Series","value":"65"},{"label":"Monster girl quest","value":"62"},{"label":"Over","value":"102"},{"label":"Rapunzel/Рапунцель","value":"83"},{"label":"Resident Evil","value":"98"},{"label":"Solo leveling","value":"63"},{"label":"Tentacle Locker","value":"89"},{"label":"X-COM","value":"82"}],"inputType":FilterInputs.Checkbox},{"key":"genres_ex","label":"Исключить жанры:","values":[{"label":"Анал","value":"2"},{"label":"Бдсм","value":"3"},{"label":"Большая грудь","value":"5"},{"label":"Большая попка","value":"6"},{"label":"Большой член","value":"7"},{"label":"Бондаж","value":"8"},{"label":"В первый раз","value":"9"},{"label":"В цвете","value":"10"},{"label":"Гарем","value":"11"},{"label":"Гендарная интрига","value":"12"},{"label":"Групповой секс","value":"13"},{"label":"Детектив","value":"39"},{"label":"Драма","value":"14"},{"label":"Зрелые женщины (milf)","value":"15"},{"label":"Измена","value":"16"},{"label":"Изнасилование","value":"17"},{"label":"Инцест","value":"18"},{"label":"Исторический","value":"19"},{"label":"Комедия","value":"20"},{"label":"Контроль над разумом","value":"35"},{"label":"Маленькая грудь","value":"21"},{"label":"Мистика","value":"40"},{"label":"Научная фантастика","value":"22"},{"label":"Нетораре","value":"23"},{"label":"Оральный секс","value":"24"},{"label":"Повседневность","value":"41"},{"label":"Приключения","value":"38"},{"label":"Публичный секс","value":"33"},{"label":"Романтика","value":"25"},{"label":"С изображениями","value":"36"},{"label":"Сверхъестественное","value":"34"},{"label":"Смат","value":"37"},{"label":"Тентакли","value":"26"},{"label":"Трагедия","value":"27"},{"label":"Ужасы","value":"28"},{"label":"Фантастика","value":"32"},{"label":"Фэнтези","value":"29"},{"label":"Чикан","value":"30"},{"label":"Этти","value":"31"},{"label":"Ahegao","value":"1"}],"inputType":FilterInputs.Checkbox},{"key":"tags_ex","label":"Исключить тэги:","values":[{"label":"+18","value":"141"},{"label":"18+","value":"200"},{"label":"21+","value":"334"},{"label":"Адекватные главные герои","value":"253"},{"label":"Азартные игры","value":"210"},{"label":"Айдолы","value":"364"},{"label":"Акула","value":"53"},{"label":"Альтернативное развитие событий","value":"338"},{"label":"Аморальный главный герой","value":"219"},{"label":"Анал","value":"7"},{"label":"Анальный секс","value":"67"},{"label":"Ангелы","value":"114"},{"label":"Антигерой","value":"226"},{"label":"Аристократия","value":"260"},{"label":"Артефакт","value":"379"},{"label":"Афродизиак","value":"276"},{"label":"Ахегао","value":"240"},{"label":"Бабушка беременна от внука","value":"393"},{"label":"Бабушка и внук","value":"380"},{"label":"Бдсм","value":"131"},{"label":"Беременность","value":"148"},{"label":"Бесплатно","value":"79"},{"label":"Бесстрашные персонажи","value":"339"},{"label":"Библиотека","value":"265"},{"label":"Бистиалити","value":"391"},{"label":"Битва за трон","value":"404"},{"label":"Близнецы","value":"198"},{"label":"Блондинка","value":"91"},{"label":"Богатые персонажи","value":"248"},{"label":"Боги","value":"115"},{"label":"Боевик","value":"252"},{"label":"Большая грудь","value":"33"},{"label":"Большая попка","value":"328"},{"label":"Большой член","value":"76"},{"label":"Большой член сына","value":"396"},{"label":"Босс и подчиненный","value":"330"},{"label":"Брак","value":"182"},{"label":"Брак по расчёту","value":"346"},{"label":"Брат","value":"29"},{"label":"Брат и сестра","value":"30"},{"label":"Брюнетка","value":"28"},{"label":"Бэтмен","value":"369"},{"label":"Бэтмен","value":"170"},{"label":"В первый раз","value":"179"},{"label":"Вагинальный секс","value":"57"},{"label":"Вагинальный секс","value":"171"},{"label":"Вайурист","value":"9"},{"label":"Вампиры","value":"133"},{"label":"Ван-пис","value":"335"},{"label":"Веб камера","value":"289"},{"label":"Ведьмы","value":"232"},{"label":"Викинги","value":"307"},{"label":"Виртуальная реальность","value":"382"},{"label":"Вирус","value":"203"},{"label":"Внучка","value":"189"},{"label":"Война","value":"387"},{"label":"Воспоминания из прошлого","value":"405"},{"label":"Враги становятся любовниками","value":"410"},{"label":"Время","value":"81"},{"label":"Второй шанс","value":"244"},{"label":"Вуайеризм","value":"62"},{"label":"Выживание","value":"135"},{"label":"Гарем","value":"107"},{"label":"Гарри поттер","value":"97"},{"label":"Гвен","value":"402"},{"label":"Гг имба","value":"87"},{"label":"Генетические модификации","value":"314"},{"label":"Гипноз","value":"143"},{"label":"Главная героиня девушка","value":"147"},{"label":"Главный герой женщина","value":"213"},{"label":"Главный герой извращенец","value":"116"},{"label":"Главный герой мужчина","value":"117"},{"label":"Глубокое горло","value":"94"},{"label":"Гоблины","value":"230"},{"label":"Город","value":"139"},{"label":"Городское фэнтези","value":"297"},{"label":"Грудное молоко","value":"225"},{"label":"Групповой секс","value":"72"},{"label":"Гэнг-бэнг","value":"235"},{"label":"Гяру","value":"222"},{"label":"Двойное проникновение","value":"42"},{"label":"Двойной анал","value":"47"},{"label":"Дворяне","value":"246"},{"label":"Деамоны старший школы","value":"291"},{"label":"Девственница","value":"119"},{"label":"Девушки-монстры","value":"223"},{"label":"Демоны","value":"98"},{"label":"Детектив","value":"249"},{"label":"Дзёсэй","value":"259"},{"label":"Доктор","value":"326"},{"label":"Дом","value":"138"},{"label":"Доминирование","value":"18"},{"label":"Дочь","value":"153"},{"label":"Дочь беременна от отца","value":"348"},{"label":"Древние времена","value":"383"},{"label":"Древний китай","value":"261"},{"label":"Другой мир","value":"365"},{"label":"Дружба","value":"325"},{"label":"Друзья детства","value":"183"},{"label":"Дядя","value":"160"},{"label":"Жена","value":"70"},{"label":"Жена и муж","value":"99"},{"label":"Жена шлюха","value":"236"},{"label":"Женское доминирование","value":"100"},{"label":"Жесткий секс","value":"283"},{"label":"Жёсткий секс","value":"101"},{"label":"Жестокие персонажи","value":"254"},{"label":"Жестокий мир","value":"336"},{"label":"Жестокость","value":"123"},{"label":"Заботливый главный герой","value":"340"},{"label":"Зависимость","value":"370"},{"label":"Заключение","value":"196"},{"label":"Заключённые","value":"384"},{"label":"Замок","value":"140"},{"label":"Запретная любовь","value":"273"},{"label":"Заражение","value":"206"},{"label":"Звёздные войны","value":"120"},{"label":"Зверодевочки","value":"158"},{"label":"Зло","value":"343"},{"label":"Золовка","value":"77"},{"label":"Золотой дождь","value":"146"},{"label":"Зомби апокалипсис","value":"241"},{"label":"Зоофилия","value":"144"},{"label":"Зрелые женщины","value":"398"},{"label":"Игровые элементы","value":"385"},{"label":"Извращения","value":"192"},{"label":"Измена","value":"71"},{"label":"Изменения внешности","value":"315"},{"label":"Изменения личности","value":"316"},{"label":"Изнасилование","value":"275"},{"label":"Изуку мидория","value":"337"},{"label":"Ино","value":"127"},{"label":"Инопланетяне","value":"304"},{"label":"Интересный сюжет","value":"349"},{"label":"Интимные сцены","value":"322"},{"label":"Интриги и заговоры","value":"262"},{"label":"Интроверт","value":"38"},{"label":"Инфекция","value":"207"},{"label":"Инцест","value":"35"},{"label":"Исторический роман","value":"406"},{"label":"Камера","value":"92"},{"label":"Колледж","value":"82"},{"label":"Комикс","value":"286"},{"label":"Контроль","value":"19"},{"label":"Контроль над разумом","value":"181"},{"label":"Контроль разума","value":"65"},{"label":"Кончил внутрь","value":"221"},{"label":"Королевская семья","value":"358"},{"label":"Коррупция","value":"49"},{"label":"Космос","value":"204"},{"label":"Красивая главная героиня","value":"255"},{"label":"Красивые женщины","value":"321"},{"label":"Красивый главный герой","value":"266"},{"label":"Ксенофилия","value":"386"},{"label":"Кулинария","value":"362"},{"label":"Культвация","value":"86"},{"label":"Кунилингус","value":"152"},{"label":"Кушина","value":"399"},{"label":"Лактация","value":"11"},{"label":"Лесби","value":"408"},{"label":"Лишение девственности","value":"212"},{"label":"Лоли","value":"218"},{"label":"Лунатизм","value":"279"},{"label":"Любовь","value":"89"},{"label":"Магический мир","value":"357"},{"label":"Магия","value":"80"},{"label":"Мама","value":"3"},{"label":"Мама беременна от сына","value":"274"},{"label":"Мама и дочь","value":"163"},{"label":"Мама и сын","value":"1"},{"label":"Мама супермена","value":"39"},{"label":"Манипуляция временем","value":"292"},{"label":"Марвел","value":"290"},{"label":"Марвел","value":"173"},{"label":"Марти стью","value":"102"},{"label":"Массаж","value":"224"},{"label":"Мастурбация","value":"63"},{"label":"Мать","value":"239"},{"label":"Мать и дочь","value":"381"},{"label":"Мать и сын","value":"237"},{"label":"Мафия","value":"256"},{"label":"Мачеха","value":"197"},{"label":"Мачеха беременна от сына","value":"395"},{"label":"Мачеха и сын","value":"394"},{"label":"Медсестра","value":"341"},{"label":"Межрассовый","value":"54"},{"label":"Месть","value":"306"},{"label":"Меха","value":"268"},{"label":"Ми","value":"243"},{"label":"Милф","value":"34"},{"label":"Милф","value":"180"},{"label":"Минет","value":"52"},{"label":"Мистика","value":"250"},{"label":"Младшая сестра","value":"154"},{"label":"Много спермы","value":"409"},{"label":"Модель","value":"324"},{"label":"Монстры","value":"333"},{"label":"Мошеничество","value":"44"},{"label":"Мужская беременность","value":"363"},{"label":"Мужчина протагонист","value":"108"},{"label":"Музыка","value":"331"},{"label":"Мэри съюха","value":"309"},{"label":"Наруко","value":"400"},{"label":"Наруто","value":"46"},{"label":"Насилие","value":"128"},{"label":"Насилие и жестокость","value":"193"},{"label":"Научный эксперимент","value":"313"},{"label":"Нежить","value":"373"},{"label":"Некромантия","value":"298"},{"label":"Ненормативная лексика","value":"124"},{"label":"Нетораре","value":"69"},{"label":"Нетори","value":"284"},{"label":"Нижнее бельё","value":"392"},{"label":"Ниндзя","value":"296"},{"label":"Ношеные трусики","value":"166"},{"label":"Нудизм","value":"156"},{"label":"Няня","value":"88"},{"label":"Обмен женами","value":"78"},{"label":"Оборотни","value":"136"},{"label":"Обратный гарем","value":"214"},{"label":"Одержимость","value":"345"},{"label":"Омегаверс","value":"368"},{"label":"Оплодотворение","value":"157"},{"label":"Оральный секс","value":"10"},{"label":"Оргия","value":"356"},{"label":"Орки","value":"388"},{"label":"От слабого к сильному","value":"351"},{"label":"Отец","value":"2"},{"label":"Отец делится с сыном","value":"6"},{"label":"Отец и дочь","value":"205"},{"label":"Отец куколд","value":"272"},{"label":"Офис","value":"234"},{"label":"Падчерица","value":"271"},{"label":"Пайзури","value":"195"},{"label":"Папа и дочь","value":"360"},{"label":"Паразиты","value":"208"},{"label":"Параллельный мир","value":"320"},{"label":"Пародия","value":"371"},{"label":"Первый раз","value":"159"},{"label":"Перемещение в другой мир","value":"347"},{"label":"Перемещение во времени","value":"245"},{"label":"Перерождение","value":"109"},{"label":"Перерождение в злодея","value":"202"},{"label":"Пирсинг","value":"145"},{"label":"Писатель","value":"267"},{"label":"Планомерное развитие событий","value":"350"},{"label":"Повседневность","value":"247"},{"label":"Подглядывание","value":"280"},{"label":"Подчинение","value":"106"},{"label":"Подчинение и унижение","value":"211"},{"label":"Поедание киски","value":"26"},{"label":"Покемоны","value":"132"},{"label":"Покорная","value":"8"},{"label":"Полигамия","value":"352"},{"label":"Половое воспитание","value":"37"},{"label":"Полулюди","value":"231"},{"label":"Попаданец","value":"103"},{"label":"Попадание в книгу","value":"361"},{"label":"Порка","value":"20"},{"label":"Порно","value":"278"},{"label":"Постапокалипсис","value":"332"},{"label":"Потеря девственности","value":"142"},{"label":"Похищение","value":"161"},{"label":"Преданные любовный интерес","value":"407"},{"label":"Призраки","value":"412"},{"label":"Приключения","value":"134"},{"label":"Принуждение","value":"66"},{"label":"Психология","value":"238"},{"label":"Публично","value":"85"},{"label":"Публичный секс","value":"233"},{"label":"Раб","value":"353"},{"label":"Рабы","value":"308"},{"label":"Разват","value":"58"},{"label":"Разврат","value":"64"},{"label":"Райзен","value":"95"},{"label":"Раса инопланетных космических лесбиянок","value":"294"},{"label":"Религия","value":"403"},{"label":"Рестленг","value":"84"},{"label":"Риас гремори","value":"389"},{"label":"Романтика","value":"178"},{"label":"Рыжий","value":"90"},{"label":"С","value":"413"},{"label":"Сакура","value":"126"},{"label":"Самолет","value":"93"},{"label":"Санса старк","value":"277"},{"label":"Санта","value":"372"},{"label":"Свадьба","value":"73"},{"label":"Сверхсила","value":"228"},{"label":"Сверхъестественное","value":"319"},{"label":"Свингеры","value":"201"},{"label":"Свободные отношения","value":"186"},{"label":"Связывание","value":"137"},{"label":"Сёдзе","value":"264"},{"label":"Секс","value":"21"},{"label":"Секс без проникновения","value":"68"},{"label":"Секс втроем","value":"43"},{"label":"Секс игрушки","value":"59"},{"label":"Секс рабыня","value":"55"},{"label":"Секс с монстрами","value":"56"},{"label":"Секс с учителем","value":"184"},{"label":"Секса будет много","value":"151"},{"label":"Сексуальное желание","value":"209"},{"label":"Селфцест","value":"397"},{"label":"Семья","value":"5"},{"label":"Сестра","value":"31"},{"label":"Сестра беременна от брата","value":"355"},{"label":"Сильный с самого начала","value":"112"},{"label":"Симбиоз","value":"50"},{"label":"Сирена","value":"51"},{"label":"Система","value":"104"},{"label":"Сиськи","value":"285"},{"label":"Сквирт","value":"164"},{"label":"Скрытый секс","value":"287"},{"label":"Служанка","value":"215"},{"label":"Соб","value":"281"},{"label":"Соблазнение","value":"162"},{"label":"Современность","value":"217"},{"label":"Соколиный Глаз","value":"176"},{"label":"Соперничество","value":"216"},{"label":"Соседи","value":"61"},{"label":"Соседка","value":"312"},{"label":"Сперма","value":"229"},{"label":"Сперма на лицо","value":"199"},{"label":"Спящие","value":"187"},{"label":"Старшая сестра","value":"311"},{"label":"Стеб","value":"111"},{"label":"Студенты","value":"177"},{"label":"Суккуб","value":"390"},{"label":"Супергерои","value":"305"},{"label":"Суперспособности","value":"300"},{"label":"Сын","value":"4"},{"label":"Твинцест","value":"188"},{"label":"Темное фэнтези","value":"293"},{"label":"Тентакли","value":"303"},{"label":"Тетя","value":"113"},{"label":"Тетя беременна от племянника","value":"376"},{"label":"Тетя и племянник","value":"377"},{"label":"Техника","value":"302"},{"label":"Технологии","value":"301"},{"label":"Тёща","value":"270"},{"label":"Тиран","value":"310"},{"label":"Трагическое прошлое","value":"251"},{"label":"Трансмиграция","value":"269"},{"label":"Трансформация","value":"317"},{"label":"Триллер","value":"344"},{"label":"Трусики","value":"165"},{"label":"Убийства","value":"258"},{"label":"Удача","value":"299"},{"label":"Ужасы","value":"375"},{"label":"Улучшение тела","value":"288"},{"label":"Умная главная героиня","value":"242"},{"label":"Умные персонажи","value":"257"},{"label":"Умный главный герой","value":"354"},{"label":"Университет","value":"323"},{"label":"Ученик","value":"83"},{"label":"Ф","value":"149"},{"label":"Фанатичная любовь","value":"366"},{"label":"Фанаты","value":"367"},{"label":"Фантастика","value":"295"},{"label":"Фанфик","value":"40"},{"label":"Фелляция","value":"22"},{"label":"Ферма","value":"191"},{"label":"Фетиш","value":"60"},{"label":"Флэш","value":"121"},{"label":"Футанария","value":"150"},{"label":"Фэнтези","value":"359"},{"label":"Хентай","value":"75"},{"label":"Хината","value":"110"},{"label":"Холодная главная героиня","value":"263"},{"label":"Черная вдова","value":"220"},{"label":"Черная Вдова","value":"175"},{"label":"Черный юмор","value":"374"},{"label":"Читерство","value":"45"},{"label":"Чтение мыслей","value":"227"},{"label":"Чудовища","value":"378"},{"label":"Шантаж","value":"129"},{"label":"Школа","value":"118"},{"label":"Школьная жизнь","value":"318"},{"label":"Шлюха","value":"32"},{"label":"Шоу-бизнес","value":"329"},{"label":"Шоу-бизнес","value":"172"},{"label":"Эксгибиционизм","value":"74"},{"label":"Элементы бдсм","value":"185"},{"label":"Эмма уотсон","value":"342"},{"label":"Эмма Уотсон","value":"169"},{"label":"Эротика","value":"36"},{"label":"Этти","value":"327"},{"label":"Юмор","value":"105"},{"label":"Яндере","value":"155"},{"label":"Bl","value":"125"},{"label":"Dc","value":"411"},{"label":"Gl","value":"96"},{"label":"Harry potter","value":"190"},{"label":"Harry potter","value":"168"},{"label":"Hentai","value":"282"},{"label":"Marvel","value":"194"},{"label":"Marvel","value":"174"},{"label":"Milf","value":"167"},{"label":"Mj","value":"401"}],"inputType":FilterInputs.Checkbox},{"key":"fandoms_ex","label":"Исключить фэндомы:","values":[{"label":"Аватар: Легенда о Корре / Avatar legend of Korra","value":"46"},{"label":"Аватар: Легенда об Аанге / Avatar: The Legend of Aang / Avatar: The Last Airbender","value":"45"},{"label":"Аладдин / Aladdin","value":"86"},{"label":"Алиса в Стране чудес / Alice in Wonderland","value":"90"},{"label":"Американский папаша / American Dad","value":"85"},{"label":"Атака титанов / Атака на титанов / Attack on Titan","value":"41"},{"label":"Блич / Bleach","value":"58"},{"label":"Боевой континент","value":"101"},{"label":"Большой куш / One Piece","value":"18"},{"label":"Боруто: Новое поколение Наруто / Boruto: Naruto Next Generations","value":"9"},{"label":"Бэтмен / The Batman","value":"36"},{"label":"Ведьмак / The Witcher","value":"53"},{"label":"Военная хроника маленькой девочки","value":"100"},{"label":"Волейбол / Haikyu!!","value":"37"},{"label":"Вселенная Марвел / Marvel Universe","value":"7"},{"label":"Вселенная Марвел / Marvel Universe / Marvel Comics","value":"52"},{"label":"Вселенная Стивена","value":"61"},{"label":"Вселенная DC / DC Universe / DC Comics","value":"48"},{"label":"Гарри Поттер / Harry Potter","value":"4"},{"label":"Гоэтия / Гоетия / Yοητεία / Ars Goetia","value":"77"},{"label":"Демоны старшей школы / High School DxD","value":"10"},{"label":"День сурка / Groundhog Day","value":"3"},{"label":"Джессика Джонс / Marvel's Jessica Jones","value":"42"},{"label":"Дисней / The Walt Disney Company","value":"74"},{"label":"Древние свитки: Скайрим / TES: Skyrim","value":"15"},{"label":"Дэдпул / Deadpool","value":"22"},{"label":"Дэнни-призрак / Danny Phantom","value":"51"},{"label":"Железный человек / Iron Man","value":"19"},{"label":"Звёздная принцесса и силы зла / Стар против сил зла / Star vs. The Forces of Evil","value":"50"},{"label":"Звездные Войны / Star Wars","value":"43"},{"label":"Звёздные Войны / Star Wars","value":"16"},{"label":"Игра престолов","value":"78"},{"label":"Касльвания / Castlevania","value":"29"},{"label":"Киберпанк 2077 / Cyberpunk 2077","value":"6"},{"label":"Код Гиас / Code Geass","value":"84"},{"label":"Кольцо Элдена","value":"60"},{"label":"Королевства Сердец / Kingdom Hearts","value":"93"},{"label":"Красавица и чудовище / Beauty and the Beast","value":"91"},{"label":"Красный, Белый, Черный, Желтый / RWBY","value":"32"},{"label":"Кунг фу панда","value":"81"},{"label":"Лига Легенд / League of Legends","value":"5"},{"label":"Люди Икс / X-Men","value":"25"},{"label":"Маг на полную ставку / Quanzhi Fashi","value":"30"},{"label":"Мастера меча онлайн / Sword Art Online / SAO","value":"47"},{"label":"Мир Тьмы / World of Darkness","value":"28"},{"label":"Мой маленький пони / My Little Pony","value":"72"},{"label":"Мой маленький пони: Дружба — это чудо / My Little Pony: Friendship is Magic","value":"71"},{"label":"Моя геройская академия / Boku no Hero Academia","value":"8"},{"label":"Мстители / The Avengers","value":"20"},{"label":"Мстители. Эра Альтрона / The Avengers. Age of Ultron","value":"24"},{"label":"Мулан / Mulan","value":"94"},{"label":"Наруто / Naruto","value":"2"},{"label":"Овервотч","value":"79"},{"label":"Поднятие уровня в одиночку","value":"87"},{"label":"Порновселенная / Porn Universe","value":"31"},{"label":"Прототип / Prototype","value":"44"},{"label":"Рапунцель: Запутанная история / Tangled","value":"96"},{"label":"Розовая пора моей школьной жизни сплошной обман / Yahari Ore no Seishun Love Come wa Machigatteiru","value":"14"},{"label":"Русалочка / The Little Mermaid","value":"97"},{"label":"Сага о Винланде","value":"66"},{"label":"Светлячок / Firefly","value":"76"},{"label":"Сильнейший в истории ученик Кэнити / Shijou Saikyou no Deshi Kenichi","value":"13"},{"label":"Симпсоны / The Simpsons","value":"73"},{"label":"Судьба: Великий Приказ / Fate: Grand Order","value":"54"},{"label":"Супергёрл(телесериал, 2015) / Supergirl","value":"95"},{"label":"Супермен / Superman","value":"1"},{"label":"Теория большого взрыва / The Big Bang Theory","value":"75"},{"label":"Тор / Thor","value":"27"},{"label":"У Коми-сан проблемы с общением / 古見さんは、コミュ症です / Komi Can't Communicate","value":"11"},{"label":"Убийца Акаме / Akame ga Kill","value":"40"},{"label":"Уэнздей / Wednesday","value":"26"},{"label":"Фантастическая четвёрка / Fantastic Four","value":"21"},{"label":"Флэш / The Flash","value":"17"},{"label":"Хвост Феи / Fairy Tail","value":"59"},{"label":"Холодное сердце / Frozen","value":"92"},{"label":"Человек одного удара / Ванпанчмен / One Punch-Man","value":"39"},{"label":"Человек-паук / Spider-Man","value":"23"},{"label":"Чёрный зверь / Чёрный Пёс / Kuroinu","value":"35"},{"label":"Чёрный зверь: Развращение Благородных Воительниц / Black Beast: Corruption of the Noble Warriors","value":"34"},{"label":"Школа мертвецов","value":"67"},{"label":"Школа строгого режима / Prison School","value":"12"},{"label":"Эффект Массы / Mass Effect","value":"57"},{"label":"Юные Титаны / Teen Titans","value":"49"},{"label":"Ars Goetia | Gods and Demons","value":"69"},{"label":"Biohazard","value":"99"},{"label":"CL","value":"70"},{"label":"Daraku Reijou Hakoiri Ojou-sama Netorare Choukyou Kiroku","value":"55"},{"label":"Doom","value":"64"},{"label":"Granblue fantasy","value":"88"},{"label":"Halo","value":"80"},{"label":"Highschool of the Dead/Школа мертвецов","value":"68"},{"label":"JK Bitch ni Shiboraretai","value":"56"},{"label":"Monogatari Series","value":"65"},{"label":"Monster girl quest","value":"62"},{"label":"Over","value":"102"},{"label":"Rapunzel/Рапунцель","value":"83"},{"label":"Resident Evil","value":"98"},{"label":"Solo leveling","value":"63"},{"label":"Tentacle Locker","value":"89"},{"label":"X-COM","value":"82"}],"inputType":FilterInputs.Checkbox},{"key":"atmosphere","label":"Атмосфера:","values":[{"label":"Неважно","value":"0"},{"label":"Позитивная","value":"1"},{"label":"Dark","value":"2"}],"inputType":FilterInputs.Picker},{"key":"adult","label":"Возрастные ограничения:","values":[{"label":"Все","value":"0"},{"label":"Только 18+","value":"2"},{"label":"Убрать 18+","value":"1"}],"inputType":FilterInputs.Picker}]; \ No newline at end of file diff --git a/plugins/russian/LitSpace.ts b/plugins/russian/LitSpace.broken.ts similarity index 100% rename from plugins/russian/LitSpace.ts rename to plugins/russian/LitSpace.broken.ts diff --git a/plugins/russian/Rulate[rulate].ts b/plugins/russian/Rulate[rulate].ts deleted file mode 100644 index 8e88c19..0000000 --- a/plugins/russian/Rulate[rulate].ts +++ /dev/null @@ -1,226 +0,0 @@ - -import { load as parseHTML } from "cheerio"; -// import dayjs from 'dayjs'; -import { fetchFile, fetchApi } from "@libs/fetch"; -import { Novel, Plugin, Chapter } from "@typings/plugin"; -// import { parseMadaraDate } from "@libs/parseMadaraDate"; -// import { isUrlAbsolute } from '@libs/isAbsoluteUrl'; -// import { showToast } from "@libs/showToast"; -import { FilterInputs } from "@libs/filterInputs"; -import { NovelStatus } from '@libs/novelStatus'; -// import { defaultCover } from "@libs/defaultCover"; - -export const id = "tl.rulate"; -export const name = "Rulate"; -export const icon = "multisrc/rulate/icons/rulate.png"; -export const version = "1.0.0"; -export const site = "https://tl.rulate.ru"; - -export const popularNovels: Plugin.popularNovels = async function ( - page, - { filters, showLatestNovels } -) { - let url = site + '/search?t='; - url += '&cat=' + (filters?.cat || '0'); - url += '&s_lang=' + (filters?.s_lang || '0'); - url += '&t_lang=' + (filters?.t_lang || '0'); - url += '&type=' + (filters?.type || '0'); - url += '&sort=' + (showLatestNovels ? '4' : (filters?.sort || '6')); - url += '&atmosphere=' + (filters?.atmosphere || '0'); - url += '&adult=' + (filters?.adult || '0'); - - if (filters?.genres instanceof Array) { - url += filters.genres.map(i => '&genres[]=' + i).join(''); - } - - if (filters?.genres_ex instanceof Array) { - url += filters.genres_ex.map(i => '&genres_ex[]=' + i).join(''); - } - - if (filters?.tags instanceof Array) { - url += filters.tags.map(i => '&tags[]=' + i).join(''); - } - - if (filters?.tags_ex instanceof Array) { - url += filters.tags_ex.map(i => '&tags_ex[]=' + i).join(''); - } - - if (filters?.fandoms instanceof Array) { - url += filters.fandoms.map(i => '&fandoms[]=' + i).join(''); - } - - if (filters?.fandoms_ex instanceof Array) { - url += filters.fandoms_ex.map(i => '&fandoms_ex[]=' + i).join(''); - } - - if (filters?.trash instanceof Array) { - url += filters.trash.map(i => '&' + i + '=1').join(''); - } - - url += '&Book_page=' + page; - - const result = await fetchApi(url); - const body = await result.text(); - const loadedCheerio = parseHTML(body); - - const novels: Novel.Item[] = []; - - loadedCheerio( - 'ul[class="search-results"] > li:not([class="ad_type_catalog"])', - ).each(function () { - novels.push({ - name: loadedCheerio(this).find('p > a').text(), - cover: site + loadedCheerio(this).find('img').attr('src'), - url: site + loadedCheerio(this).find('p > a').attr('href') || '', - }); - }); - - return novels; -}; - - -export const parseNovelAndChapters: Plugin.parseNovelAndChapters = - async function (novelUrl) { - const novel: Novel.instance = { - url: novelUrl, - chapters: [], - }; - let result = await fetchApi(novelUrl); - if (result.url.includes('mature?path=')) { - const formData = new FormData(); - formData.append('path', novelUrl); - formData.append('ok', 'Да'); - - await fetchApi(result.url, { - method: 'POST', - body: formData, - }); - - result = await fetchApi(novelUrl); - } - const body = await result.text(); - const loadedCheerio = parseHTML(body); - - novel.name = loadedCheerio('div[class="container"] > div > div > h1, div.span8:nth-child(1) > h1:nth-child(2)') - .text() - .trim(); - novel.cover = - site + loadedCheerio('div[class="images"] > div img').attr('src'); - novel.summary = loadedCheerio('#Info > div:nth-child(3), .book-description').text(); - novel.author = loadedCheerio('.book-stats-icons_author > span:nth-child(2) > a:nth-child(1)').text() - let genres: string[] = []; - - loadedCheerio('div.span5 > p, .span5 > div:nth-child(2) > p').each(function () { - switch (loadedCheerio(this).find('strong').text()) { - case 'Автор:': - novel.author = loadedCheerio(this).find('em > a').text().trim(); - break; - case 'Выпуск:': - novel.status = - loadedCheerio(this).find('em').text().trim() === 'продолжается' - ? NovelStatus.Ongoing - : NovelStatus.Completed; - break; - case 'Тэги:': - loadedCheerio(this) - .find('em > a') - .each(function () { - genres.push(loadedCheerio(this).text()); - }); - break; - case 'Жанры:': - loadedCheerio(this) - .find('em > a') - .each(function () { - genres.push(loadedCheerio(this).text()); - }); - break; - } - }); - - if (genres.length > 0) { - novel.genres = genres.reverse().join(','); - } - - const chapters: Chapter.Item[] = []; - loadedCheerio('table > tbody > tr.chapter_row').each(function () { - const chapterName = loadedCheerio(this) - .find('td[class="t"] > a') - .text() - .trim(); - const releaseDate = loadedCheerio(this) - .find('td > span') - .attr('title') - ?.trim(); - const chapterUrl = site + loadedCheerio(this) - .find('td[class="t"] > a') - .attr('href'); - - if ( - loadedCheerio(this).find('td > span[class="disabled"]').length < 1 && - releaseDate - ) { - chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); - } - }); - - novel.chapters = chapters; - return novel; - }; - -export const parseChapter: Plugin.parseChapter = async function (chapterUrl) { - let result = await fetchApi(chapterUrl); - if (result.url.includes('mature?path=')) { - const formData = new FormData(); - formData.append('ok', 'Да'); - - await fetchApi(result.url, { - method: 'POST', - body: formData, - }); - - result = await fetchApi(chapterUrl); - } - const body = await result.text(); - const loadedCheerio = parseHTML(body); - - loadedCheerio('.content-text img').each(function () { - if (!loadedCheerio(this).attr('src')?.startsWith('http')) { - const src = loadedCheerio(this).attr('src'); - loadedCheerio(this).attr('src', site + src); - } - }); - - const chapterText = loadedCheerio('.content-text').html(); - return chapterText; -}; - -export const searchNovels: Plugin.searchNovels = async (searchTerm) => { - const novels: Novel.Item[] = []; - const result = await fetchApi( - site + '/search/autocomplete?query=' + searchTerm, - ); - let json = await result.json() as response[]; - - json.forEach((item) => { - const novelName = item.title_one + ' / ' + item.title_two; - const novelCover = site + item.img; - const novelUrl = site + item.url; - - novels.push({ name: novelName, cover: novelCover, url: novelUrl }); - }); - - return novels; -}; - -interface response { - id: number; - title_one: string; - title_two: string; - url: string; - img: string; -}; - -export const fetchImage: Plugin.fetchImage = fetchFile; - -export const filters = [{"key":"cat","label":"Из раздела каталога:","values":[{"label":"Неважно","value":"0"},{"label":"Авторские","value":"18"},{"label":"Авторские","value":"35"},{"label":"Авторские фанфики","value":"51"},{"label":"Английские","value":"28"},{"label":"Английские","value":"34"},{"label":"Английские","value":"48"},{"label":"Аниме","value":"20"},{"label":"Аудиокниги","value":"25"},{"label":"Блич","value":"42"},{"label":"Большие игры","value":"22"},{"label":"Ван-Пис","value":"41"},{"label":"Визуальные новеллы","value":"8"},{"label":"Вьетнамские","value":"39"},{"label":"Вьетнамские","value":"49"},{"label":"Игры","value":"3"},{"label":"Китайские","value":"5"},{"label":"Китайские","value":"31"},{"label":"Китайские","value":"45"},{"label":"Книги","value":"2"},{"label":"Книги","value":"14"},{"label":"Комиксы","value":"29"},{"label":"Корейские","value":"7"},{"label":"Корейские","value":"33"},{"label":"Корейские","value":"47"},{"label":"Маленькие игры","value":"23"},{"label":"Манга","value":"16"},{"label":"Манга","value":"30"},{"label":"Марвел","value":"43"},{"label":"Машинный перевод","value":"44"},{"label":"Наруто","value":"40"},{"label":"Новеллы и ранобэ","value":"12"},{"label":"Переводы фанфиков","value":"19"},{"label":"Психология","value":"37"},{"label":"Путешествия","value":"36"},{"label":"Статьи","value":"13"},{"label":"Субтитры","value":"15"},{"label":"Фильмы","value":"21"},{"label":"Японские","value":"6"},{"label":"Японские","value":"32"},{"label":"Японские","value":"46"}],"inputType":FilterInputs.Picker},{"key":"s_lang","label":"Язык оригинала:","values":[{"label":"Неважно","value":"0"},{"label":"Абхазский","value":"20"},{"label":"Аварский","value":"21"},{"label":"Азербайджанский","value":"22"},{"label":"Аймара","value":"23"},{"label":"Акан","value":"24"},{"label":"Албанский","value":"25"},{"label":"Амхарский","value":"26"},{"label":"Английский","value":"2"},{"label":"Арабский","value":"27"},{"label":"Арагонский","value":"28"},{"label":"Арберешский","value":"29"},{"label":"Армянский","value":"30"},{"label":"Ассамский","value":"31"},{"label":"Астурийский","value":"32"},{"label":"Афарский","value":"33"},{"label":"Африкаанс","value":"34"},{"label":"Ацтекский","value":"35"},{"label":"Баварский","value":"36"},{"label":"Бамбарийский","value":"37"},{"label":"Баскский","value":"39"},{"label":"Башкирский","value":"40"},{"label":"Белорусский","value":"10"},{"label":"Бенгальский","value":"41"},{"label":"Бирманский","value":"42"},{"label":"Бислама","value":"43"},{"label":"Бихари","value":"44"},{"label":"Болгарский","value":"45"},{"label":"Боснийский","value":"234"},{"label":"Бретонский","value":"47"},{"label":"Валенсийский","value":"48"},{"label":"Валлийский","value":"49"},{"label":"Валлонский","value":"50"},{"label":"Венгерский","value":"51"},{"label":"Венда","value":"52"},{"label":"Венетский","value":"53"},{"label":"Верхнелужицкий","value":"54"},{"label":"Волоф","value":"55"},{"label":"Вьетнамский","value":"57"},{"label":"Гавайский","value":"58"},{"label":"Гаитянский","value":"59"},{"label":"Галисийский","value":"60"},{"label":"Гереро","value":"61"},{"label":"Голландский","value":"62"},{"label":"Греческий","value":"63"},{"label":"Грузинский","value":"64"},{"label":"Гуарани","value":"65"},{"label":"Гуджарати","value":"66"},{"label":"Датский","value":"19"},{"label":"Дзонг-кэ","value":"68"},{"label":"Древнегреческий","value":"69"},{"label":"Западно-фламандский","value":"70"},{"label":"Зулу","value":"71"},{"label":"Иврит","value":"15"},{"label":"Игбо","value":"72"},{"label":"Идиш","value":"73"},{"label":"Илоко","value":"74"},{"label":"Индонезийский","value":"75"},{"label":"Интерлингва","value":"76"},{"label":"Инуктитут","value":"77"},{"label":"Инупиак","value":"78"},{"label":"Ирландский","value":"79"},{"label":"Исландский","value":"80"},{"label":"Испанский","value":"6"},{"label":"Итальянский","value":"5"},{"label":"Йоруба","value":"81"},{"label":"Кабильский","value":"82"},{"label":"Казахский","value":"83"},{"label":"Калмыцкий","value":"235"},{"label":"Каннада","value":"84"},{"label":"Кантонский юэ","value":"85"},{"label":"Канури","value":"86"},{"label":"Каталанский","value":"87"},{"label":"Кашмири","value":"88"},{"label":"Кечуа","value":"90"},{"label":"Кикуйю","value":"91"},{"label":"Киньяруанда","value":"92"},{"label":"Киргизский","value":"93"},{"label":"Китайский","value":"7"},{"label":"Клингонский","value":"94"},{"label":"Коми","value":"95"},{"label":"Конго","value":"96"},{"label":"Конкани","value":"97"},{"label":"Корейский","value":"98"},{"label":"Корсиканский","value":"100"},{"label":"Котава","value":"101"},{"label":"Кри","value":"102"},{"label":"Курдский","value":"105"},{"label":"Кхмерский","value":"107"},{"label":"Лакский","value":"233"},{"label":"Лаосский","value":"109"},{"label":"Латынь","value":"110"},{"label":"Латышский","value":"111"},{"label":"Лезгинский","value":"112"},{"label":"Лимбургский","value":"113"},{"label":"Лингала","value":"114"},{"label":"Литовский","value":"115"},{"label":"Луба","value":"118"},{"label":"Луганда","value":"119"},{"label":"Люксембургский","value":"120"},{"label":"Македонский","value":"121"},{"label":"Малагасийский","value":"122"},{"label":"Малайский","value":"123"},{"label":"Мальдивский","value":"125"},{"label":"Мальтийский","value":"126"},{"label":"Маори","value":"127"},{"label":"Марийский","value":"232"},{"label":"Маршалльский","value":"130"},{"label":"Молдавский","value":"11"},{"label":"Монгольский","value":"133"},{"label":"Мяо (хмонг)","value":"209"},{"label":"Навахо","value":"135"},{"label":"Неаполитанский","value":"139"},{"label":"Немецкий","value":"3"},{"label":"Непальский","value":"140"},{"label":"Норвежский","value":"18"},{"label":"Осетинский","value":"147"},{"label":"Пакистанский","value":"230"},{"label":"Пенджабский","value":"149"},{"label":"Персидский","value":"151"},{"label":"Польский","value":"152"},{"label":"Португальский","value":"153"},{"label":"Румынский","value":"158"},{"label":"Русский","value":"1"},{"label":"Санскрит","value":"163"},{"label":"Сардинский","value":"164"},{"label":"Сербохорватский","value":"166"},{"label":"Словацкий","value":"170"},{"label":"Словенский","value":"171"},{"label":"Сомали","value":"172"},{"label":"Старотурецкий","value":"174"},{"label":"Суахили","value":"175"},{"label":"Сунданский","value":"176"},{"label":"Тагальский","value":"177"},{"label":"Таджикский","value":"178"},{"label":"Таитянский","value":"179"},{"label":"Тайваньский","value":"180"},{"label":"Тайский","value":"181"},{"label":"Тамильский","value":"182"},{"label":"Татарский","value":"12"},{"label":"Телугу","value":"184"},{"label":"Тибетский","value":"185"},{"label":"Тигринья","value":"186"},{"label":"Ток-писин","value":"187"},{"label":"Токи пона","value":"188"},{"label":"Тонганский","value":"189"},{"label":"Тсвана","value":"191"},{"label":"Тсонга","value":"192"},{"label":"Турецкий","value":"193"},{"label":"Туркменский","value":"194"},{"label":"Удмуртский","value":"196"},{"label":"Узбекский","value":"197"},{"label":"Уйгурский","value":"198"},{"label":"Украинский","value":"9"},{"label":"Фиджийский","value":"201"},{"label":"Филиппинский","value":"229"},{"label":"Финский","value":"17"},{"label":"Французский","value":"4"},{"label":"Фризский","value":"203"},{"label":"Фулах","value":"204"},{"label":"Хауса","value":"206"},{"label":"Хинди","value":"207"},{"label":"Хири-моту","value":"208"},{"label":"Чеченский","value":"213"},{"label":"Чешский","value":"13"},{"label":"Чувашский","value":"217"},{"label":"Шведский","value":"16"},{"label":"Швейцарский немецкий","value":"218"},{"label":"Шона","value":"219"},{"label":"Шотландский","value":"67"},{"label":"Эве","value":"221"},{"label":"Эскимосский","value":"223"},{"label":"Эсперанто","value":"14"},{"label":"Эстонский","value":"224"},{"label":"Южно-корейский","value":"231"},{"label":"Юкатекский","value":"225"},{"label":"Яванский","value":"227"},{"label":"Японский","value":"8"}],"inputType":FilterInputs.Picker},{"key":"t_lang","label":"Язык перевода:","values":[{"label":"Неважно","value":"0"},{"label":"Абхазский","value":"20"},{"label":"Аварский","value":"21"},{"label":"Азербайджанский","value":"22"},{"label":"Аймара","value":"23"},{"label":"Акан","value":"24"},{"label":"Албанский","value":"25"},{"label":"Амхарский","value":"26"},{"label":"Английский","value":"2"},{"label":"Арабский","value":"27"},{"label":"Арагонский","value":"28"},{"label":"Арберешский","value":"29"},{"label":"Армянский","value":"30"},{"label":"Ассамский","value":"31"},{"label":"Астурийский","value":"32"},{"label":"Афарский","value":"33"},{"label":"Африкаанс","value":"34"},{"label":"Ацтекский","value":"35"},{"label":"Баварский","value":"36"},{"label":"Бамбарийский","value":"37"},{"label":"Баскский","value":"39"},{"label":"Башкирский","value":"40"},{"label":"Белорусский","value":"10"},{"label":"Бенгальский","value":"41"},{"label":"Бирманский","value":"42"},{"label":"Бислама","value":"43"},{"label":"Бихари","value":"44"},{"label":"Болгарский","value":"45"},{"label":"Боснийский","value":"234"},{"label":"Бретонский","value":"47"},{"label":"Валенсийский","value":"48"},{"label":"Валлийский","value":"49"},{"label":"Валлонский","value":"50"},{"label":"Венгерский","value":"51"},{"label":"Венда","value":"52"},{"label":"Венетский","value":"53"},{"label":"Верхнелужицкий","value":"54"},{"label":"Волоф","value":"55"},{"label":"Вьетнамский","value":"57"},{"label":"Гавайский","value":"58"},{"label":"Гаитянский","value":"59"},{"label":"Галисийский","value":"60"},{"label":"Гереро","value":"61"},{"label":"Голландский","value":"62"},{"label":"Греческий","value":"63"},{"label":"Грузинский","value":"64"},{"label":"Гуарани","value":"65"},{"label":"Гуджарати","value":"66"},{"label":"Датский","value":"19"},{"label":"Дзонг-кэ","value":"68"},{"label":"Древнегреческий","value":"69"},{"label":"Западно-фламандский","value":"70"},{"label":"Зулу","value":"71"},{"label":"Иврит","value":"15"},{"label":"Игбо","value":"72"},{"label":"Идиш","value":"73"},{"label":"Илоко","value":"74"},{"label":"Индонезийский","value":"75"},{"label":"Интерлингва","value":"76"},{"label":"Инуктитут","value":"77"},{"label":"Инупиак","value":"78"},{"label":"Ирландский","value":"79"},{"label":"Исландский","value":"80"},{"label":"Испанский","value":"6"},{"label":"Итальянский","value":"5"},{"label":"Йоруба","value":"81"},{"label":"Кабильский","value":"82"},{"label":"Казахский","value":"83"},{"label":"Калмыцкий","value":"235"},{"label":"Каннада","value":"84"},{"label":"Кантонский юэ","value":"85"},{"label":"Канури","value":"86"},{"label":"Каталанский","value":"87"},{"label":"Кашмири","value":"88"},{"label":"Кечуа","value":"90"},{"label":"Кикуйю","value":"91"},{"label":"Киньяруанда","value":"92"},{"label":"Киргизский","value":"93"},{"label":"Китайский","value":"7"},{"label":"Клингонский","value":"94"},{"label":"Коми","value":"95"},{"label":"Конго","value":"96"},{"label":"Конкани","value":"97"},{"label":"Корейский","value":"98"},{"label":"Корсиканский","value":"100"},{"label":"Котава","value":"101"},{"label":"Кри","value":"102"},{"label":"Курдский","value":"105"},{"label":"Кхмерский","value":"107"},{"label":"Лакский","value":"233"},{"label":"Лаосский","value":"109"},{"label":"Латынь","value":"110"},{"label":"Латышский","value":"111"},{"label":"Лезгинский","value":"112"},{"label":"Лимбургский","value":"113"},{"label":"Лингала","value":"114"},{"label":"Литовский","value":"115"},{"label":"Луба","value":"118"},{"label":"Луганда","value":"119"},{"label":"Люксембургский","value":"120"},{"label":"Македонский","value":"121"},{"label":"Малагасийский","value":"122"},{"label":"Малайский","value":"123"},{"label":"Мальдивский","value":"125"},{"label":"Мальтийский","value":"126"},{"label":"Маори","value":"127"},{"label":"Марийский","value":"232"},{"label":"Маршалльский","value":"130"},{"label":"Молдавский","value":"11"},{"label":"Монгольский","value":"133"},{"label":"Мяо (хмонг)","value":"209"},{"label":"Навахо","value":"135"},{"label":"Неаполитанский","value":"139"},{"label":"Немецкий","value":"3"},{"label":"Непальский","value":"140"},{"label":"Норвежский","value":"18"},{"label":"Осетинский","value":"147"},{"label":"Пакистанский","value":"230"},{"label":"Пенджабский","value":"149"},{"label":"Персидский","value":"151"},{"label":"Польский","value":"152"},{"label":"Португальский","value":"153"},{"label":"Румынский","value":"158"},{"label":"Русский","value":"1"},{"label":"Санскрит","value":"163"},{"label":"Сардинский","value":"164"},{"label":"Сербохорватский","value":"166"},{"label":"Словацкий","value":"170"},{"label":"Словенский","value":"171"},{"label":"Сомали","value":"172"},{"label":"Старотурецкий","value":"174"},{"label":"Суахили","value":"175"},{"label":"Сунданский","value":"176"},{"label":"Тагальский","value":"177"},{"label":"Таджикский","value":"178"},{"label":"Таитянский","value":"179"},{"label":"Тайваньский","value":"180"},{"label":"Тайский","value":"181"},{"label":"Тамильский","value":"182"},{"label":"Татарский","value":"12"},{"label":"Телугу","value":"184"},{"label":"Тибетский","value":"185"},{"label":"Тигринья","value":"186"},{"label":"Ток-писин","value":"187"},{"label":"Токи пона","value":"188"},{"label":"Тонганский","value":"189"},{"label":"Тсвана","value":"191"},{"label":"Тсонга","value":"192"},{"label":"Турецкий","value":"193"},{"label":"Туркменский","value":"194"},{"label":"Удмуртский","value":"196"},{"label":"Узбекский","value":"197"},{"label":"Уйгурский","value":"198"},{"label":"Украинский","value":"9"},{"label":"Фиджийский","value":"201"},{"label":"Филиппинский","value":"229"},{"label":"Финский","value":"17"},{"label":"Французский","value":"4"},{"label":"Фризский","value":"203"},{"label":"Фулах","value":"204"},{"label":"Хауса","value":"206"},{"label":"Хинди","value":"207"},{"label":"Хири-моту","value":"208"},{"label":"Чеченский","value":"213"},{"label":"Чешский","value":"13"},{"label":"Чувашский","value":"217"},{"label":"Шведский","value":"16"},{"label":"Швейцарский немецкий","value":"218"},{"label":"Шона","value":"219"},{"label":"Шотландский","value":"67"},{"label":"Эве","value":"221"},{"label":"Эскимосский","value":"223"},{"label":"Эсперанто","value":"14"},{"label":"Эстонский","value":"224"},{"label":"Южно-корейский","value":"231"},{"label":"Юкатекский","value":"225"},{"label":"Яванский","value":"227"},{"label":"Японский","value":"8"}],"inputType":FilterInputs.Picker},{"key":"type","label":"Тип:","values":[{"label":"Неважно","value":"0"},{"label":"Только авторские","value":"2"},{"label":"Только переводы","value":"1"}],"inputType":FilterInputs.Picker},{"key":"trash","label":"Другое:","values":[{"label":"Без фэндомов","value":"fandoms_ex_all"},{"label":"Готовые на 100%","value":"ready"},{"label":"Доступные для перевода","value":"tr"},{"label":"Доступные для скачивания","value":"gen"},{"label":"Завершённые проекты","value":"wealth"},{"label":"Распродажа","value":"discount"},{"label":"Только онгоинги","value":"ongoings"},{"label":"Убрать машинный","value":"remove_machinelate"}],"inputType":FilterInputs.Checkbox},{"key":"sort","label":"Сортировка:","values":[{"label":"По рейтингу","value":"6"},{"label":"По дате последней активности","value":"4"},{"label":"По дате создания","value":"3"},{"label":"По кол-ву бесплатных глав","value":"11"},{"label":"По кол-ву в закладках","value":"13"},{"label":"По кол-ву в избранном","value":"14"},{"label":"По кол-ву лайков","value":"8"},{"label":"По кол-ву переведённых глав","value":"7"},{"label":"По кол-ву рецензий","value":"12"},{"label":"По кол-ву страниц","value":"10"},{"label":"По названию на языке оригинала","value":"1"},{"label":"По названию на языке перевода","value":"2"},{"label":"По просмотрам","value":"5"},{"label":"По степени готовности","value":"0"},{"label":"Случайно","value":"9"}],"inputType":FilterInputs.Picker},{"key":"genres","label":"Жанры:","values":[{"label":"18+","value":"52"},{"label":"Арт","value":"1"},{"label":"Боевик","value":"2"},{"label":"Боевые искусства","value":"3"},{"label":"Гаремник","value":"5"},{"label":"Героическое фэнтези","value":"7"},{"label":"Детектив","value":"8"},{"label":"Дзёсэй","value":"9"},{"label":"Додзинси","value":"10"},{"label":"Драма","value":"11"},{"label":"История","value":"13"},{"label":"Киберпанк","value":"46"},{"label":"Кодомо","value":"14"},{"label":"Комедия","value":"15"},{"label":"Литрпг","value":"48"},{"label":"Махо-сёдзё","value":"16"},{"label":"Мелодрама","value":"49"},{"label":"Меха","value":"17"},{"label":"Мистика","value":"18"},{"label":"Научная фантастика","value":"19"},{"label":"Повседневность","value":"20"},{"label":"Постапокалиптика","value":"21"},{"label":"Приключения","value":"22"},{"label":"Психология","value":"23"},{"label":"Романтика","value":"24"},{"label":"Самурайский боевик","value":"25"},{"label":"Сверхъестественное","value":"26"},{"label":"Сёдзё","value":"27"},{"label":"Сёнэн","value":"29"},{"label":"Смат","value":"45"},{"label":"Спорт","value":"31"},{"label":"Сэйнэн","value":"32"},{"label":"Сюаньхуа","value":"44"},{"label":"Сюаньхуань","value":"47"},{"label":"Сянься (XianXia)","value":"42"},{"label":"Трагедия","value":"33"},{"label":"Триллер","value":"34"},{"label":"Ужасы","value":"35"},{"label":"Уся (wuxia)","value":"41"},{"label":"Фантастика","value":"36"},{"label":"Фанфик","value":"50"},{"label":"Фэнтези","value":"37"},{"label":"Школа","value":"38"},{"label":"Этти","value":"39"},{"label":"Bl","value":"43"},{"label":"Gl","value":"40"}],"inputType":FilterInputs.Checkbox},{"key":"tags","label":"Тэги:","values":[{"label":"12+","value":"3316"},{"label":"16+","value":"83"},{"label":"Абсурд","value":"7973"},{"label":"Авантюристы","value":"222"},{"label":"Автомат","value":"5272"},{"label":"Авторский мир","value":"1062"},{"label":"Агрессивные персонажи","value":"3249"},{"label":"Ад","value":"2623"},{"label":"Ад и рай","value":"817"},{"label":"Адам дженсен","value":"1649"},{"label":"Адаптация произведения","value":"192"},{"label":"Адвокат","value":"6340"},{"label":"Адекватные главные герои","value":"1953"},{"label":"Азартные игры","value":"5301"},{"label":"Азгард","value":"3494"},{"label":"Азула","value":"5550"},{"label":"Аид","value":"7641"},{"label":"Айдолы","value":"4081"},{"label":"Академия","value":"316"},{"label":"Акамэ","value":"5059"},{"label":"Аквакинез","value":"5952"},{"label":"Акира","value":"2639"},{"label":"Акнология","value":"4634"},{"label":"Актерское мастерство","value":"4798"},{"label":"Актёры","value":"7506"},{"label":"Активные герои","value":"6376"},{"label":"Акутагава рюноске","value":"4113"},{"label":"Аладдин","value":"6489"},{"label":"Алая ведьма","value":"4767"},{"label":"Алиса","value":"4761"},{"label":"Алкоголь","value":"5508"},{"label":"Аллегория","value":"271"},{"label":"Алукард","value":"4914"},{"label":"Алхимики","value":"1164"},{"label":"Алхимия","value":"1473"},{"label":"Алчность","value":"6897"},{"label":"Альбус дамблдор","value":"5784"},{"label":"Альтернативное развитие событий","value":"5330"},{"label":"Альянсы","value":"328"},{"label":"Амбициозный главный герой","value":"3751"},{"label":"Америка","value":"4082"},{"label":"Амнезия","value":"2207"},{"label":"Аморальный герой","value":"18"},{"label":"Анбу","value":"8129"},{"label":"Ангелы","value":"857"},{"label":"Ангелы и демоны","value":"1327"},{"label":"Ангст","value":"4638"},{"label":"Андроиды","value":"1993"},{"label":"Анимализм","value":"5249"},{"label":"Аниме","value":"1294"},{"label":"Анко митараши","value":"5768"},{"label":"Антагонист","value":"2144"},{"label":"Антигерой","value":"7725"},{"label":"Антиквариат","value":"3552"},{"label":"Антимаг","value":"1348"},{"label":"Антиутопия","value":"662"},{"label":"Апокалипсис","value":"1498"},{"label":"Аристократия","value":"371"},{"label":"Аристократы","value":"7338"},{"label":"Армия","value":"1723"},{"label":"Артас","value":"6700"},{"label":"Артефакты","value":"2296"},{"label":"Археология","value":"6523"},{"label":"Асгард","value":"3635"},{"label":"Ассасин","value":"1415"},{"label":"Асуна","value":"5044"},{"label":"Аугментации","value":"7751"},{"label":"Ацуши накаджима","value":"4109"},{"label":"Аянокоджи киетака","value":"6862"},{"label":"Бандиты","value":"2188"},{"label":"Басейн","value":"6847"},{"label":"Баскетбол","value":"7933"},{"label":"Бастарды","value":"76"},{"label":"Бедность","value":"1207"},{"label":"Без культивации","value":"668"},{"label":"Без любовной линий","value":"2225"},{"label":"Без перерождений","value":"262"},{"label":"Без попаданца","value":"8065"},{"label":"Без системы","value":"747"},{"label":"Без юмора","value":"763"},{"label":"Бездна","value":"1026"},{"label":"Безжалостное домашнее животное","value":"1245"},{"label":"Безжалостные персонажи","value":"2986"},{"label":"Беззаботные персонажи","value":"3123"},{"label":"Безответная любовь","value":"7815"},{"label":"Безработный","value":"2202"},{"label":"Безумие","value":"37"},{"label":"Безумные персонажи","value":"2049"},{"label":"Бейсбол","value":"7623"},{"label":"Беременность","value":"2122"},{"label":"Бесконечный поток","value":"7556"},{"label":"Беспечные персонажи","value":"742"},{"label":"Бесплатно","value":"8403"},{"label":"Бессмертные персонажи","value":"566"},{"label":"Бесстрашные персонажи","value":"6921"},{"label":"Бесстыдные персонажи","value":"1257"},{"label":"Бесстыдный главный герой","value":"8190"},{"label":"Библиотека","value":"4210"},{"label":"Библия","value":"488"},{"label":"Бизнес","value":"704"},{"label":"Биология","value":"2220"},{"label":"Биомехи","value":"1968"},{"label":"Биседзе","value":"777"},{"label":"Битва за веру","value":"721"},{"label":"Битва за трон","value":"7211"},{"label":"Битва королевств","value":"1151"},{"label":"Битва рас","value":"6989"},{"label":"Битвы","value":"1740"},{"label":"Благородные персонажи","value":"2201"},{"label":"Близнецы","value":"2931"},{"label":"Богатство","value":"6522"},{"label":"Богатые персонажи","value":"520"},{"label":"Боги","value":"173"},{"label":"Богини","value":"30"},{"label":"Богиня","value":"8324"},{"label":"Богоубийца","value":"1253"},{"label":"Богохульство","value":"95"},{"label":"Боевая академия","value":"2108"},{"label":"Большая грудь","value":"4717"},{"label":"Борос","value":"6533"},{"label":"Борьба","value":"1925"},{"label":"Борьба за власть","value":"8072"},{"label":"Босс и подчиненный","value":"7157"},{"label":"Бояръ","value":"2307"},{"label":"Брак","value":"1558"},{"label":"Брак по расчету","value":"1389"},{"label":"Брат и сестра","value":"615"},{"label":"Братский комплекс","value":"2321"},{"label":"Броманс","value":"1103"},{"label":"Брошенные дети","value":"2846"},{"label":"Буддизм","value":"1871"},{"label":"Будущее","value":"1820"},{"label":"Бывший муж","value":"8080"},{"label":"Быстрое развитие","value":"1443"},{"label":"Бэтгерл","value":"2584"},{"label":"Бэтмен","value":"4668"},{"label":"В первый раз","value":"6212"},{"label":"В этот же мир","value":"49"},{"label":"Ваканда","value":"8331"},{"label":"Валькирии","value":"4047"},{"label":"Вампиры","value":"2206"},{"label":"Веб камера","value":"5664"},{"label":"Веб новелла","value":"2349"},{"label":"Ведьмак","value":"843"},{"label":"Ведьмы","value":"643"},{"label":"Везучие персонажи","value":"1879"},{"label":"Веном","value":"3994"},{"label":"Вестерн","value":"2131"},{"label":"Вестерос","value":"8171"},{"label":"Взросление","value":"624"},{"label":"Взрослый главный герой","value":"2416"},{"label":"Видео игры","value":"2630"},{"label":"Викинги","value":"267"},{"label":"Вино","value":"6972"},{"label":"Вирт","value":"6213"},{"label":"Виртуальная реальность","value":"325"},{"label":"Вирусы","value":"3327"},{"label":"Владыка демонов","value":"555"},{"label":"Власть","value":"756"},{"label":"Влюбленность","value":"6132"},{"label":"Внешний вид отличается от личности","value":"1938"},{"label":"Внучка","value":"8399"},{"label":"Военные","value":"1096"},{"label":"Возрождение","value":"1160"},{"label":"Воины","value":"287"},{"label":"Война","value":"443"},{"label":"Войны","value":"2431"},{"label":"Воландеморт","value":"4278"},{"label":"Волейбол","value":"6415"},{"label":"Волки","value":"1166"},{"label":"Волшебники","value":"122"},{"label":"Волшебные существа","value":"1689"},{"label":"Волшебство","value":"719"},{"label":"Вор","value":"1399"},{"label":"Воровка","value":"6948"},{"label":"Ворон","value":"848"},{"label":"Воскрешение","value":"6915"},{"label":"Воспоминания из другого мира","value":"1366"},{"label":"Воспоминания из прошлого","value":"1372"},{"label":"Воссоединие семьи","value":"8130"},{"label":"Восхождение","value":"380"},{"label":"Враги становятся любовниками","value":"978"},{"label":"Врата","value":"40"},{"label":"Врата в другой мир","value":"1957"},{"label":"Врач","value":"1243"},{"label":"Временная петля","value":"2852"},{"label":"Врмморпг","value":"2043"},{"label":"Все дозволено","value":"96"},{"label":"Всемогущий главный герой","value":"1414"},{"label":"Второй шанс","value":"2372"},{"label":"Вуайеризм","value":"2498"},{"label":"Выживание","value":"501"},{"label":"Вымышленные существа","value":"3466"},{"label":"Вынужденный брак","value":"7705"},{"label":"Высокие технологии","value":"653"},{"label":"Высокомерные персонажи","value":"3250"},{"label":"Галустян","value":"5199"},{"label":"Гангстеры","value":"7704"},{"label":"Гарем","value":"440"},{"label":"Гарри поттер","value":"226"},{"label":"Геймеры","value":"2130"},{"label":"Генетические модификации","value":"1750"},{"label":"Гениальный главный герой","value":"1500"},{"label":"Гений","value":"1650"},{"label":"Гермиона грейнджер","value":"4280"},{"label":"Герои","value":"185"},{"label":"Гигаполис","value":"8393"},{"label":"Гильгамеш","value":"6031"},{"label":"Гильдии","value":"900"},{"label":"Гильдия авантюристов","value":"1858"},{"label":"Гинтама","value":"4544"},{"label":"Гипноз","value":"358"},{"label":"Главная героиня влюбляется первой","value":"973"},{"label":"Главный герой бог","value":"164"},{"label":"Главный герой влюбляется первым","value":"3629"},{"label":"Главный герой выживальщик","value":"120"},{"label":"Главный герой гонг","value":"7877"},{"label":"Главный герой девушка","value":"257"},{"label":"Главный герой демон","value":"136"},{"label":"Главный герой женщина","value":"7329"},{"label":"Главный герой жестокий","value":"1553"},{"label":"Главный герой извращенец","value":"94"},{"label":"Главный герой имба","value":"2421"},{"label":"Главный герой киборг","value":"7780"},{"label":"Главный герой монстр","value":"869"},{"label":"Главный герой мужчина","value":"1997"},{"label":"Главный герой на стороне сил зла","value":"1514"},{"label":"Главный герой не адекватный","value":"5"},{"label":"Главный герой не психопат","value":"7804"},{"label":"Главный герой не человек","value":"2172"},{"label":"Главный герой не эмоционален","value":"1150"},{"label":"Главный герой подросток","value":"2215"},{"label":"Главный герой позитивный","value":"7787"},{"label":"Главный герой психопат","value":"7803"},{"label":"Главный герой ребенок","value":"2347"},{"label":"Главный герой русский","value":"2417"},{"label":"Главный герой сильный с самого начала","value":"88"},{"label":"Главный герой скрывает свою силу","value":"1059"},{"label":"Главный герой эгоист","value":"8326"},{"label":"Гномы","value":"1870"},{"label":"Гоблины","value":"2029"},{"label":"Годзилла","value":"6990"},{"label":"Големы","value":"1690"},{"label":"Голливуд","value":"7754"},{"label":"Головоломка","value":"1697"},{"label":"Горничные","value":"8091"},{"label":"Гробница","value":"388"},{"label":"Дазай осаму","value":"4112"},{"label":"Даньмэй","value":"3411"},{"label":"Даосизм","value":"258"},{"label":"Дарк соулс","value":"6057"},{"label":"Дарт вейдер","value":"6826"},{"label":"Дафна гринграсс","value":"5192"},{"label":"Дворяне","value":"7204"},{"label":"Девушки","value":"7668"},{"label":"Девушки монстры","value":"2231"},{"label":"Дедушка и внучка","value":"8400"},{"label":"Дейви джонс","value":"8061"},{"label":"Действие","value":"1425"},{"label":"Демон лорд","value":"153"},{"label":"Демонология","value":"2024"},{"label":"Демоны","value":"1406"},{"label":"Дети","value":"580"},{"label":"Джарвис","value":"933"},{"label":"Джедай","value":"4442"},{"label":"Джин","value":"4024"},{"label":"Джокер","value":"3351"},{"label":"Джон сноу","value":"7412"},{"label":"Джоффри баратеон","value":"3936"},{"label":"Дзесэй","value":"678"},{"label":"Дин винчестер","value":"6953"},{"label":"Династии","value":"2982"},{"label":"Динозавры","value":"3666"},{"label":"Директор","value":"1417"},{"label":"Для девушек","value":"1441"},{"label":"Дневник","value":"298"},{"label":"Добби","value":"6762"},{"label":"Добрый мир","value":"1685"},{"label":"Договоры с богами","value":"2152"},{"label":"Договоры с демонами","value":"1922"},{"label":"Доктор","value":"1991"},{"label":"Доктор стрэндж","value":"7634"},{"label":"Доминирование","value":"2054"},{"label":"Дота","value":"6965"},{"label":"Доудзюцу","value":"7133"},{"label":"Дочь","value":"3291"},{"label":"Драко малфой","value":"46"},{"label":"Драконы","value":"282"},{"label":"Драконы оборотни","value":"8082"},{"label":"Древние времена","value":"7781"},{"label":"Древний египет","value":"7614"},{"label":"Древний китай","value":"473"},{"label":"Древний мир","value":"4"},{"label":"Другая вселенная","value":"39"},{"label":"Другие планеты","value":"2371"},{"label":"Другой мир","value":"2248"},{"label":"Дружба","value":"1903"},{"label":"Друзья детства","value":"1153"},{"label":"Духи","value":"114"},{"label":"Духовные силы","value":"1955"},{"label":"Души","value":"1212"},{"label":"Дьявол","value":"1094"},{"label":"Дьявольские фрукты","value":"1564"},{"label":"Дэдпул","value":"4399"},{"label":"Евнух","value":"6293"},{"label":"Европейская атмосфера","value":"5837"},{"label":"Египет","value":"528"},{"label":"Еда","value":"2056"},{"label":"Единороги","value":"437"},{"label":"Екаи","value":"655"},{"label":"Жалкий главный герой","value":"97"},{"label":"Жена","value":"5729"},{"label":"Женское доминирование","value":"4622"},{"label":"Женщина в теле мужчины","value":"2748"},{"label":"Женщина кошка","value":"7513"},{"label":"Жестокие персонажи","value":"3153"},{"label":"Жестокий мир","value":"1532"},{"label":"Жестокость","value":"7880"},{"label":"Животные","value":"7488"},{"label":"Животные компаньоны","value":"2061"},{"label":"Жизнь и смерть","value":"2014"},{"label":"Жнец","value":"6288"},{"label":"Жойен рид","value":"3926"},{"label":"Заботливый главный герой","value":"338"},{"label":"Закалка тела","value":"148"},{"label":"Заклинания","value":"558"},{"label":"Заключенные","value":"3052"},{"label":"Занпакто","value":"1102"},{"label":"Запретная любовь","value":"8033"},{"label":"Запутанный сюжет","value":"1041"},{"label":"Захват мира","value":"315"},{"label":"Зачарованные","value":"4169"},{"label":"Звери","value":"1638"},{"label":"Зверодевочки","value":"2006"},{"label":"Зверолюди","value":"1018"},{"label":"Земля","value":"82"},{"label":"Злая организация","value":"7768"},{"label":"Зло","value":"1512"},{"label":"Злодей","value":"1060"},{"label":"Злодейка","value":"2376"},{"label":"Злой главный герой","value":"616"},{"label":"Злые боги","value":"7109"},{"label":"Злые персонажи","value":"3243"},{"label":"Змей","value":"5721"},{"label":"Знаменитости","value":"1341"},{"label":"Знание медицины","value":"1411"},{"label":"Золушка","value":"2980"},{"label":"Зомби","value":"1743"},{"label":"Зомби апокалипсис","value":"912"},{"label":"Зона 51","value":"3051"},{"label":"Зооморфы","value":"375"},{"label":"Зорро","value":"6736"},{"label":"Зрелые женщины","value":"1458"},{"label":"Игра","value":"663"},{"label":"Игра на выживание","value":"2182"},{"label":"Игровая система","value":"384"},{"label":"Игровые элементы","value":"720"},{"label":"Извращения","value":"651"},{"label":"Измена","value":"1874"},{"label":"Изменение характера","value":"1113"},{"label":"Изменения внешности","value":"259"},{"label":"Изменения личности","value":"1080"},{"label":"Изобретения","value":"126"},{"label":"Изуку мидория","value":"6967"},{"label":"Император","value":"867"},{"label":"Империи","value":"712"},{"label":"Империя","value":"1716"},{"label":"Инвалидность","value":"2073"},{"label":"Инквизитор","value":"143"},{"label":"Инкуб","value":"3264"},{"label":"Инопланетное вторжение","value":"209"},{"label":"Инопланетяне","value":"866"},{"label":"Интерактив с читателями","value":"472"},{"label":"Интересный сюжет","value":"7374"},{"label":"Интернет","value":"739"},{"label":"Интимные сцены","value":"3450"},{"label":"Интрига","value":"317"},{"label":"Интриги и заговоры","value":"1009"},{"label":"Иные миры","value":"35"},{"label":"Исекай","value":"2979"},{"label":"Искусственный интеллект","value":"1900"},{"label":"Исследование","value":"1626"},{"label":"Исторический роман","value":"573"},{"label":"Итачи учиха","value":"4556"},{"label":"Ичиго","value":"7254"},{"label":"Йода","value":"6829"},{"label":"Йоруичи","value":"6755"},{"label":"Калипсо","value":"8062"},{"label":"Каннибализм","value":"2249"},{"label":"Капитан америка","value":"6301"},{"label":"Каракура","value":"7473"},{"label":"Карточная игра","value":"1557"},{"label":"Кастиэль","value":"6954"},{"label":"Кафе","value":"3934"},{"label":"Кацуки бакуго","value":"7696"},{"label":"Квесты","value":"1707"},{"label":"Киберспорт","value":"1984"},{"label":"Кино","value":"7126"},{"label":"Китай","value":"3762"},{"label":"Кицунэ","value":"241"},{"label":"Кланы","value":"834"},{"label":"Клоны","value":"1624"},{"label":"Книги","value":"1068"},{"label":"Книжный червь","value":"521"},{"label":"Колдовство","value":"2681"},{"label":"колледж","value":"5058"},{"label":"Коллекционер","value":"2588"},{"label":"Кольцо","value":"1628"},{"label":"Коммунисты","value":"1042"},{"label":"Коноха","value":"2827"},{"label":"Контракт","value":"4304"},{"label":"Контроль разума","value":"485"},{"label":"Конфеты","value":"341"},{"label":"Корейцы","value":"6535"},{"label":"Корея","value":"2443"},{"label":"Королевская власть","value":"55"},{"label":"Королевская семья","value":"276"},{"label":"Королевство","value":"1695"},{"label":"Короткий рассказ","value":"239"},{"label":"Коррупция","value":"831"},{"label":"Космическая опера","value":"2245"},{"label":"Космические рейнджеры","value":"5860"},{"label":"Космос","value":"329"},{"label":"Кот","value":"5171"},{"label":"Кража навыков","value":"1159"},{"label":"Красивая главная героиня","value":"186"},{"label":"Красивые женщины","value":"66"},{"label":"Красивые персонажи","value":"5787"},{"label":"Красивый главный герой","value":"895"},{"label":"Крафт","value":"1599"},{"label":"Кроссовер","value":"75"},{"label":"Ктулху","value":"920"},{"label":"Кузнец","value":"853"},{"label":"Кукла","value":"3085"},{"label":"Кулинария","value":"2230"},{"label":"Культивация","value":"1901"},{"label":"Культивирование","value":"1860"},{"label":"Курама","value":"5709"},{"label":"Курилин","value":"6134"},{"label":"Кушина узумаки","value":"5222"},{"label":"Лавкрафт","value":"6063"},{"label":"Лара крофт","value":"6435"},{"label":"Легенда о зельде","value":"5707"},{"label":"Ленивый главный герой","value":"1516"},{"label":"Леон золдик","value":"7469"},{"label":"Лес","value":"6645"},{"label":"Лечебная магия","value":"562"},{"label":"Локи","value":"1725"},{"label":"Лоли","value":"1576"},{"label":"Лопата","value":"4989"},{"label":"Лорд","value":"8404"},{"label":"Лориен","value":"7397"},{"label":"Лошади","value":"6110"},{"label":"Лунатизм","value":"3520"},{"label":"Луффи","value":"274"},{"label":"Лучник","value":"1038"},{"label":"Любовный интерес влюбляется первым","value":"7753"},{"label":"Любовный треугольник","value":"2109"},{"label":"Любовь","value":"2297"},{"label":"Любовь с первого взгляда","value":"7748"},{"label":"Любящие родители","value":"2699"},{"label":"Люди","value":"3572"},{"label":"Люцифер","value":"5883"},{"label":"Маг","value":"780"},{"label":"Магазин","value":"4762"},{"label":"Маги","value":"58"},{"label":"Магическая академия","value":"6788"},{"label":"Магические звери","value":"684"},{"label":"Магические предметы","value":"1648"},{"label":"Магический мир","value":"578"},{"label":"Магия","value":"150"},{"label":"Магия воды","value":"6450"},{"label":"Магия воздуха","value":"7627"},{"label":"Магия земли","value":"7626"},{"label":"Магия и технология","value":"107"},{"label":"Магия крови","value":"7976"},{"label":"Магия льда","value":"1379"},{"label":"Магия огня","value":"7625"},{"label":"Магия призыва","value":"885"},{"label":"Магия природы","value":"6226"},{"label":"Магия стихий","value":"7673"},{"label":"Магия тьмы","value":"3596"},{"label":"Мадара","value":"2929"},{"label":"Мазохизм","value":"1961"},{"label":"Мама","value":"12"},{"label":"Мама и дочь","value":"7894"},{"label":"Мама и сын","value":"7895"},{"label":"Манга","value":"2464"},{"label":"Манипуляция временем","value":"932"},{"label":"Маньяк","value":"2026"},{"label":"Маргери тирелл","value":"3935"},{"label":"Марионетки","value":"3175"},{"label":"Марс","value":"4013"},{"label":"Марти стью","value":"594"},{"label":"Мастер на все руки","value":"3189"},{"label":"Матриархат","value":"7197"},{"label":"Мать и сестры","value":"7946"},{"label":"Мафия","value":"353"},{"label":"Мачеха","value":"4664"},{"label":"Мегаполис","value":"3322"},{"label":"Медицина","value":"441"},{"label":"Медленная романтика","value":"8383"},{"label":"Медленное развитие истории","value":"7462"},{"label":"Мелиодас","value":"7224"},{"label":"Мелодрама","value":"1507"},{"label":"Менеджмент","value":"368"},{"label":"Мерлин","value":"3977"},{"label":"Месть","value":"1218"},{"label":"Меч","value":"48"},{"label":"Мечники","value":"969"},{"label":"Мечта","value":"527"},{"label":"Мизуки","value":"4269"},{"label":"Микото","value":"3862"},{"label":"Милая главная героиня","value":"134"},{"label":"Милф","value":"1987"},{"label":"Милый главный герой","value":"2678"},{"label":"Мимик","value":"5706"},{"label":"Мина ашидо","value":"7695"},{"label":"Минато намикадзе","value":"5223"},{"label":"Мир будущего","value":"1770"},{"label":"Мир земли","value":"8394"},{"label":"Мир меча и магии","value":"1271"},{"label":"Мистер пропер","value":"565"},{"label":"Мифические существа","value":"1878"},{"label":"Мифы и легенды","value":"4463"},{"label":"Младшая сестра","value":"1523"},{"label":"Мморпг","value":"620"},{"label":"Много главных героев","value":"1191"},{"label":"Много крови","value":"5318"},{"label":"Много персонажей","value":"1539"},{"label":"Множество королевств","value":"32"},{"label":"Модерн","value":"5457"},{"label":"Мокутон","value":"4438"},{"label":"Молоко","value":"5469"},{"label":"Монархия","value":"3590"},{"label":"Монстры","value":"307"},{"label":"Море","value":"922"},{"label":"Моритика ринносукэ","value":"1142"},{"label":"Мортал комбат","value":"5861"},{"label":"Мошенник","value":"959"},{"label":"Мрачный мир","value":"1"},{"label":"Мужчина в женском теле","value":"8405"},{"label":"Музыка","value":"1183"},{"label":"Мультивселенная","value":"7410"},{"label":"Мурим","value":"7342"},{"label":"Мутанты","value":"2392"},{"label":"Мутация","value":"29"},{"label":"Мясо","value":"1503"},{"label":"На реальных событиях","value":"26"},{"label":"Навыки","value":"415"},{"label":"Нагато узумаки","value":"5221"},{"label":"Наемники","value":"1668"},{"label":"Назарик","value":"5369"},{"label":"Наивный главный герой","value":"159"},{"label":"Наложница","value":"4867"},{"label":"Наноботы","value":"2332"},{"label":"Наруто","value":"7177"},{"label":"Наруто и хината","value":"5766"},{"label":"Насилие и жестокость","value":"1440"},{"label":"Наука","value":"2150"},{"label":"Национализм","value":"5556"},{"label":"Нацу","value":"5826"},{"label":"Нацуки субару","value":"6656"},{"label":"Начальная школа","value":"3920"},{"label":"Наши дни","value":"1814"},{"label":"Не всесильный главный герой","value":"42"},{"label":"Не по канону","value":"1611"},{"label":"Неверность","value":"5735"},{"label":"Невеста","value":"6011"},{"label":"Неджи хьюга","value":"3099"},{"label":"Недооценённый главный герой","value":"43"},{"label":"Нежить","value":"1949"},{"label":"Некромаг","value":"7441"},{"label":"Некромант","value":"1914"},{"label":"Некромантия","value":"754"},{"label":"Ненормативная лексика","value":"160"},{"label":"Необычные герои","value":"67"},{"label":"Нет людей","value":"7486"},{"label":"Нетораре","value":"403"},{"label":"Нетори","value":"5393"},{"label":"Нефилимы","value":"7764"},{"label":"Нецензурная лексика","value":"4912"},{"label":"Нечисть","value":"4559"},{"label":"Ник фьюри","value":"6304"},{"label":"Ниндзюцу","value":"2354"},{"label":"Ниндзя","value":"1330"},{"label":"Новелла","value":"2105"},{"label":"Нэко","value":"147"},{"label":"Оби ван кеноби","value":"6830"},{"label":"Обито учиха","value":"2814"},{"label":"Оборотни","value":"53"},{"label":"Обратный гарем","value":"3303"},{"label":"Овощ","value":"6098"},{"label":"Огнестрельное оружие","value":"3155"},{"label":"Одержимость","value":"708"},{"label":"Один в поле воин","value":"6498"},{"label":"Онлайн игра","value":"1565"},{"label":"Ооками теппей","value":"849"},{"label":"Оригинальные персонажи","value":"7741"},{"label":"Орки","value":"1597"},{"label":"Оружие","value":"125"},{"label":"Основано на видео игре","value":"602"},{"label":"Особые способности","value":"2904"},{"label":"От бедности к богатству","value":"901"},{"label":"От слабого до сильного","value":"118"},{"label":"Отель","value":"2879"},{"label":"Отец","value":"3290"},{"label":"Отношения","value":"398"},{"label":"Отношения человек/нечеловек","value":"7406"},{"label":"Офис","value":"3460"},{"label":"Охотники","value":"2263"},{"label":"Оцуцуки","value":"5101"},{"label":"Ошейник","value":"2362"},{"label":"Ояш","value":"8048"},{"label":"Падчерица","value":"7023"},{"label":"Падший ангел","value":"184"},{"label":"Палач","value":"852"},{"label":"Палочка","value":"2682"},{"label":"Пандорум","value":"4360"},{"label":"Папа и дочь","value":"7647"},{"label":"Паразит","value":"1213"},{"label":"Параллельный мир","value":"2092"},{"label":"Парень","value":"619"},{"label":"Паркур","value":"3391"},{"label":"Пародия","value":"898"},{"label":"Пасхалки","value":"455"},{"label":"Паук","value":"2209"},{"label":"Пекарь","value":"5073"},{"label":"Первая книга","value":"269"},{"label":"Первая любовь","value":"640"},{"label":"Первый раз","value":"1465"},{"label":"Переводы","value":"24"},{"label":"Перевоплощение","value":"1596"},{"label":"Перевоплощение в игровом мире","value":"92"},{"label":"Перемещение в другой мир","value":"1288"},{"label":"Перемещение во времени","value":"146"},{"label":"Перерождение","value":"894"},{"label":"Перерождение в демона","value":"1111"},{"label":"Перерождение в дракона","value":"6867"},{"label":"Перерождение в злодейку","value":"5619"},{"label":"Перерождение в злодея","value":"749"},{"label":"Перерождение в ином мире","value":"109"},{"label":"Перерождение в монстра","value":"917"},{"label":"Перерождений","value":"335"},{"label":"Переселение","value":"813"},{"label":"Переселение души","value":"1864"},{"label":"Перси джексон","value":"6329"},{"label":"Пилот","value":"5521"},{"label":"Пилюли","value":"1531"},{"label":"Пират","value":"1579"},{"label":"Пирог","value":"80"},{"label":"Писатель","value":"734"},{"label":"Пистолеты","value":"4916"},{"label":"Письмо","value":"840"},{"label":"Питомцы","value":"3122"},{"label":"Планомерное развитие событий","value":"62"},{"label":"Племянник","value":"8303"},{"label":"Пленница","value":"4897"},{"label":"Плети","value":"4839"},{"label":"Пляж","value":"4243"},{"label":"Повар","value":"658"},{"label":"Повествование от первого лица","value":"1054"},{"label":"Повествование от разных лиц","value":"600"},{"label":"Повествование от третьего лица","value":"2116"},{"label":"Подавитель","value":"497"},{"label":"Подземелье","value":"798"},{"label":"Подростки","value":"636"},{"label":"Подруга","value":"5804"},{"label":"Подчинение","value":"8343"},{"label":"Подчинение и унижение","value":"4500"},{"label":"Покемоны","value":"2840"},{"label":"Полиамория","value":"1300"},{"label":"Полигамия","value":"1336"},{"label":"Политика","value":"1313"},{"label":"Полицейский","value":"1907"},{"label":"Полубог","value":"7170"},{"label":"Полукровка","value":"999"},{"label":"Полулюди","value":"2273"},{"label":"Поношенные трусики","value":"1204"},{"label":"Попаданец","value":"2396"},{"label":"Попаданец в другой мир","value":"685"},{"label":"Попаданец в игру","value":"6466"},{"label":"Попадание в книгу","value":"6957"},{"label":"Постапокалипсис","value":"1079"},{"label":"Похищение","value":"7452"},{"label":"Поэзия","value":"1120"},{"label":"Правитель","value":"2261"},{"label":"Превращения в животных","value":"3410"},{"label":"Преданный любовный интерес","value":"2055"},{"label":"Предательство","value":"70"},{"label":"Президент","value":"4334"},{"label":"Преступник","value":"4049"},{"label":"Преступный мир","value":"965"},{"label":"Призрак","value":"511"},{"label":"Призыв","value":"332"},{"label":"Призыв в другой мир","value":"781"},{"label":"Призыв существ","value":"412"},{"label":"Приложение на телефоне","value":"5345"},{"label":"Принудительный брак","value":"2954"},{"label":"Принуждение","value":"1442"},{"label":"Принц","value":"362"},{"label":"Принцесса","value":"2403"},{"label":"Приручение мостров","value":"2338"},{"label":"Прислуга","value":"5185"},{"label":"Пришельцы","value":"273"},{"label":"Проза","value":"2012"},{"label":"Прокачка","value":"1070"},{"label":"Проклятия","value":"1347"},{"label":"Проработанный мир","value":"1711"},{"label":"Пророчество","value":"7762"},{"label":"Против наркотиков","value":"8406"},{"label":"Псайкеры","value":"3659"},{"label":"Псионика","value":"5216"},{"label":"Психбольница","value":"6969"},{"label":"Психические расстройства","value":"2445"},{"label":"Психологические травмы","value":"3418"},{"label":"Публичный дом","value":"7860"},{"label":"Путешествие в другой мир","value":"10"},{"label":"Пух","value":"4286"},{"label":"Пушечное мясо","value":"7234"},{"label":"Пытки","value":"1756"},{"label":"Пьяный мастер","value":"1655"},{"label":"Пэнси паркинсон","value":"7411"},{"label":"Раб","value":"977"},{"label":"Рабы","value":"1240"},{"label":"Разведение животных","value":"3990"},{"label":"Развитие","value":"208"},{"label":"Развитие персонажа","value":"1780"},{"label":"Развитие поселения","value":"7203"},{"label":"Развитие технологий","value":"1875"},{"label":"Раздвоение личности","value":"2062"},{"label":"Разные расы","value":"1188"},{"label":"Разорванная помолвка","value":"2057"},{"label":"Разработчик","value":"2333"},{"label":"Ранги","value":"1568"},{"label":"Ранобэ","value":"1764"},{"label":"Расизм","value":"3554"},{"label":"Растение","value":"407"},{"label":"Реализм","value":"1180"},{"label":"Ребенок","value":"2881"},{"label":"Ревность","value":"293"},{"label":"Революция","value":"3996"},{"label":"Реинкарнация","value":"1302"},{"label":"Реинкарнация в другом мире","value":"2180"},{"label":"Реинкарнация в игровой мир","value":"304"},{"label":"Рейджер","value":"5147"},{"label":"Религия","value":"2184"},{"label":"Рем","value":"6655"},{"label":"Ремесленник","value":"1483"},{"label":"Ремонт","value":"5703"},{"label":"Репликаторы","value":"3495"},{"label":"Ресторан","value":"7519"},{"label":"Риас гремори","value":"6950"},{"label":"Рим","value":"612"},{"label":"Риннеган","value":"4230"},{"label":"Ритуал","value":"1233"},{"label":"Робот","value":"4011"},{"label":"Роботы","value":"467"},{"label":"Рок ли","value":"7002"},{"label":"Рокси","value":"7380"},{"label":"Рон уизли","value":"4279"},{"label":"Ророноа зоро","value":"1590"},{"label":"Росомаха","value":"1035"},{"label":"Российская империя","value":"2146"},{"label":"Россия","value":"4246"},{"label":"Рудеус","value":"7379"},{"label":"Руны","value":"2393"},{"label":"Русалки","value":"3127"},{"label":"Русь","value":"2016"},{"label":"Рыцари","value":"1902"},{"label":"Рэо хатаке","value":"2823"},{"label":"Сабли","value":"6136"},{"label":"Сайян","value":"6802"},{"label":"Сакура","value":"2515"},{"label":"Самец","value":"1592"},{"label":"Самураи","value":"576"},{"label":"Санса старк","value":"3925"},{"label":"Сарказм","value":"4658"},{"label":"Саске","value":"7237"},{"label":"Сатира","value":"215"},{"label":"Сборник","value":"7367"},{"label":"Свадьба","value":"1524"},{"label":"Сверхсила","value":"1055"},{"label":"Свинцовые книги","value":"5322"},{"label":"Связывание","value":"4506"},{"label":"Священик","value":"61"},{"label":"Северус снейп","value":"5783"},{"label":"Сёдзе","value":"2219"},{"label":"Секты","value":"1234"},{"label":"Сельское хозяйство","value":"787"},{"label":"Семейный конфликт","value":"935"},{"label":"Семья","value":"728"},{"label":"Сенджу","value":"6069"},{"label":"Серийный убийца","value":"261"},{"label":"Сестра","value":"2342"},{"label":"Сила глаза","value":"1019"},{"label":"Сильная героиня","value":"7292"},{"label":"Сильная главная героиня","value":"1994"},{"label":"Сильный главный герой","value":"570"},{"label":"Сильфиетта","value":"7381"},{"label":"Симбиот","value":"2648"},{"label":"Сириус блэк","value":"7655"},{"label":"Сирота","value":"297"},{"label":"Система","value":"251"},{"label":"Система уровней","value":"2174"},{"label":"Ситх","value":"1618"},{"label":"Сказка","value":"3570"},{"label":"Скайрим","value":"4032"},{"label":"Скайуокер","value":"6828"},{"label":"Сквиб","value":"4101"},{"label":"Скелет","value":"1315"},{"label":"Скрытые способности","value":"3417"},{"label":"Скульптор","value":"1178"},{"label":"Слабая главная героиня","value":"5805"},{"label":"Слабый главный герой","value":"731"},{"label":"Славяне","value":"2168"},{"label":"Слизерин","value":"6979"},{"label":"Слизь","value":"1095"},{"label":"Сломанная игрушка","value":"8396"},{"label":"Служанка","value":"3486"},{"label":"Смартфон","value":"457"},{"label":"Смена сущности","value":"8391"},{"label":"Смерть","value":"1779"},{"label":"Смерть основного персонажа","value":"1530"},{"label":"Собаки","value":"6109"},{"label":"Соблазн","value":"7994"},{"label":"Соблазнение","value":"2290"},{"label":"Современность","value":"568"},{"label":"Современные знания","value":"988"},{"label":"Сожительство","value":"3026"},{"label":"Создание армии","value":"1992"},{"label":"Создание королевства","value":"1497"},{"label":"Создание пилюль","value":"816"},{"label":"Создатель","value":"1045"},{"label":"Сокровища","value":"6521"},{"label":"Сокрытие истинной личности","value":"2894"},{"label":"Сома и эрина","value":"5737"},{"label":"Соперничество","value":"7699"},{"label":"Соседи","value":"4075"},{"label":"Сотрудник","value":"6339"},{"label":"Социология","value":"7618"},{"label":"Спокойная главная героиня","value":"236"},{"label":"Спокойный главный герой","value":"1656"},{"label":"Спор","value":"3484"},{"label":"Спортивное тело","value":"8317"},{"label":"Способность кражи","value":"7784"},{"label":"Сражения","value":"23"},{"label":"Средневековье","value":"1022"},{"label":"Сталкер","value":"1932"},{"label":"Становление государства","value":"111"},{"label":"Старшая школа","value":"1658"},{"label":"Стёб","value":"454"},{"label":"Стекло","value":"7453"},{"label":"Стеснительный персонаж","value":"152"},{"label":"Стимпанк","value":"1894"},{"label":"Стихи","value":"1309"},{"label":"Стратегия","value":"569"},{"label":"Строительство","value":"921"},{"label":"Студент","value":"1464"},{"label":"Студентка","value":"7518"},{"label":"Суккубы","value":"2662"},{"label":"Супер зрение","value":"6574"},{"label":"Супер удача","value":"489"},{"label":"Супергерои","value":"1481"},{"label":"Суперзлодеи","value":"2125"},{"label":"Супермен","value":"6997"},{"label":"Суперсилы","value":"2276"},{"label":"Существа","value":"6033"},{"label":"Сферы","value":"1077"},{"label":"Схемы и заговоры","value":"7116"},{"label":"Сценарий","value":"7489"},{"label":"Счастливый конец","value":"3293"},{"label":"Сын","value":"3297"},{"label":"Сэм винчестер","value":"7461"},{"label":"Сюаньхуа","value":"2560"},{"label":"Сюжетные повороты","value":"7202"},{"label":"Таблетки для развития","value":"589"},{"label":"Таинственное прошлое","value":"769"},{"label":"Тайная личность","value":"8096"},{"label":"Тайная любовь","value":"113"},{"label":"Тайны","value":"7481"},{"label":"Тайные отношения","value":"7450"},{"label":"Тайцы","value":"6413"},{"label":"Танки","value":"1787"},{"label":"Творчество","value":"20"},{"label":"Тейлор эберт","value":"3526"},{"label":"Телекинез","value":"2203"},{"label":"Телепортация","value":"914"},{"label":"Телохранитель","value":"723"},{"label":"Темари","value":"4810"},{"label":"Темная магия","value":"4788"},{"label":"Темное фэнтези","value":"1675"},{"label":"Темные эльфы","value":"7198"},{"label":"Тенсейган","value":"4367"},{"label":"Тетя","value":"4194"},{"label":"Техномагия","value":"508"},{"label":"Тиран","value":"1174"},{"label":"Титаны","value":"3308"},{"label":"Тодороки шото","value":"5105"},{"label":"Токио","value":"5791"},{"label":"Том реддл","value":"6652"},{"label":"Тони старк","value":"1338"},{"label":"Тор","value":"1800"},{"label":"Тор и локи","value":"2645"},{"label":"Торговля","value":"1637"},{"label":"Травничество","value":"221"},{"label":"Трагическое прошлое","value":"644"},{"label":"Трактир","value":"1918"},{"label":"Трансмиграция","value":"1071"},{"label":"Трансформация","value":"156"},{"label":"Трансформеры","value":"4616"},{"label":"Тревор филипс","value":"5427"},{"label":"Тройняшки","value":"7169"},{"label":"Троли","value":"4250"},{"label":"Трудолюбивый главный герой","value":"248"},{"label":"Тупой главный герой","value":"3710"},{"label":"Тьма","value":"1919"},{"label":"Тюрьма","value":"5597"},{"label":"Тяжёлое детство","value":"2253"},{"label":"Убийства","value":"378"},{"label":"Убийцы","value":"1766"},{"label":"Убийцы драконов","value":"1484"},{"label":"Увечья","value":"3266"},{"label":"Удача","value":"6575"},{"label":"Узумаки","value":"7579"},{"label":"Укротитель","value":"367"},{"label":"Умения","value":"531"},{"label":"Умная главная героиня","value":"1381"},{"label":"Умные персонажи","value":"2756"},{"label":"Умный главный герой","value":"2093"},{"label":"Университет","value":"2102"},{"label":"Унижение","value":"8342"},{"label":"Уничтожение мира","value":"81"},{"label":"Управление временем","value":"5648"},{"label":"Уровни","value":"8"},{"label":"Усиление","value":"3549"},{"label":"Усопп","value":"6737"},{"label":"Устроенный брак","value":"2223"},{"label":"Усыновление","value":"395"},{"label":"Утопия","value":"4677"},{"label":"Уход за детьми","value":"7609"},{"label":"Учеба в университете","value":"2797"},{"label":"Учебное заведение","value":"1817"},{"label":"Ученые","value":"1843"},{"label":"Учитель","value":"845"},{"label":"Учиха","value":"5348"},{"label":"Фамильяры","value":"1471"},{"label":"Фанатичная любовь","value":"6721"},{"label":"Фанаты","value":"7739"},{"label":"Фантастический мир","value":"2414"},{"label":"Фармацевт","value":"1706"},{"label":"Фашисты","value":"3118"},{"label":"Феи","value":"7185"},{"label":"Фелляция","value":"5880"},{"label":"Феминизм","value":"6527"},{"label":"Феникс","value":"2413"},{"label":"Фенрир","value":"2740"},{"label":"Феодализм","value":"280"},{"label":"Ферма","value":"285"},{"label":"Фехтовальщик","value":"4685"},{"label":"Филиппины","value":"128"},{"label":"Философия","value":"1859"},{"label":"Флафф","value":"5048"},{"label":"Флер делакур","value":"5191"},{"label":"Флэш","value":"4667"},{"label":"Фокусник","value":"7602"},{"label":"Фольклор","value":"4086"},{"label":"Фугаку","value":"6161"},{"label":"Фурри","value":"6631"},{"label":"Футбол","value":"1121"},{"label":"Фэнтезийный мир","value":"1556"},{"label":"Хакер","value":"475"},{"label":"Халк","value":"1196"},{"label":"Хан нуньен синг","value":"4817"},{"label":"Ханма юджиро","value":"4369"},{"label":"Хаос","value":"3117"},{"label":"Харизматичный главный герой","value":"2350"},{"label":"Хатаке какаши","value":"2820"},{"label":"Хиддлстон","value":"5903"},{"label":"Химавари","value":"2583"},{"label":"Хината","value":"2513"},{"label":"Хитрый главный герой","value":"2036"},{"label":"Хоббит","value":"6698"},{"label":"Хогвартс","value":"5954"},{"label":"Холодная главная героиня","value":"6507"},{"label":"Холодное оружие","value":"4889"},{"label":"Холодный главный герой","value":"2686"},{"label":"Храм","value":"2135"},{"label":"Христианство","value":"877"},{"label":"Художественная литература","value":"2380"},{"label":"Художница","value":"518"},{"label":"Хулиганы","value":"854"},{"label":"Цветок","value":"902"},{"label":"Цезарь","value":"1705"},{"label":"Целители","value":"4523"},{"label":"Церковь","value":"1980"},{"label":"Цундере","value":"1078"},{"label":"Чакра","value":"1393"},{"label":"Чат-система","value":"8407"},{"label":"Черный юмор","value":"2868"},{"label":"Честная главная героиня","value":"5855"},{"label":"Честный главный герой","value":"129"},{"label":"Читы","value":"451"},{"label":"Шантаж","value":"7175"},{"label":"Шаринган","value":"5165"},{"label":"Шинигами","value":"4661"},{"label":"Шиноби","value":"1227"},{"label":"Школьная жизнь","value":"284"},{"label":"Школьники","value":"218"},{"label":"Школьницы","value":"5946"},{"label":"Шлюха","value":"5822"},{"label":"Шоу-бизнес","value":"7119"},{"label":"Шпионы","value":"4262"},{"label":"Эволюция","value":"2040"},{"label":"Экзорцизм","value":"676"},{"label":"Экономика","value":"121"},{"label":"Экспансия","value":"110"},{"label":"Эксперименты над людьми","value":"7408"},{"label":"Элементальная магия","value":"1264"},{"label":"Эльфы","value":"1362"},{"label":"Эротика","value":"2053"},{"label":"Юмор","value":"7360"},{"label":"Яды","value":"201"},{"label":"Якудза","value":"4599"},{"label":"Яндере","value":"7111"},{"label":"Rpg","value":"90"},{"label":"Star wars","value":"1985"},{"label":"Time skip","value":"824"},{"label":"Warrior of light","value":"5289"}],"inputType":FilterInputs.Checkbox},{"key":"fandoms","label":"Фэндом:","values":[{"label":"19 Дней - Один день / 19 Days - One Day","value":"838"},{"label":"47-й / Хитмэн: Агент 47 / Наёмный убийца / Hitman","value":"589"},{"label":"Абсолютный дуэт / Absolute Duo","value":"1029"},{"label":"Аватар (Короля; об Аанге; об Корре) / Avatar","value":"1889"},{"label":"Аватар: Легенда о Корре / Avatar legend of Korra","value":"351"},{"label":"Аватар: Легенда об Аанге / Avatar: The Legend of Aang / Avatar: The Last Airbender","value":"303"},{"label":"Аватар(Фильм, 2009) / Avatar","value":"19"},{"label":"Ад Данте(Данте Алигьери) / Dante's Inferno(Dante Alighieri)","value":"1502"},{"label":"Азур Лейн / Azur Lane","value":"1009"},{"label":"Айон / Aion","value":"1005"},{"label":"Аладдин / Aladdin","value":"502"},{"label":"Алиса в Стране чудес / Alice in Wonderland","value":"616"},{"label":"Альдноа.Зеро / Aldnoah.Zero","value":"1799"},{"label":"Амагами СС / Amagami SS","value":"900"},{"label":"Амано Мегуми полна любви! / Amano Megumi wa Sukidarake!","value":"991"},{"label":"Американские боги / American Gods","value":"1843"},{"label":"Американский папаша! / American Dad","value":"348"},{"label":"Ангельские ритмы! / Angel Beats!","value":"880"},{"label":"Анлимитед: Хёбу Кёске / Zettai Karen Children: The Unlimited - Hyoubu Kyousuke","value":"74"},{"label":"Апостол карточек / The Apostle of Cards","value":"1504"},{"label":"Арифурэта: сильнейший ремесленник в мире / Arifureta: From Commonplace to World's Strongest","value":"62"},{"label":"Аркан: О Паровых Заводах и Магии Обскуры / Arcanum: Of Steamworks and Magick Obscura","value":"1495"},{"label":"Аркейн / Arcane: League of Legends","value":"1154"},{"label":"Аркнайтс(Games) / Arknights","value":"1210"},{"label":"Армелло(Games) / Armello","value":"1846"},{"label":"Астра, затерянная в космосе / Kanata no Astra","value":"1851"},{"label":"Атака титанов / Атака на титанов / Attack on Titan","value":"106"},{"label":"Атлантида: Затерянный мир / Atlantis: The Lost Empire","value":"985"},{"label":"Бакуган Отчаянные бойцы / Bakugan Battle Brawlers","value":"1069"},{"label":"Банановая рыба / Banana Fish","value":"1685"},{"label":"Баскетбол Куроко / Kuroko no basuke","value":"582"},{"label":"Баффи - Истребительница вампиров / Buffy the Vampire Slayer","value":"115"},{"label":"Башня Бога / Tower of God","value":"58"},{"label":"Бездарная Нана / Munou na Nana","value":"954"},{"label":"Бездомный бог / Норагами / Noragami","value":"1014"},{"label":"Безумные Мотивы / Looney Tunes","value":"1140"},{"label":"Безумный азарт / Kakegurui","value":"334"},{"label":"Бейблэйд / Beyblade","value":"921"},{"label":"Бен - 10 / Ben 10","value":"475"},{"label":"Берсерк / Berserk","value":"479"},{"label":"Бесконечное лето / Everlasting Summer","value":"966"},{"label":"Бесконечный ужас / Terror Infinity","value":"381"},{"label":"Бесподобный Воинственный Бог / Peerless Martial God","value":"419"},{"label":"Бессмертный Деревенщина(Games) / Immortal Redneck","value":"1524"},{"label":"Бесстыжие / Shameless","value":"1759"},{"label":"Био шок(Games) / BioShock","value":"1095"},{"label":"Блейд / Blade","value":"1479"},{"label":"Блич / Bleach","value":"7"},{"label":"Бог войны / God Of War","value":"352"},{"label":"Бог из машины / Deus Ex","value":"612"},{"label":"Боги поступают плохо / Игры богов / Gods Behaving Badly","value":"301"},{"label":"Боевая академия города Астериск / Gakusen Toshi Asterisk","value":"884"},{"label":"Боевой континент / Combat Continent / Douluo Dalu","value":"739"},{"label":"Боевой молот 40-го тысячелетия / WH40K / Warhammer 40,000","value":"341"},{"label":"Боевой молот Фэнтезийная битва / Warhammer Fantasy Battles","value":"1742"},{"label":"Боевые машины(Games) / BattleTech","value":"1667"},{"label":"Боец Баки / Baki the Grappler","value":"821"},{"label":"Божественность II: Эго Дракона(Games) / Divinity II: Ego Draconis","value":"1538"},{"label":"Божественные Врата / Divine Gate","value":"1490"},{"label":"Большая автомобильная кража 5 / GTA V / Grand Theft Auto V","value":"1139"},{"label":"Большая автомобильная кража: Сан-Андреас / GTA: SA / Grand Theft Auto: San Andreas","value":"820"},{"label":"Большая разница / Far Cry","value":"939"},{"label":"Большой куш / Ван Пис / One Piece","value":"25"},{"label":"Боруто: Следующие поколения Наруто / Boruto: Naruto Next Generations","value":"602"},{"label":"Брак по договоренности с принцессой красных скорпионов / Arranged marriage to the princess of the Red Scorpions","value":"1386"},{"label":"Бэтмен за гранью: Наследие / Batman Beyond: Legacy","value":"1380"},{"label":"В другом мире со смартфоном / Isekai wa Smartphone to Tomo ni","value":"947"},{"label":"В объятиях шлюхи / JK Bitch ni Shiboraretai","value":"1283"},{"label":"В ожидании бедности, я собираюсь стать кузнецом / Expecting to Fall into Ruin, I Aim to Become a Blacksmith","value":"1475"},{"label":"В Повелителе как Довакин / In Overlord as a Dovahkiin","value":"1816"},{"label":"Вакфу / Wakfu","value":"814"},{"label":"ВАЛЛ-И / Wally","value":"801"},{"label":"Вампир: Маскарад - Родословные / Vampire: The Masquerade Bloodline","value":"1212"},{"label":"Вампирелла / Vampirella","value":"1214"},{"label":"Варфрейм / Warframe","value":"967"},{"label":"Ведьмак / The Witcher","value":"278"},{"label":"Великий из бродячих псов / Bungou Stray Dogs","value":"75"},{"label":"Великолепный парк Амаги / Amagi Brilliant Park","value":"813"},{"label":"Вельзепуз / Вельзевул / Beelzebub","value":"765"},{"label":"Веном / Venom","value":"978"},{"label":"Веселая ферма / Fun Farm","value":"1124"},{"label":"Вечная история / The Neverending Story","value":"547"},{"label":"Вечные(Фильм, 2021) / Eternal","value":"1234"},{"label":"Виви: Песнь флюоритового глаза / Vivy: Fluorite Eye's Song","value":"1819"},{"label":"Викинги / Vikings","value":"369"},{"label":"Владелец ранчо со слизью(Games) / Ранчо слизи / Slime Rancher","value":"1529"},{"label":"Властелин колец / Lord of the Ring","value":"254"},{"label":"Власть книжного червя / Honzuki no Gekokujou","value":"1399"},{"label":"Внук Мудрец / Kenjo no Mago","value":"1260"},{"label":"Внук Нурарихёна / Nurarihyon no Mago","value":"66"},{"label":"Во всеоружии / Overgeared","value":"1021"},{"label":"Во тьме(Games) / The Darkness","value":"938"},{"label":"Военная хроника маленькой девочки / Сага о злой Тане / The Saga of Tanya the Evil / \tGekijouban Youjo Senki","value":"1726"},{"label":"Возвращение в детские годы / Gaki ni Modotte Yarinaoshi!!!","value":"1031"},{"label":"Возрождение Серийного Убийцы / Rebirth Of A Serial Killer","value":"1358"},{"label":"Воинственный Бог Асура / Martial God Asura","value":"771"},{"label":"Война будущего / The Tomorrow War","value":"1174"},{"label":"Война Любовь Снег / War Love Snow","value":"1417"},{"label":"Волейбол! / Haikyuu!!","value":"697"},{"label":"Волчонок / Teen Wolf","value":"795"},{"label":"Волшебная Девушка Спецоперация Аска / Magical Girl Spec-Ops Asuka","value":"1470"},{"label":"Волшебник-воин Орфен / Majutsushi Orphen Hagure Tabi: Kimluck-hen","value":"1128"},{"label":"Волшебники / The Magicians","value":"1314"},{"label":"Волшебный учитель Нэгима! / Negima!: Magister Negi Mag","value":"1777"},{"label":"Воля второго цикла мироздания. / Will of the second cycle of the Worldifice.","value":"1036"},{"label":"Воспитание хозяина / Yours to Claim","value":"839"},{"label":"Восставший против неба / Against the Gods","value":"957"},{"label":"Восстание стражей / Хранители снов / Rise of the Guardians","value":"1488"},{"label":"Восхождение в Голливуде / I'm in Hollywood","value":"1237"},{"label":"Восхождение героя щита / The Rising of the Shield Hero","value":"103"},{"label":"Врата Штейна / Steins: Gate","value":"1044"},{"label":"Врата: там бьются наши воины / Gate: Jieitai Kanochi nite, Kaku Tatakaeri","value":"727"},{"label":"Время / In Time","value":"542"},{"label":"Всегда вялый Танака-кун / Tanaka-kun wa Itsumo Kedaruge","value":"1082"},{"label":"Всего лишь восьмой сын? Я с этим не смирюсь! / Hachinan tte, Sore wa Nai Deshou! / Eighth son, I don’t think so!","value":"1473"},{"label":"Вселенная Марвел / Marvel Universe / Marvel Comics","value":"6"},{"label":"Вселенная монстров / Monsterverse / Monster Verse","value":"905"},{"label":"Вселенная Стивена / Steven universe","value":"573"},{"label":"Вселенная Стрелы / Arrowverse","value":"488"},{"label":"Вселенная Тип Луны(Игровая компания) / Universe Type Moon","value":"1221"},{"label":"Вселенная DC / DC Universe / DC Comics","value":"36"},{"label":"Выпадение радиоактивных осадков / Fallout","value":"55"},{"label":"Выращивание онлайн / Cultivation Online","value":"1252"},{"label":"Галактическая секс-звезда / Galaxy Sex Star","value":"1539"},{"label":"Гало(Games) / Halo","value":"1338"},{"label":"Ганц / Gantz","value":"256"},{"label":"Гарем рабов в лабиринте другого мира / Slave Harem in the Labyrinth of the Other World","value":"1853"},{"label":"Гарри Поттер / Harry Potter","value":"1"},{"label":"Гвен-паук / Spider-Gwen","value":"920"},{"label":"Генерал маньяк с его сумасшедшей системой / The Maniacal General with his Crazy System","value":"1356"},{"label":"Генерал, вы вправе уйти. / General, You May Leave Now","value":"1385"},{"label":"Геншин Импакт / Genshin Impact","value":"689"},{"label":"Геркулес / Hercules","value":"721"},{"label":"Герои и замки / Heroes & Castles","value":"940"},{"label":"Герои меча и магии / Heroes of Might and Magic","value":"1002"},{"label":"Герои(телесериал) / Heroes","value":"864"},{"label":"Гильгамеш / Gilgamesh","value":"1143"},{"label":"Гинтама / Gintama","value":"129"},{"label":"Глубина(Фильм, 2002) / Below","value":"1186"},{"label":"Гнев Асуры / Asura's wrath","value":"100"},{"label":"Годзилла / Godzilla","value":"922"},{"label":"Голодные игры / The Hunger Games","value":"859"},{"label":"Горец / Highlander","value":"1761"},{"label":"Горожане(Games) / Townsmen","value":"1599"},{"label":"Госпожа Кагуя: в любви как на войне / Kaguya sama: Love is war","value":"533"},{"label":"Готика / Gothic","value":"418"},{"label":"Готов ли ты влюбиться в извращенку до тех пор, пока она милая? / Hentai demo Suki ni Natte Kuremasu ka","value":"1383"},{"label":"Гоэтия / Гоетия / Yοητεία / Ars Goetia","value":"772"},{"label":"Гравити Фолз / Gravity Falls","value":"491"},{"label":"Граница пустоты / Kara no Kyoukai","value":"1101"},{"label":"Гриффины / Family Guy","value":"349"},{"label":"Гром над небом / Thunder over the sky","value":"793"},{"label":"Гуррен-Лаганн / Tengen Toppa Gurren Lagann","value":"719"},{"label":"Да будет благословенен этот прекрасный мир! / Konosuba / Kono Subarashii Sekai ni Shukufuku wo!","value":"82"},{"label":"Да Здравствует Призыв! / Long Live Summons!","value":"948"},{"label":"Да, я паук, и что с того? / So I'm a Spider, So What? / Kumo Desu ga, Nani ka?","value":"910"},{"label":"Данганронпа / Danganronpa","value":"972"},{"label":"Две звезды Онмёджи / Sousei no Onmyouji","value":"1108"},{"label":"Дворянство / Благородство / Noblesse","value":"636"},{"label":"Девочка-волшебница Мадока Магика / Mahou Shoujo Madoka Magica","value":"1412"},{"label":"Девочка, которая видит это / Mieruko-chan","value":"1645"},{"label":"Декстер(телесериал) / Dexter","value":"1543"},{"label":"Демон Бездны всех царств / Abyss Demon of All Realms","value":"1419"},{"label":"Демоны старшей школы / High School DxD","value":"8"},{"label":"День независимости(Фильм, 1996) / Independence Day","value":"850"},{"label":"Детектив Конан / Detective Conan","value":"1554"},{"label":"Дети индиго из другого мира / Mondaiji-tachi ga isekai kara kuru sô desu yo","value":"1484"},{"label":"Джаггед Альянс 2: Агония Власти(Games) / Jagged Alliance 2","value":"1668"},{"label":"Джессика Джонс / Marvel's Jessica Jones","value":"1817"},{"label":"Джон Уик / John Wick","value":"388"},{"label":"Дисней / The Walt Disney Company","value":"503"},{"label":"Для тебя, Бессмертный / Fumetsu no Anata e / To Your Eternity","value":"1802"},{"label":"Дневник Будущего / Mirai Nikki","value":"368"},{"label":"Дневники вампира / The Vampire Diaries","value":"160"},{"label":"Доблесть рыцаря-неудачника / Chivalry of a Failed Knight","value":"1462"},{"label":"Добро пожаловать в ад, Ирума / Welcome to Demon School! Iruma-kun","value":"261"},{"label":"Добро пожаловать в класс превосходства / Classroom of the Elite","value":"122"},{"label":"Добро пожаловать! В лес похотливых эльфов! / Youkoso! Sukebe Elf no Mori e","value":"1034"},{"label":"Добывать ремесло / Майнкрафт / Minecraft","value":"102"},{"label":"Доктор Кто / Doctor Who","value":"277"},{"label":"Доктор Стоун / Dr. Stone","value":"720"},{"label":"Доля секунды: скорость / Split - second: velocity","value":"890"},{"label":"Дом кролика / Кофейня "Кроличий домик" / Gochuumon wa Usagi Desu ka?","value":"642"},{"label":"Домашний очаг / Hearthstone: Heroes of Warcraft / Hearthstone","value":"934"},{"label":"Домекано / Domestic Na Kanojo","value":"632"},{"label":"Дорогой звёзд / Звёздное преобразование / Stellar Transformation / Xing Chen Bian","value":"1155"},{"label":"Доспехи Бога 2: Операция Кондор / Armour of God II: Operation Condor","value":"1829"},{"label":"Дота 2 / Dota 2","value":"1105"},{"label":"Дофус / Dofus","value":"817"},{"label":"Дракенгард / Drakengard / Drag-On Dragoon","value":"919"},{"label":"Дракон-горничная госпожи Кобаяси / Kobayashi-san Chi no Maid Dragon","value":"673"},{"label":"Дракон-сама из семьи Касумигаока / Dragon-sama of the Kasumigaoka Family","value":"1458"},{"label":"Драконий жемчуг Зет / Dragon Ball Z","value":"307"},{"label":"Дракониум Онлайн / Draconic Online","value":"1360"},{"label":"Дракула / Dracula","value":"709"},{"label":"Древнегреческая мифология / Ancient Greek mythology","value":"1159"},{"label":"Дре́вние / Первородные / The Originals","value":"863"},{"label":"Древние свитки / The Elder Scrolls","value":"428"},{"label":"Древние свитки: Скайрим / TES: Skyrim","value":"337"},{"label":"Другой мир / Underworld","value":"480"},{"label":"Друид с Сеульской станции / Seoul Station Druid","value":"1178"},{"label":"Дьявол / Диабло / Diablo","value":"1787"},{"label":"Дьявол может плакать / Devil May Cry / DMC","value":"339"},{"label":"Дьявол Юраги-су / The Devil of Yuragi-sou","value":"431"},{"label":"Дьявол II(Games) / Диабло II / Diablo II","value":"1055"},{"label":"Дэдпул / Deadpool","value":"810"},{"label":"Дэнни-призрак / Danny Phantom","value":"109"},{"label":"Евангелион / Neon Genesis Evangelion","value":"583"},{"label":"Единство семи магов / Тринити: Семь Магов / Trinity Seven","value":"442"},{"label":"Еженедельный прыжок сёнэн / Weekly Shōnen Jump","value":"1629"},{"label":"Ёрмунганд / Jormungand","value":"77"},{"label":"Жажда скорости / Need For Speed","value":"1493"},{"label":"Железный человек / Iron Man","value":"710"},{"label":"Жемчуг дракона / Dragon Ball","value":"309"},{"label":"Женщина-Халк(телесериал) / She-Hulk: Attorney at Law","value":"1593"},{"label":"Жизнь девушки в игровом мире / A Girl’s Life In A Gaming World","value":"1406"},{"label":"Жизнь после / Days Gone","value":"1279"},{"label":"За гранью / Beyond the Boundary","value":"357"},{"label":"Загипнотизировать Семью / Kyonyuu Kazoku Saimin","value":"1032"},{"label":"Закон Уэки / The Law of Ueki","value":"790"},{"label":"Закулисье / Backrooms","value":"1827"},{"label":"Зачарованные / Charmed","value":"113"},{"label":"Защитники / Defenders","value":"1832"},{"label":"Защитница Химари / Omamori Himari","value":"279"},{"label":"Звёздная принцесса и силы зла\t / Стар против сил зла / Star vs. The Forces of Evil","value":"782"},{"label":"Звёздное дитя / Oshi no Ko","value":"1903"},{"label":"Звёздное ремесло / StarCraft","value":"386"},{"label":"Звездные Войны / Star Wars","value":"40"},{"label":"Звёздные войны: Войны клонов - Все типы носителей(мультсериал, 2008) / Star Wars: The Clone Wars","value":"1182"},{"label":"Звёздные врата / Stargate","value":"770"},{"label":"Звёздные врата: Атлантида / Stargate: Atlantis","value":"1097"},{"label":"Звездный путь / Стартрек / Star Trek","value":"849"},{"label":"Зверополис / Zootopia","value":"1449"},{"label":"Зеленая Жизнь / Green Life","value":"1196"},{"label":"Зеленый фонарь / The Green Lantern","value":"1222"},{"label":"Зетмен / Zetman","value":"1191"},{"label":"Игра в кальмара(телесериал) / Squid game","value":"1065"},{"label":"Игра престолов / Game of Thrones","value":"22"},{"label":"Игрок / The Gamer","value":"126"},{"label":"Идеальная судьба / The Perfect Destiny","value":"781"},{"label":"Идолмастер / The Idolmaster","value":"807"},{"label":"Иерихон Клайва Баркера / Иерихон / Clive Barker’s Jericho /Jericho","value":"320"},{"label":"Извивающийся дракон / Coiling Dragon","value":"692"},{"label":"Изгнаные королевства РПГ / Exiled Kingdoms RPG","value":"1375"},{"label":"Импульс Валькирии: Сирена / Варукири Дораиву: Сирена / Valkyrie Drive: Mermaid","value":"1736"},{"label":"Индекс волшебства / A Certain Magical Index","value":"68"},{"label":"Инуяша - Пес-демон / InuYasha","value":"481"},{"label":"Искусственный отбор / Triage X","value":"1037"},{"label":"Истинный мир боевых искусств / Zhenwu Shijie / True Martial World","value":"867"},{"label":"История монстров / Monogatari","value":"911"},{"label":"История о второстепенном персонаже который стал игроком в другой игре. / The story is about a minor character who became a player in another game.","value":"868"},{"label":"Кабанери железной крепости / Koutetsujou no Kabaneri","value":"1494"},{"label":"Каждый раз, когда я сплю, моя душа покидает мое тело / Every Day I Sleep, My Soul Goes Out of My Body","value":"1048"},{"label":"Как воспитать героиню из обычной девушки / Saenai Heroine no Sodatekata","value":"1637"},{"label":"Как игрок глупой FPS попал в иной мир / Как дурачок из стрелялки в другой мир попал / Manuke na FPS Player ga Isekai e Ochita Baai","value":"746"},{"label":"Как приручить дракона / How to Train Your Dragon","value":"687"},{"label":"Капитан Америка / Captain America","value":"1425"},{"label":"Капитан Марвел(Фильм, 2019) / Captain Marvel","value":"1594"},{"label":"Каратель / The Punisher","value":"387"},{"label":"Касл / Castle","value":"389"},{"label":"Касльвания / Castlevania","value":"1215"},{"label":"Катаклизм: Тёмные дни впереди / DDA / Cataclysm: Dark Days Ahead","value":"680"},{"label":"Квайзер со Стигматом / Адепт Святого Знака / The Qwaser of Stigmata","value":"72"},{"label":"Квартет из альтернативного мира / Isekai Quartet","value":"1801"},{"label":"Квест Девушки-монстра / Monster Girl Questt","value":"928"},{"label":"Квест титана(Games) / Титанический квест / Titan Quest","value":"1483"},{"label":"Кенши(Games) / Kenshi","value":"1230"},{"label":"Киберпанк 2077 / Cyberpunk 2077","value":"416"},{"label":"Ким Пять-с-плюсом / Kim Possible","value":"436"},{"label":"Киру ра Киру / Круши Кромсай / Убей или умри / Kill la Kill","value":"763"},{"label":"Класс убийц / Assassination classroom","value":"610"},{"label":"Клеймор / Claymore","value":"110"},{"label":"Клинок зла / Evil Blade / Übel Blatt","value":"722"},{"label":"Клинок королевы / Queen’s Blade","value":"757"},{"label":"Клинок Маню: Тайна сисечного свитка / Manyuu Hiken-chou","value":"501"},{"label":"Клинок рассекающий демонов / Demon Slayer: Kimetsu no Yaiba","value":"21"},{"label":"Клуб Винкс / Winx Club","value":"397"},{"label":"Книга джунглей / The Jungle Book","value":"1688"},{"label":"Князь тьмы с задней парты / Demon King Daimao / Ichiban Ushiro no Daimaou","value":"1207"},{"label":"Код Гиас / Code Geass","value":"340"},{"label":"Код Квалидеи / Qualidea Code","value":"76"},{"label":"Кольцо Элдена / Elden Ring","value":"1408"},{"label":"Комната / The Room","value":"889"},{"label":"Конь и клинок: Боевой отряд(Games) / Mount and Blade:Warband","value":"1477"},{"label":"Королевства Сердец / Kingdom Hearts","value":"407"},{"label":"Короли крестоносцев / Crusader kings","value":"572"},{"label":"Король бойцов / The King of Fighters","value":"1378"},{"label":"Король лев / The Lion king","value":"1705"},{"label":"Король Шаманов / Shaman King","value":"744"},{"label":"Корона греха / Guilty Crown","value":"1007"},{"label":"Корпорация лоботомии / Lobotomy corporation","value":"852"},{"label":"Космические рейнджеры(Games) / Space Rangers","value":"1508"},{"label":"Кошечка из Сакурасо / Sakurasou no Pet na Kanojo","value":"605"},{"label":"Красавица и чудовище / Beauty and the Beast","value":"1765"},{"label":"Красная угроза 3 / Command & Conquer: Red Alert 3","value":"742"},{"label":"Красный, Белый, Черный, Желтый / RWBY","value":"131"},{"label":"Кредо убийцы / Assassin's Creed","value":"690"},{"label":"Кризис / Crysis","value":"1734"},{"label":"Крушитель / The Breaker","value":"1080"},{"label":"Кунг-фу панда / Kung Fu Panda","value":"831"},{"label":"Кэйон! / K-On!","value":"1785"},{"label":"Кэнган Асура / Kengan Asura","value":"726"},{"label":"Лаборатория Декстера / Dexter Lab","value":"639"},{"label":"Лавкрафт / Говард Филлипс Лавкрафт / Howard Phillips Lovecraft","value":"1259"},{"label":"Легенда о восьми псах востока / Hakkenden: Touhou Hakken Ibun","value":"1699"},{"label":"Легенда о Зельде / The Legend of Zelda","value":"870"},{"label":"Легенда о Короле Драконов / Legend of the Dragon King","value":"623"},{"label":"Легенда о Легендарных Героях / Densetsu no Yuusha no Densetsu","value":"193"},{"label":"Легион Супергероев / The Legion of Super-Heroes","value":"450"},{"label":"Леди Баг и Супер-Кот / Miraculous Ladybug","value":"327"},{"label":"Летняя сага / Summertime Saga","value":"1441"},{"label":"Лига Легенд / League of Legends","value":"65"},{"label":"Линия фронта для девочек / Girls' Frontline","value":"1686"},{"label":"Литературный клуб Доки Доки / Литературный клуб / Doki Doki literature club!","value":"819"},{"label":"Лорд героев(Games) / Lord of Heroes","value":"1771"},{"label":"Лорд человечества / Lord of the People","value":"1896"},{"label":"Лориенская Сага / Lorien Legacies","value":"521"},{"label":"Любимая жена господина генерального директора / Mr.CEO's Beloved Wife","value":"1389"},{"label":"Любовные неприятности / To love ru","value":"353"},{"label":"Любовь, Деньги, Рок-н-Ролл / Love, Money, Rock'n'Roll","value":"1890"},{"label":"Люди в чёрном(Фильм) / Men in Black","value":"1193"},{"label":"Люди Икс / X-Men","value":"371"},{"label":"Лютер Строуд Сага / The Luther Strode Saga","value":"1700"},{"label":"Люцифер(телесериал) / Lucifer","value":"681"},{"label":"Маг на полную ставку / Quanzhi Fashi","value":"291"},{"label":"Маг смерти не желающий четвертой реинкарнации / The Death Mage Who Doesn’t Want a Fourth Time","value":"1775"},{"label":"Маг-целитель: Новый старт / Kaifuku Jutsushi no Yarinaoshi","value":"1311"},{"label":"Маги: Волшебный лабиринт / Magi: The Labyrinth of Magic","value":"1581"},{"label":"Магистр дьявольского культа / The Grandmaster of Demonic Cultivation","value":"608"},{"label":"Магическая академия Атараксия: Гибрид х Сердце / Hybrid x Heart Magias Academy Ataraxia","value":"1898"},{"label":"Магическая битва / Magic Battle / Jujutsu Kaisen","value":"671"},{"label":"Маленькие кошмары 2 / Little Nightmares 2","value":"601"},{"label":"Малефисента / Maleficent","value":"775"},{"label":"Мальчик с оленьими рогами / Сладкоежка / Sweet tooth","value":"1772"},{"label":"Маска / The mask","value":"847"},{"label":"Мастер Урадана / The Master of Uradan","value":"1395"},{"label":"Мастера меча онлайн / Sword Art Online / SAO","value":"324"},{"label":"Межвидовые Рецензенты / Interspecies Reviewers","value":"1555"},{"label":"Менеджер среднего звена Тонэгава / Chuukan Kanriroku Tonegawa","value":"1084"},{"label":"Мерлин / Merlin","value":"486"},{"label":"Мертвы к Рассвету / Dead by Daylight","value":"899"},{"label":"Мертвый или живой / Dead or Alive","value":"1563"},{"label":"Мертвый остров / Dead Island","value":"124"},{"label":"Месть Масамуне-куна! / Masamune-kun no Revenge","value":"571"},{"label":"Метавселенная Рудазова / Rudazov's Metauniverse","value":"1211"},{"label":"Метро 2033(Games) / Metro 2033","value":"1584"},{"label":"Милый во Франксе / Любимый во Франксе / Darling in the Franxx","value":"942"},{"label":"Мир боевых искусств / 武极天下 / Wuji Tianxia / Martial World","value":"620"},{"label":"Мир зомби / Zombie World","value":"1880"},{"label":"Мир Льда и Пламени / The World of Ice & Fire","value":"415"},{"label":"Мир приключений Джеки Чана(мультсериал, 2000) / ackie Chan Adventures","value":"1544"},{"label":"Мир танков / WoT Blitz / World of Tanks Blitz","value":"525"},{"label":"Мир Тьмы / World of Darkness","value":"145"},{"label":"Мир Эрастай / The World of Erasthay","value":"1836"},{"label":"Мир Warcraft / World of Warcraft","value":"89"},{"label":"Мировая война Z / Война миров Z / World War Z","value":"1217"},{"label":"Моана / Moana","value":"686"},{"label":"Моб психо 100 / Mob Psycho 100","value":"866"},{"label":"Мобильные легенды: Бах-Бах(Games) / Mobile Legends: Bang Bang","value":"1497"},{"label":"Могучие рейнджеры / Power Rangers","value":"1486"},{"label":"Может, я встречу тебя в подземелье? / DanMachi","value":"9"},{"label":"Мой жених сбежал / My Groom Ran Away","value":"1047"},{"label":"Мой маленький пони / My Little Pony","value":"655"},{"label":"Мой маленький пони: Дружба — это чудо / My Little Pony: Friendship is Magic","value":"658"},{"label":"Мой шумный дом(мультсериал, 2016) / The Loud House","value":"1467"},{"label":"Монстер Хай / Monster High","value":"1012"},{"label":"Моя возлюбленная чпокается со всеми / Kanojo wa Dare to demo Sex Sur","value":"1274"},{"label":"Моя геройская академия / Boku no Hero Academia","value":"69"},{"label":"Моя девушка - зомби / My Girlfriend is a Zombie","value":"754"},{"label":"Моя жена - красивый генеральный директор / My Wife is a Beautiful CEO","value":"1025"},{"label":"Моя жена — президент студенческого совета! / My Wife is the Student Council President / Okusama ga Seitokaichou","value":"241"},{"label":"Моя Марвел Академия / My marvel academia","value":"696"},{"label":"Моя первая модница / Hajimete no Gal","value":"1835"},{"label":"Моя Супер-Бывшая / My Super Ex-Girlfriend","value":"1828"},{"label":"Мрачный рассвет / Grim Dawn","value":"1113"},{"label":"Мстители / The Avengers","value":"1747"},{"label":"Мстители. Эра Альтрона / The Avengers. Age of Ultron","value":"784"},{"label":"Мулан / Mulan","value":"706"},{"label":"Мы не можем учится / Bokutachi wa Benkyou ga Dekinai","value":"912"},{"label":"Мэй Гунцин / Mei Gongqing","value":"753"},{"label":"Наблюдать / Overwatch","value":"607"},{"label":"Надпись / Inscription","value":"1718"},{"label":"Нам Ён / Nam Yeon","value":"1188"},{"label":"Наруто / Naruto","value":"3"},{"label":"Начало после конца / The Beginning After The End","value":"888"},{"label":"Не голодай / Don't Starve","value":"274"},{"label":"Не издевайся надо мной, Нагаторо / Ijiranaide / Nagatoro-san Don't Toy with Me, Miss Nagatoro","value":"1041"},{"label":"Не люблю боль, так что вкачаю все в защиту / Itai no wa Iya nano de Bougyoryoku ni Kyokufuri Shitai to Omoimasu","value":"517"},{"label":"Не моя вина, что я непопулярна! / Watashi ga Motenai no wa Dou Kangaetemo Omaera ga Warui","value":"1381"},{"label":"Небесный замок Лапута / Tenkuu no Shiro Laputa","value":"1109"},{"label":"Невероятные приключения ДжоДжо / JoJo's Bizarre Adventure","value":"20"},{"label":"Негодник, которому не снилась девочка-зайка / Rascal Does Not Dream of Bunny Girl Senpai","value":"1897"},{"label":"Негодяй спасает мужскую роль / The Villain Saves the Male Lead","value":"1224"},{"label":"Неизвестен / Persona","value":"205"},{"label":"Некий магический индекс / To Aru Majutsu no Index","value":"562"},{"label":"Некий научный акселератор / Toaru Kagaku no Accelerator","value":"1487"},{"label":"Ненасытный Берсерк / Boushoku no Berserk: Ore dake Level to Iu Gainen wo Toppa suru the Comic","value":"1195"},{"label":"Необъятные небеса / Infinite Stratos / IS","value":"280"},{"label":"Необъятный океан / Grand Blue","value":"531"},{"label":"Непревзойденная / Master Piece The Animation","value":"712"},{"label":"Непризнанный школой владыка демонов / Maou Gakuin no Futekigousha","value":"1476"},{"label":"Непутевый ученик в школе магии / Mahouka Koukou No Rettousei","value":"982"},{"label":"Непутевый ученик в школе магии / The Irregular at Magic High School","value":"630"},{"label":"Несокрушимая механическая кукла / Machine-Doll wa Kizutsukanai","value":"1030"},{"label":"Несправедливость / Injustice","value":"1026"},{"label":"Нет игры - нет жизни / Без игры жизни нет / No Game No Life","value":"718"},{"label":"Неуязвимый / Invincible","value":"702"},{"label":"НиоХ(Games) / NioH","value":"1465"},{"label":"Новый завет Владыки тьмы / Shinmai Maou no Testament","value":"1432"},{"label":"Ну и ну! Земляничные яйца / I My Me! Strawberry Eggs","value":"1485"},{"label":"Нулевой Уровень Целомудрия / Teisou Kannen Zero","value":"1209"},{"label":"О моём перерождении в меч / Tensei Shitara Ken deshita","value":"53"},{"label":"О моём перерождении в слизь / Tensei shitara Slime Datta Ken","value":"64"},{"label":"О моя Богиня / Aa! Megami-sama! / Ah! My Goddess","value":"915"},{"label":"Обесчещенный(Games) / Dishonored","value":"1073"},{"label":"Обитель зла / Resident Evil","value":"86"},{"label":"Огненная эмблема / Fire Emblem","value":"1615"},{"label":"Огненная эмблема: Пробуждение / Fire Emblem: Awakening","value":"1616"},{"label":"Огненная эмблема: Три Дома / Fire Emblem:Three Houses","value":"1716"},{"label":"Одинокий рокер! / Bocchi the Rock!","value":"1904"},{"label":"Одному лишь Богу ведомый мир / World God Only Knows","value":"1248"},{"label":"Она становится гламурной после расторжения помолвки / She gets glamorous after the engagement is annulled","value":"1404"},{"label":"Орк-рубака / Orc Grunt","value":"779"},{"label":"Освободите эту ведьму / Release that witch","value":"994"},{"label":"Острые козырьки(телесериал) / Peaky Blinders","value":"1177"},{"label":"От заката до рассвета! / From Dusk till Dawn!","value":"1416"},{"label":"Отброс из семьи графа / Trash of counts family","value":"853"},{"label":"Отряд самоубийц / The Suicide Squad","value":"1844"},{"label":"Отчаянные домохозяйки / Desperate Housewives","value":"1011"},{"label":"Отчет о буйстве духов / YuYu Hakusho","value":"1008"},{"label":"Охота демонического короля на свою жену / Xie Wang Zhui Qi","value":"1737"},{"label":"Охотник х Охотник / Hunter x Hunter","value":"101"},{"label":"Охотницы на демонов / Taimanin Asagi","value":"1463"},{"label":"Очень приятно Бог! / Kamisama Hajimemashita","value":"1585"},{"label":"Очень Странные Дела(телесериал) / Stranger Things","value":"1834"},{"label":"ПАЗЛ / PUZZLE","value":"1762"},{"label":"Палач Рока / DOOM","value":"132"},{"label":"Параграф 78(Фильм) / Paragraph 78","value":"923"},{"label":"Паразит: Учение о жизни / Parasyte: The Maxim","value":"1176"},{"label":"Пастырь(Фильм, 2011) / Priest","value":"1173"},{"label":"Пацаны / The Boys","value":"133"},{"label":"Первый детский сад во вселенной / The First Kindergarten in the Universe","value":"1049"},{"label":"Перевозчик / Le Transporteur","value":"365"},{"label":"Передающийся через кровь / Bloodborne","value":"229"},{"label":"Пережить / Outlast","value":"645"},{"label":"Перерождение / Rebirth","value":"550"},{"label":"Перерождение бессмертного горожанина-культиватора / Rebirth – City Cultivation / Rebirth of the Urban Immortal Cultivator","value":"843"},{"label":"Перерождение в монстра / Re:Monster","value":"85"},{"label":"Перестрой мир / Sekai O Sai Kochiku / Rebuild World","value":"961"},{"label":"Период полураспада(Valve) / Half-Life","value":"895"},{"label":"Перси Джексон / Percy Jackson","value":"308"},{"label":"Персона 5 / Persona 5","value":"1614"},{"label":"Печать ветра / Kaze no Stigma","value":"845"},{"label":"Пик боевых искусств / Martial Peak","value":"414"},{"label":"Пираты Карибского моря / Pirates of the Caribbean","value":"932"},{"label":"Пираты черной лагуны / Black Lagoon","value":"621"},{"label":"Пламенная бригада пожарных / Fire Force / Enen no Shouboutai","value":"841"},{"label":"Пламя бесчисленых невзгод / I' m really not demon god's lackey","value":"1452"},{"label":"Планетарная аннигиляция / Planetary Annihilation","value":"487"},{"label":"Плоскостной пейзаж: Мучение / Planescape: Torment","value":"1768"},{"label":"По велению адской сестры / The Testament of Sister New Devil","value":"18"},{"label":"Поборники тьмы / Darksiders","value":"1028"},{"label":"Повар небесной гостиницы / Чем кормят в ином мире / Kakuriyo no Yadomeshi","value":"998"},{"label":"Повар-боец Сома / В поисках божественного рецепта / Shokugeki no Souma","value":"191"},{"label":"Повелитель тьмы на подработке! / Hataraku Maou-sama!","value":"674"},{"label":"Повелитель тьмы: Другая история мира / How Not to Summon a Demon Lord / Isekai Maou to Shoukan Shoujo no Dorei Majutsu","value":"699"},{"label":"Повелитель(Куганэ Маруяма) / Overlord","value":"27"},{"label":"Повелитель(Games) / Overlord","value":"1623"},{"label":"Повесть о Конце Света / Record of Ragnarok","value":"332"},{"label":"Повесть о лунной принцессе / Tsukihime: Lunar Legend","value":"750"},{"label":"Повесть о Небесных островах / Фэнтези Гранблю / Granblue Fantasy","value":"808"},{"label":"Повседневная жизнь бессмертного короля / The Daily Life of the Immortal King / Xian Wang de Richang Shenghuo","value":"1466"},{"label":"Повседневная жизнь с девушкой-монстром / Monster Musume","value":"760"},{"label":"Пограничье(Games) / Borderlands","value":"992"},{"label":"Под лунами Драконьих глаз / Beneath the Dragoneye Moons","value":"1735"},{"label":"Подземелья и драконы / Dungeons & Dragons","value":"81"},{"label":"Подземная история / Андертейл / Undertale","value":"390"},{"label":"Поднявшийся(Games) / Risen","value":"1273"},{"label":"Поднятие уровня в одиночку / Solo Leveling","value":"127"},{"label":"Подручный Луизы-Нулизы / Zero no Tsukaima","value":"580"},{"label":"Пожиратель богов / God Eater","value":"1321"},{"label":"Поймай себя ! Моя дорогая жена / Catch You ! My Dear Wife","value":"1317"},{"label":"Покемон / Pokemon","value":"43"},{"label":"Политическая Хроника Молодой Девушки / A Young Woman's Political Record","value":"1306"},{"label":"Полностью пленённые / Totally Captivated","value":"1086"},{"label":"Полый Рыцарь(Games) / Hollow Knight","value":"1198"},{"label":"Пользователи Силы / Forceusers","value":"1162"},{"label":"Поля битвы Неизвестного игрока / ПАБГ / Player Unknown's Battlegrounds / PUBG","value":"622"},{"label":"Попытка приручить злого повелителя / Trying to Tame an Evil Overlord","value":"983"},{"label":"Поработитель Ада / Helltaker","value":"776"},{"label":"Порновселенная / Porn Universe","value":"1776"},{"label":"Портал(Valve) / Portal","value":"800"},{"label":"Последние из нас / Last Of Us","value":"1717"},{"label":"Последний Серафим / Owari no Seraph","value":"551"},{"label":"Последняя из рода Блау(Тайга Ри) / The last of the Blau family","value":"1507"},{"label":"Последняя фантазия / ファイナルファンタジ / Final Fantasy","value":"769"},{"label":"Преподобное безумие / Reverend Insanity","value":"1280"},{"label":"Преподобный Гу / Gu Zhen Ren / Daoist Gu","value":"1464"},{"label":"Призрачный бегун / Ghostrunner","value":"613"},{"label":"Призрачный гонщик / Ghost Rider","value":"823"},{"label":"Принц Драконов Хаоса / The Chaos Dragon Prince","value":"1397"},{"label":"Принц Персии / Prince of Persia","value":"1535"},{"label":"Принцесса монстров / Princess Resurrection","value":"1304"},{"label":"Принцесса Цу / Не проиграю! / Maken Ki","value":"675"},{"label":"Проект „Восток“ / Touhou Project","value":"809"},{"label":"Проект Кей / K Project","value":"73"},{"label":"Проклятие: Автоматизация / NieR:Automata","value":"1496"},{"label":"Противостояние святого / Renegade Immortal","value":"926"},{"label":"Прототип / Prototype","value":"54"},{"label":"Пуленепробиваемый / Bang-Tan / BTS","value":"520"},{"label":"Путешествие на Запад / Journey to the West","value":"1833"},{"label":"Пять невест / Go-Toubun no Hanayome","value":"713"},{"label":"Пять ночей у Фредди / Five nights at freddy's","value":"930"},{"label":"Рагнарёк Онлайн / Ragnarok Online","value":"953"},{"label":"Радуга 6: Осада / Rainbow Six: Siege","value":"421"},{"label":"Развращение Дочери / Daraku Reijou Hakoiri Ojou-sama Netorare Choukyou Kiroku","value":"1284"},{"label":"Рай Грисайи / Эдем в серых тонах / Grisaia no Rakuen","value":"584"},{"label":"Рандеву с жизнью / Date A live","value":"851"},{"label":"Ранма ½ / Ranma ½","value":"1192"},{"label":"Рапунцель: Запутанная история / Tangled","value":"773"},{"label":"Расколотая битвой синева небес / Battle Through the Heavens","value":"927"},{"label":"Рассказ служанки / The Handmaid's Tale","value":"1135"},{"label":"Расхитительница гробниц / Tomb Raider","value":"988"},{"label":"Резатель / Лангриссер / Langrisser","value":"792"},{"label":"Реинкарнация безработного / Mushoku Tensei","value":"569"},{"label":"Реинкарнация Богини / Megami Tensei","value":"1161"},{"label":"Репликант НиеР / NieR Replicant / NieR Gestalt","value":"1299"},{"label":"Рецеттия: Повесть о магазине предметов / Recettear: An Item Shop's Tale","value":"858"},{"label":"Ривердэйл / Riverdale","value":"637"},{"label":"Рик и Морти / Rick and Morty","value":"315"},{"label":"Розарий и Вампир / Rosario+Vampire","value":"83"},{"label":"Розовая пора моей школьной жизни сплошной обман / Yahari Ore no Seishun Love Come wa Machigatteiru","value":"856"},{"label":"Рок шоу! / Show By Rock!!","value":"344"},{"label":"Русалочка / The Little Mermaid","value":"892"},{"label":"Рыцарь и маг / Knight's & Magic","value":"1491"},{"label":"Сага о Винланде / Vinland Saga","value":"1200"},{"label":"Садистская смесь / Blend S","value":"1120"},{"label":"Сайт волшебниц / Mahou Shoujo Site","value":"909"},{"label":"Сверхъестественное(телесериал) / Supernatural","value":"916"},{"label":"Связь принцесс: повторное погружение / Princess Connect! Re:Dive","value":"1481"},{"label":"Святые / Saints Row","value":"1390"},{"label":"Сейлор Мун / Sailor Moon","value":"114"},{"label":"Секире: Тени Умирают Дважды / Sekiro: Shadows Die Twice","value":"1076"},{"label":"Семь смертных грехов / Nanatsu no Taizai","value":"61"},{"label":"Семья шпиона / Spy x Family","value":"1646"},{"label":"Сердца Пандоры / Pandora Hearts","value":"497"},{"label":"Серия Метроидов / Metroid Series","value":"1612"},{"label":"Серый человек / Ди: Гурэйман / D.Gray-man","value":"367"},{"label":"Си Тянь Гуань / Si Tian Guan","value":"1189"},{"label":"Сильнейший в истории ученик Кэнити / Shijou Saikyou no Deshi Kenichi","value":"242"},{"label":"Сильнейший в истории ученик Кэнъити / KenIchi: The Mightiest Disciple","value":"745"},{"label":"Сильнейший магнат / The Strongest Tycoon","value":"1340"},{"label":"Сильнейший мудрец низшей эмблемы / Shikkakumon no Saikyou Kenja","value":"1472"},{"label":"Симпсоны / The Simpsons","value":"1461"},{"label":"Симс / The Sims","value":"654"},{"label":"Симфония морской стали / Aoki Hagane no Arpeggio","value":"958"},{"label":"Сингулярность(Games) / Singularity","value":"1793"},{"label":"Синий Архив / Blue Archive","value":"1411"},{"label":"Синий экзорцист / Blue Exorcist","value":"312"},{"label":"Синяя Тюрьма: Блю Лок / Blue Lock","value":"1792"},{"label":"Система Богов и Демонов / God and Devil World","value":"1648"},{"label":"Система Спаси-Себя-Сам / The Scum Villain's Self-Saving System: Ren Zha Fanpai Zijiu Xitong","value":"1505"},{"label":"Система: Восьмой уровень(Д. Серебряков) / System: Eighth level","value":"1175"},{"label":"Сисястая Принцесса под гипнозом / Kyonyuu Princess Saimin","value":"1618"},{"label":"Сказание о Демонах и Богах / Tales of Demons and Gods","value":"59"},{"label":"Сказание о Тёмном Рыцаре ~ Призван, чтобы одолеть Героя ~ / Tale of Dark Knight~Summoned to Defeat The Hero~","value":"1647"},{"label":"Сказки хранителей(Games) / Guardian tales","value":"1068"},{"label":"Скрытая Похотливая Натура Моих Русских Сестренок и Мачехи / Muttsuri do Sukebe ro Gibo Shimai","value":"1282"},{"label":"Скуби-Ду / Scooby-Doo","value":"638"},{"label":"Скучный мир, где не существует самой идеи похабных шуток / Shimoneta to Iu Gainen ga Sonzai Shinai Taikutsu na Sekai","value":"830"},{"label":"Сладкая жизнь / Happy Sugar Life","value":"1099"},{"label":"Сладкий флирт / Amour Sucré / Sweet Crush","value":"495"},{"label":"Сладости и Сигареты / Candy & Cigarettes","value":"778"},{"label":"Следопыт Гнев Праведников / Pathfinder Wrath Of The Righteous","value":"1077"},{"label":"Следопыт: Творец королей / Pathfinder: Kingmaker","value":"1770"},{"label":"Смертельная битва / Мортал Комбат / Mortal Kombat","value":"806"},{"label":"Смертельный укус","value":"1902"},{"label":"Созданный в бездне / Made in Abyss","value":"952"},{"label":"Сок джунглей","value":"1901"},{"label":"Сокрушитель: Новые волны / The Breaker: New Waves","value":"1500"},{"label":"Соник еж / Sonic the hedgehog","value":"1052"},{"label":"Сорвиголова / Daredevil","value":"1690"},{"label":"Сотня / Hundred","value":"885"},{"label":"Спаун / Spawn","value":"1254"},{"label":"Спецагент Арчер / Archer","value":"624"},{"label":"Специалист по апгрейду из другого мира / Endless Sea of Clouds ESC","value":"1499"},{"label":"Спираль / Удзумаки / Uzumaki","value":"1164"},{"label":"СТАЛКЕР / STALKER / S.T.A.L.K.E.R","value":"677"},{"label":"Стальная тревога / Full Metal Panic! The Second Raid","value":"1489"},{"label":"Стальной алхимик / Fullmetal Alchemist","value":"1123"},{"label":"Стальной Гигант / The Iron Giant","value":"1241"},{"label":"Становление богом / Bai Lian Cheng Shen","value":"1315"},{"label":"Старгерл / Stargirl","value":"1137"},{"label":"Стелларис / Stellaris","value":"1098"},{"label":"Сторожевые Псы / Watch Dogs","value":"1886"},{"label":"Стражи Галактики / Guardians of the Galaxy","value":"1426"},{"label":"Страна Самоцветов / Houseki no Kuni","value":"1305"},{"label":"Страна чудес смертников / Зона-парк смертников / Deadman Wonderland","value":"857"},{"label":"Страношары / Кантриболз / Countryballs","value":"1895"},{"label":"Студии 20-й век / 20th Century Studios","value":"1715"},{"label":"Судьба / Fate","value":"1740"},{"label":"Судьба: Апокриф / Fate: Apocrypha","value":"231"},{"label":"Судьба: Великий Орден / Fate: Grand Order","value":"60"},{"label":"Судьба: Девочка волшебница Илия / Fate: Kaleid Liner Prisma","value":"789"},{"label":"Судьба: Истоки / Fate: Zero","value":"230"},{"label":"Судьба: Ночь схватки / Fate: Stay Night","value":"536"},{"label":"Сумерки / Twilight","value":"471"},{"label":"Супер ген бога / Super God Gene","value":"316"},{"label":"Супер Марио / Super Mario","value":"1661"},{"label":"Супергёрл(телесериал, 2015) / Supergirl","value":"1088"},{"label":"Супермедицинский ниндзя / Super medical ninja","value":"1391"},{"label":"Суперсемейка / The Incredibles","value":"306"},{"label":"Сэкирэй / Sekirei","value":"111"},{"label":"Тада не может влюбиться! / Tada-kun wa koi wo shinai!","value":"1905"},{"label":"Тайны Смолвиля / Smallville","value":"449"},{"label":"Танец клинка Элементалиста / Seireitsukai no Blade Dance","value":"1498"},{"label":"Твоя апрельская ложь / Your lie in april","value":"532"},{"label":"Те, кто охотятся на эльфов / エルフを狩るモノたち / Those Who Hunt Elves","value":"1168"},{"label":"Темнейшее подземелье / Darkest dungeon","value":"1405"},{"label":"Темные Души / Dark Souls","value":"200"},{"label":"Темный Ангел / Dark Angel","value":"1010"},{"label":"Тёмный Дворецкий / Kuroshitsuj / Dark Butler","value":"411"},{"label":"Темный дворецкий / Kuroshitsuji","value":"1043"},{"label":"Темный призыватель Апокалипсиса / The Dark Summoner of the Apocalypse","value":"1407"},{"label":"Тень ежа / Ёж Шэдоу / Shadow the hedgehog","value":"796"},{"label":"Терминатор / The Terminator","value":"759"},{"label":"Террарий / Terraria","value":"805"},{"label":"Тетрадь смерти / Death Note","value":"78"},{"label":"Тибериумные войны / Tiberium Wars","value":"1893"},{"label":"Титаник / Titanic","value":"1842"},{"label":"Тихий Холм / Сайлент Хилл / Silent Hill","value":"848"},{"label":"Тихоокеанский рубеж / Pacific Rim","value":"832"},{"label":"Тогайну но Чи ~Потерял кровь~(Games) / Togainu no Chi ~Lost Blood~","value":"1540"},{"label":"Токийские вороны / Tokyo Ravens","value":"836"},{"label":"Токийские мстители / Tokyo Revengers","value":"1064"},{"label":"Токийский Гуль / Tokyo Ghoul","value":"271"},{"label":"Тор / Thor","value":"764"},{"label":"Торико / Toriko","value":"342"},{"label":"Точка зрения Всеведущего читателя / Omniscient Reader’s Viewpoint","value":"1872"},{"label":"Трансформеры / Transformers","value":"117"},{"label":"Трес Наварра / Tres Navarre","value":"1197"},{"label":"Три Икса / xXx","value":"364"},{"label":"Трон: Восстание / Tron: Uprising","value":"1887"},{"label":"Тропико / Tropico","value":"694"},{"label":"Ты единственная, кто любит Великого Меня / Ore wo Suki nano wa Omae dake ka yo","value":"1818"},{"label":"Ты же любишь мамочку, удары которой бьют по площади двойным уроном? / Tsuujou Kougeki ga Zentai Kougeki de Ni-kai Kougeki no Okaasan wa Suki Desu ka?","value":"333"},{"label":"Тэнти - лишний! / Tenchi Muyo","value":"1316"},{"label":"У Коми-сан проблемы с общением / 古見さんは、コミュ症です / Komi Can't Communicate","value":"591"},{"label":"У меня мало друзей / Boku wa Tomodachi ga Sukunai","value":"1506"},{"label":"Убийца Акаме / Akame ga Kill","value":"30"},{"label":"Убийца Брайан / Carl Robert Brown","value":"1092"},{"label":"Убийца гоблинов / Goblin slayer","value":"803"},{"label":"Удар крови / Very AU strike the blood","value":"1255"},{"label":"Уж не зомби ли это? / Kore wa Zombie Desu ka?","value":"725"},{"label":"Уличный боец(Games) / Суторито Фаита / Street Fighter","value":"1203"},{"label":"Ультрафиолет / Ultraviolet","value":"1831"},{"label":"Усио и Тора / Ushio and Tora","value":"1501"},{"label":"Утраченное небесами / Sora no Otoshimoto / Lost Property of the Sky","value":"627"},{"label":"Ученик Мудреца / Kenja no Deshi wo Nanoru Kenja","value":"1474"},{"label":"Ученик чародея / The Sorcerer's Apprentice","value":"862"},{"label":"Ученики(Games) / Disciples","value":"1478"},{"label":"Учитель Хокаге / Hokage Master","value":"1319"},{"label":"Учитель-мафиози Реборн! / Katekyo Hitman Reborn!","value":"134"},{"label":"Ушастые Друзья / Kemono Friends","value":"578"},{"label":"Фальшивая любовь / Nisekoi","value":"1103"},{"label":"Фантастическая четвёрка / Fantastic Four","value":"625"},{"label":"Фантастические твари и где они обитают / Fantastic Beasts and Where to Find Them","value":"246"},{"label":"Финес и Ферб / Phineas and Ferb","value":"898"},{"label":"Флотская коллекция / Kantai Collection","value":"1194"},{"label":"Флэш / The Flash","value":"1136"},{"label":"Фонд SCP / SCP / SCP Foundation","value":"822"},{"label":"Форма голоса / A Silent Voice","value":"1100"},{"label":"Форсаж / The Fast and the Furious","value":"363"},{"label":"Фронт кровавой блокады / Кровавый круг - линия фронта / Kekkai Sensen / Blood Blockade Battlefront","value":"794"},{"label":"Футадом мир / Futadom world","value":"984"},{"label":"Халк / Hulk","value":"973"},{"label":"Хвост Феи / Fairy Tail","value":"13"},{"label":"Хеллбой / Hellboy","value":"1171"},{"label":"Хеллсинг: Война с нечистью / Hellsing","value":"116"},{"label":"Хикару и го / Hikaru no Go","value":"1121"},{"label":"Хищник / Predator","value":"747"},{"label":"Хоббит(Дж. Р. Р. Толкина) / The Hobbit(John R.R. Tolkien)","value":"1127"},{"label":"Ходячие мертвецы / The Walking Dead","value":"704"},{"label":"Холодное сердце / Frozen","value":"633"},{"label":"Хонкай удар / Honkai impact","value":"1332"},{"label":"Хранители Пандоры / The guardians of Pandora","value":"1187"},{"label":"Хранитель вечности / UQ Holder","value":"1469"},{"label":"Хроники Акаши / Rokudenashi Majutsu Koushi to Akashic Records","value":"1166"},{"label":"Хроники Ксенобладания / Дзэнобурэйдо / Xenoblade Chronicles","value":"1110"},{"label":"Хроники Миров(Е. Лукин) / Chronicles of the Worlds(E. Lukin)","value":"346"},{"label":"Хроники расхитителей гробниц / Даому Биджи / Grave Robbery Note / Dao Mu Bi Ji / Daomu Biji","value":"724"},{"label":"Хроники Ренегата / The Renegade Chronicles","value":"1225"},{"label":"Царь Горы / The Gog of the Highschool","value":"1285"},{"label":"Чародейки / W.I.T.C.H.","value":"118"},{"label":"Человек — бензопила / Chainsaw Man","value":"797"},{"label":"Человек — летучая мышь / Бэтмен / Bat-man / Batman","value":"440"},{"label":"Человек одного удара / Ванпанчмен / One Punch-Man","value":"70"},{"label":"Человек-паук / Spider-Man","value":"326"},{"label":"Чемпион! / Campione!","value":"534"},{"label":"Червь(Джон Маккрей) / Worm(John C. McCrae(Wildbow))","value":"700"},{"label":"Черная Пантера(Фильм, 2018) / Black Panther","value":"1605"},{"label":"Черновик(С.Лукьяненко) / Draft","value":"1023"},{"label":"Чернокнижник в Мире Магов / Варлок / Warlock","value":"635"},{"label":"Чёрные души / Black Souls","value":"1439"},{"label":"Чёрный зверь / Чёрный Пёс / Kuroinu","value":"755"},{"label":"Чёрный зверь: Развращение Благородных Воительниц / Black Beast: Corruption of the Noble Warriors","value":"1733"},{"label":"Чёрный клевер / Black Clover","value":"11"},{"label":"Что такое настоящий мир? / What is real peace?","value":"1336"},{"label":"Чудачества любви не помеха! / Chuunibyou Demo Koi ga Shitai!","value":"1719"},{"label":"Чужой / Чужие / Aliens","value":"1791"},{"label":"Чужой / Alien","value":"748"},{"label":"Чума инкорпорейтед / Plague Inc","value":"125"},{"label":"Шазам! / Shazam!","value":"1560"},{"label":"Шальной последний босс появился! / A Wild Last Boss Appeared!","value":"968"},{"label":"Шальные девчонки / Girl the Wild's","value":"965"},{"label":"Шан Чи и легенда десяти колец / Shang-Chi and the Legend of the Ten Rings","value":"1424"},{"label":"Шарлотта / Charlotte","value":"71"},{"label":"Шерлок (ВВС) / Sherlock","value":"492"},{"label":"Шестерни войны / Gears of War","value":"1346"},{"label":"Школа мертвецов / Highschool of the Dead","value":"98"},{"label":"Школа строгого режима / Prison School","value":"676"},{"label":"Школьные воины / Сила тысячи / Ikki Tosen","value":"818"},{"label":"Шрек(мультфильм) / Шрэк / Shrek","value":"1586"},{"label":"Шухер, у нас новый студент / Transfer Student The Storm Bringer","value":"628"},{"label":"Эволюционировать(Games) / Evolve","value":"1789"},{"label":"Эволюция. Естественный Отбор / Game Evolution","value":"287"},{"label":"Эльсворд: Эль-ий Йоин / Elsword","value":"199"},{"label":"Эльфийская песнь / Elfen Lied","value":"1899"},{"label":"Эпоха Драконов / Dragon Age","value":"253"},{"label":"Эр Ген Я запечатаю небеса / ISSTH / Er Gen I shall seal the heavens","value":"1170"},{"label":"Эрагон(Кристофер Паолини) / Eragon","value":"417"},{"label":"Эроманга-сэнсэй / Ero-manga Sensei","value":"1094"},{"label":"Эстетика заблудшего героя / Hagure Yuusha no Aesthetica","value":"1310"},{"label":"Эта гяру будет встречаться с отаку через 100 дней. / 100-nichigo ni Otaku-kun to Tsukiau Gal","value":"1246"},{"label":"Эта фарфоровая кукла влюбилась / Sono Bisque Doll wa Koi wo Suru My Dress-Up Darling","value":"1335"},{"label":"Это не Гарри Поттер / This is not Harry Potter","value":"1219"},{"label":"Этот герой неуязвим, но очень осторожен / This Hero Is Invincible but Too Cautious","value":"1276"},{"label":"Эффект массы / Mass Effect","value":"213"},{"label":"Эхо пули / Bullet Echo","value":"1523"},{"label":"Югио: Дуэльные монстры / Yu-Gi-Oh","value":"1814"},{"label":"Югио! Вреинс / Yu-Gi-Oh! VRAINS","value":"1888"},{"label":"Юна из гостиницы Юраги / Yuuna of Yuragi Manor","value":"493"},{"label":"Юная Лига Справедливости / Young Justice","value":"1020"},{"label":"Юные Титаны / Teen Titans","value":"420"},{"label":"Я - Четвертый / I Am Number Four","value":"590"},{"label":"Я Король-Волшебник / I Am The Sorcerer King","value":"1292"},{"label":"Я мачеха, но моя дочь слишком милая / I'm stepmother but daughter is too cute","value":"777"},{"label":"Я не родился счастливчиком / I Wasn’t Born Lucky","value":"996"},{"label":"Я получил читерские способности в другом мире и стал экстраординарным в реальном мире / I Got a Cheat Skill in Another World and Became Unrivaled in The Real World, Too","value":"1900"},{"label":"Я стала потерянной дочерью злодея / I Became the Villain’s Lost Daughter","value":"1387"},{"label":"Ядерный трон / Nuclear Throne","value":"1456"},{"label":"Ярость [Пересмотрено] / Rage [Revised]","value":"1337"},{"label":"Ящик предложений Мэдаки / Medaka box","value":"874"},{"label":"Cказка для Дьявола / Tale For Satan","value":"1271"},{"label":"D&D стиль / D&D style","value":"1289"},{"label":"Dying Light 2: Stay Human","value":"1906"},{"label":"Fallout: Нью-Вегас / Fallout: New Vegas","value":"1249"},{"label":"Re: Жизнь в альтернативном мире с нуля / Re: Zero, Starting Life in Another World","value":"57"},{"label":"Re:Zero Начало жизни в другом мире / Re:Zero Starting Life in Another World","value":"1531"},{"label":"Rimworld","value":"1894"},{"label":"The Second Coming of Gluttony / The Second Coming of Avarice","value":"1236"},{"label":"Vfhdbk","value":"1884"},{"label":"XCOM: Враг внутри / XCOM: Enemy Unknown","value":"476"},{"label":"Xenus: Точка кипения / Boiling point: Road To Hell / Xenus: Boiling Point","value":"695"}],"inputType":FilterInputs.Checkbox},{"key":"genres_ex","label":"Исключить жанры:","values":[{"label":"18+","value":"52"},{"label":"Арт","value":"1"},{"label":"Боевик","value":"2"},{"label":"Боевые искусства","value":"3"},{"label":"Гаремник","value":"5"},{"label":"Героическое фэнтези","value":"7"},{"label":"Детектив","value":"8"},{"label":"Дзёсэй","value":"9"},{"label":"Додзинси","value":"10"},{"label":"Драма","value":"11"},{"label":"История","value":"13"},{"label":"Киберпанк","value":"46"},{"label":"Кодомо","value":"14"},{"label":"Комедия","value":"15"},{"label":"Литрпг","value":"48"},{"label":"Махо-сёдзё","value":"16"},{"label":"Мелодрама","value":"49"},{"label":"Меха","value":"17"},{"label":"Мистика","value":"18"},{"label":"Научная фантастика","value":"19"},{"label":"Повседневность","value":"20"},{"label":"Постапокалиптика","value":"21"},{"label":"Приключения","value":"22"},{"label":"Психология","value":"23"},{"label":"Романтика","value":"24"},{"label":"Самурайский боевик","value":"25"},{"label":"Сверхъестественное","value":"26"},{"label":"Сёдзё","value":"27"},{"label":"Сёнэн","value":"29"},{"label":"Смат","value":"45"},{"label":"Спорт","value":"31"},{"label":"Сэйнэн","value":"32"},{"label":"Сюаньхуа","value":"44"},{"label":"Сюаньхуань","value":"47"},{"label":"Сянься (XianXia)","value":"42"},{"label":"Трагедия","value":"33"},{"label":"Триллер","value":"34"},{"label":"Ужасы","value":"35"},{"label":"Уся (wuxia)","value":"41"},{"label":"Фантастика","value":"36"},{"label":"Фанфик","value":"50"},{"label":"Фэнтези","value":"37"},{"label":"Школа","value":"38"},{"label":"Этти","value":"39"},{"label":"Bl","value":"43"},{"label":"Gl","value":"40"}],"inputType":FilterInputs.Checkbox},{"key":"tags_ex","label":"Исключить тэги:","values":[{"label":"12+","value":"3316"},{"label":"16+","value":"83"},{"label":"Абсурд","value":"7973"},{"label":"Авантюристы","value":"222"},{"label":"Автомат","value":"5272"},{"label":"Авторский мир","value":"1062"},{"label":"Агрессивные персонажи","value":"3249"},{"label":"Ад","value":"2623"},{"label":"Ад и рай","value":"817"},{"label":"Адам дженсен","value":"1649"},{"label":"Адаптация произведения","value":"192"},{"label":"Адвокат","value":"6340"},{"label":"Адекватные главные герои","value":"1953"},{"label":"Азартные игры","value":"5301"},{"label":"Азгард","value":"3494"},{"label":"Азула","value":"5550"},{"label":"Аид","value":"7641"},{"label":"Айдолы","value":"4081"},{"label":"Академия","value":"316"},{"label":"Акамэ","value":"5059"},{"label":"Аквакинез","value":"5952"},{"label":"Акира","value":"2639"},{"label":"Акнология","value":"4634"},{"label":"Актерское мастерство","value":"4798"},{"label":"Актёры","value":"7506"},{"label":"Активные герои","value":"6376"},{"label":"Акутагава рюноске","value":"4113"},{"label":"Аладдин","value":"6489"},{"label":"Алая ведьма","value":"4767"},{"label":"Алиса","value":"4761"},{"label":"Алкоголь","value":"5508"},{"label":"Аллегория","value":"271"},{"label":"Алукард","value":"4914"},{"label":"Алхимики","value":"1164"},{"label":"Алхимия","value":"1473"},{"label":"Алчность","value":"6897"},{"label":"Альбус дамблдор","value":"5784"},{"label":"Альтернативное развитие событий","value":"5330"},{"label":"Альянсы","value":"328"},{"label":"Амбициозный главный герой","value":"3751"},{"label":"Америка","value":"4082"},{"label":"Амнезия","value":"2207"},{"label":"Аморальный герой","value":"18"},{"label":"Анбу","value":"8129"},{"label":"Ангелы","value":"857"},{"label":"Ангелы и демоны","value":"1327"},{"label":"Ангст","value":"4638"},{"label":"Андроиды","value":"1993"},{"label":"Анимализм","value":"5249"},{"label":"Аниме","value":"1294"},{"label":"Анко митараши","value":"5768"},{"label":"Антагонист","value":"2144"},{"label":"Антигерой","value":"7725"},{"label":"Антиквариат","value":"3552"},{"label":"Антимаг","value":"1348"},{"label":"Антиутопия","value":"662"},{"label":"Апокалипсис","value":"1498"},{"label":"Аристократия","value":"371"},{"label":"Аристократы","value":"7338"},{"label":"Армия","value":"1723"},{"label":"Артас","value":"6700"},{"label":"Артефакты","value":"2296"},{"label":"Археология","value":"6523"},{"label":"Асгард","value":"3635"},{"label":"Ассасин","value":"1415"},{"label":"Асуна","value":"5044"},{"label":"Аугментации","value":"7751"},{"label":"Ацуши накаджима","value":"4109"},{"label":"Аянокоджи киетака","value":"6862"},{"label":"Бандиты","value":"2188"},{"label":"Басейн","value":"6847"},{"label":"Баскетбол","value":"7933"},{"label":"Бастарды","value":"76"},{"label":"Бедность","value":"1207"},{"label":"Без культивации","value":"668"},{"label":"Без любовной линий","value":"2225"},{"label":"Без перерождений","value":"262"},{"label":"Без попаданца","value":"8065"},{"label":"Без системы","value":"747"},{"label":"Без юмора","value":"763"},{"label":"Бездна","value":"1026"},{"label":"Безжалостное домашнее животное","value":"1245"},{"label":"Безжалостные персонажи","value":"2986"},{"label":"Беззаботные персонажи","value":"3123"},{"label":"Безответная любовь","value":"7815"},{"label":"Безработный","value":"2202"},{"label":"Безумие","value":"37"},{"label":"Безумные персонажи","value":"2049"},{"label":"Бейсбол","value":"7623"},{"label":"Беременность","value":"2122"},{"label":"Бесконечный поток","value":"7556"},{"label":"Беспечные персонажи","value":"742"},{"label":"Бесплатно","value":"8403"},{"label":"Бессмертные персонажи","value":"566"},{"label":"Бесстрашные персонажи","value":"6921"},{"label":"Бесстыдные персонажи","value":"1257"},{"label":"Бесстыдный главный герой","value":"8190"},{"label":"Библиотека","value":"4210"},{"label":"Библия","value":"488"},{"label":"Бизнес","value":"704"},{"label":"Биология","value":"2220"},{"label":"Биомехи","value":"1968"},{"label":"Биседзе","value":"777"},{"label":"Битва за веру","value":"721"},{"label":"Битва за трон","value":"7211"},{"label":"Битва королевств","value":"1151"},{"label":"Битва рас","value":"6989"},{"label":"Битвы","value":"1740"},{"label":"Благородные персонажи","value":"2201"},{"label":"Близнецы","value":"2931"},{"label":"Богатство","value":"6522"},{"label":"Богатые персонажи","value":"520"},{"label":"Боги","value":"173"},{"label":"Богини","value":"30"},{"label":"Богиня","value":"8324"},{"label":"Богоубийца","value":"1253"},{"label":"Богохульство","value":"95"},{"label":"Боевая академия","value":"2108"},{"label":"Большая грудь","value":"4717"},{"label":"Борос","value":"6533"},{"label":"Борьба","value":"1925"},{"label":"Борьба за власть","value":"8072"},{"label":"Босс и подчиненный","value":"7157"},{"label":"Бояръ","value":"2307"},{"label":"Брак","value":"1558"},{"label":"Брак по расчету","value":"1389"},{"label":"Брат и сестра","value":"615"},{"label":"Братский комплекс","value":"2321"},{"label":"Броманс","value":"1103"},{"label":"Брошенные дети","value":"2846"},{"label":"Буддизм","value":"1871"},{"label":"Будущее","value":"1820"},{"label":"Бывший муж","value":"8080"},{"label":"Быстрое развитие","value":"1443"},{"label":"Бэтгерл","value":"2584"},{"label":"Бэтмен","value":"4668"},{"label":"В первый раз","value":"6212"},{"label":"В этот же мир","value":"49"},{"label":"Ваканда","value":"8331"},{"label":"Валькирии","value":"4047"},{"label":"Вампиры","value":"2206"},{"label":"Веб камера","value":"5664"},{"label":"Веб новелла","value":"2349"},{"label":"Ведьмак","value":"843"},{"label":"Ведьмы","value":"643"},{"label":"Везучие персонажи","value":"1879"},{"label":"Веном","value":"3994"},{"label":"Вестерн","value":"2131"},{"label":"Вестерос","value":"8171"},{"label":"Взросление","value":"624"},{"label":"Взрослый главный герой","value":"2416"},{"label":"Видео игры","value":"2630"},{"label":"Викинги","value":"267"},{"label":"Вино","value":"6972"},{"label":"Вирт","value":"6213"},{"label":"Виртуальная реальность","value":"325"},{"label":"Вирусы","value":"3327"},{"label":"Владыка демонов","value":"555"},{"label":"Власть","value":"756"},{"label":"Влюбленность","value":"6132"},{"label":"Внешний вид отличается от личности","value":"1938"},{"label":"Внучка","value":"8399"},{"label":"Военные","value":"1096"},{"label":"Возрождение","value":"1160"},{"label":"Воины","value":"287"},{"label":"Война","value":"443"},{"label":"Войны","value":"2431"},{"label":"Воландеморт","value":"4278"},{"label":"Волейбол","value":"6415"},{"label":"Волки","value":"1166"},{"label":"Волшебники","value":"122"},{"label":"Волшебные существа","value":"1689"},{"label":"Волшебство","value":"719"},{"label":"Вор","value":"1399"},{"label":"Воровка","value":"6948"},{"label":"Ворон","value":"848"},{"label":"Воскрешение","value":"6915"},{"label":"Воспоминания из другого мира","value":"1366"},{"label":"Воспоминания из прошлого","value":"1372"},{"label":"Воссоединие семьи","value":"8130"},{"label":"Восхождение","value":"380"},{"label":"Враги становятся любовниками","value":"978"},{"label":"Врата","value":"40"},{"label":"Врата в другой мир","value":"1957"},{"label":"Врач","value":"1243"},{"label":"Временная петля","value":"2852"},{"label":"Врмморпг","value":"2043"},{"label":"Все дозволено","value":"96"},{"label":"Всемогущий главный герой","value":"1414"},{"label":"Второй шанс","value":"2372"},{"label":"Вуайеризм","value":"2498"},{"label":"Выживание","value":"501"},{"label":"Вымышленные существа","value":"3466"},{"label":"Вынужденный брак","value":"7705"},{"label":"Высокие технологии","value":"653"},{"label":"Высокомерные персонажи","value":"3250"},{"label":"Галустян","value":"5199"},{"label":"Гангстеры","value":"7704"},{"label":"Гарем","value":"440"},{"label":"Гарри поттер","value":"226"},{"label":"Геймеры","value":"2130"},{"label":"Генетические модификации","value":"1750"},{"label":"Гениальный главный герой","value":"1500"},{"label":"Гений","value":"1650"},{"label":"Гермиона грейнджер","value":"4280"},{"label":"Герои","value":"185"},{"label":"Гигаполис","value":"8393"},{"label":"Гильгамеш","value":"6031"},{"label":"Гильдии","value":"900"},{"label":"Гильдия авантюристов","value":"1858"},{"label":"Гинтама","value":"4544"},{"label":"Гипноз","value":"358"},{"label":"Главная героиня влюбляется первой","value":"973"},{"label":"Главный герой бог","value":"164"},{"label":"Главный герой влюбляется первым","value":"3629"},{"label":"Главный герой выживальщик","value":"120"},{"label":"Главный герой гонг","value":"7877"},{"label":"Главный герой девушка","value":"257"},{"label":"Главный герой демон","value":"136"},{"label":"Главный герой женщина","value":"7329"},{"label":"Главный герой жестокий","value":"1553"},{"label":"Главный герой извращенец","value":"94"},{"label":"Главный герой имба","value":"2421"},{"label":"Главный герой киборг","value":"7780"},{"label":"Главный герой монстр","value":"869"},{"label":"Главный герой мужчина","value":"1997"},{"label":"Главный герой на стороне сил зла","value":"1514"},{"label":"Главный герой не адекватный","value":"5"},{"label":"Главный герой не психопат","value":"7804"},{"label":"Главный герой не человек","value":"2172"},{"label":"Главный герой не эмоционален","value":"1150"},{"label":"Главный герой подросток","value":"2215"},{"label":"Главный герой позитивный","value":"7787"},{"label":"Главный герой психопат","value":"7803"},{"label":"Главный герой ребенок","value":"2347"},{"label":"Главный герой русский","value":"2417"},{"label":"Главный герой сильный с самого начала","value":"88"},{"label":"Главный герой скрывает свою силу","value":"1059"},{"label":"Главный герой эгоист","value":"8326"},{"label":"Гномы","value":"1870"},{"label":"Гоблины","value":"2029"},{"label":"Годзилла","value":"6990"},{"label":"Големы","value":"1690"},{"label":"Голливуд","value":"7754"},{"label":"Головоломка","value":"1697"},{"label":"Горничные","value":"8091"},{"label":"Гробница","value":"388"},{"label":"Дазай осаму","value":"4112"},{"label":"Даньмэй","value":"3411"},{"label":"Даосизм","value":"258"},{"label":"Дарк соулс","value":"6057"},{"label":"Дарт вейдер","value":"6826"},{"label":"Дафна гринграсс","value":"5192"},{"label":"Дворяне","value":"7204"},{"label":"Девушки","value":"7668"},{"label":"Девушки монстры","value":"2231"},{"label":"Дедушка и внучка","value":"8400"},{"label":"Дейви джонс","value":"8061"},{"label":"Действие","value":"1425"},{"label":"Демон лорд","value":"153"},{"label":"Демонология","value":"2024"},{"label":"Демоны","value":"1406"},{"label":"Дети","value":"580"},{"label":"Джарвис","value":"933"},{"label":"Джедай","value":"4442"},{"label":"Джин","value":"4024"},{"label":"Джокер","value":"3351"},{"label":"Джон сноу","value":"7412"},{"label":"Джоффри баратеон","value":"3936"},{"label":"Дзесэй","value":"678"},{"label":"Дин винчестер","value":"6953"},{"label":"Династии","value":"2982"},{"label":"Динозавры","value":"3666"},{"label":"Директор","value":"1417"},{"label":"Для девушек","value":"1441"},{"label":"Дневник","value":"298"},{"label":"Добби","value":"6762"},{"label":"Добрый мир","value":"1685"},{"label":"Договоры с богами","value":"2152"},{"label":"Договоры с демонами","value":"1922"},{"label":"Доктор","value":"1991"},{"label":"Доктор стрэндж","value":"7634"},{"label":"Доминирование","value":"2054"},{"label":"Дота","value":"6965"},{"label":"Доудзюцу","value":"7133"},{"label":"Дочь","value":"3291"},{"label":"Драко малфой","value":"46"},{"label":"Драконы","value":"282"},{"label":"Драконы оборотни","value":"8082"},{"label":"Древние времена","value":"7781"},{"label":"Древний египет","value":"7614"},{"label":"Древний китай","value":"473"},{"label":"Древний мир","value":"4"},{"label":"Другая вселенная","value":"39"},{"label":"Другие планеты","value":"2371"},{"label":"Другой мир","value":"2248"},{"label":"Дружба","value":"1903"},{"label":"Друзья детства","value":"1153"},{"label":"Духи","value":"114"},{"label":"Духовные силы","value":"1955"},{"label":"Души","value":"1212"},{"label":"Дьявол","value":"1094"},{"label":"Дьявольские фрукты","value":"1564"},{"label":"Дэдпул","value":"4399"},{"label":"Евнух","value":"6293"},{"label":"Европейская атмосфера","value":"5837"},{"label":"Египет","value":"528"},{"label":"Еда","value":"2056"},{"label":"Единороги","value":"437"},{"label":"Екаи","value":"655"},{"label":"Жалкий главный герой","value":"97"},{"label":"Жена","value":"5729"},{"label":"Женское доминирование","value":"4622"},{"label":"Женщина в теле мужчины","value":"2748"},{"label":"Женщина кошка","value":"7513"},{"label":"Жестокие персонажи","value":"3153"},{"label":"Жестокий мир","value":"1532"},{"label":"Жестокость","value":"7880"},{"label":"Животные","value":"7488"},{"label":"Животные компаньоны","value":"2061"},{"label":"Жизнь и смерть","value":"2014"},{"label":"Жнец","value":"6288"},{"label":"Жойен рид","value":"3926"},{"label":"Заботливый главный герой","value":"338"},{"label":"Закалка тела","value":"148"},{"label":"Заклинания","value":"558"},{"label":"Заключенные","value":"3052"},{"label":"Занпакто","value":"1102"},{"label":"Запретная любовь","value":"8033"},{"label":"Запутанный сюжет","value":"1041"},{"label":"Захват мира","value":"315"},{"label":"Зачарованные","value":"4169"},{"label":"Звери","value":"1638"},{"label":"Зверодевочки","value":"2006"},{"label":"Зверолюди","value":"1018"},{"label":"Земля","value":"82"},{"label":"Злая организация","value":"7768"},{"label":"Зло","value":"1512"},{"label":"Злодей","value":"1060"},{"label":"Злодейка","value":"2376"},{"label":"Злой главный герой","value":"616"},{"label":"Злые боги","value":"7109"},{"label":"Злые персонажи","value":"3243"},{"label":"Змей","value":"5721"},{"label":"Знаменитости","value":"1341"},{"label":"Знание медицины","value":"1411"},{"label":"Золушка","value":"2980"},{"label":"Зомби","value":"1743"},{"label":"Зомби апокалипсис","value":"912"},{"label":"Зона 51","value":"3051"},{"label":"Зооморфы","value":"375"},{"label":"Зорро","value":"6736"},{"label":"Зрелые женщины","value":"1458"},{"label":"Игра","value":"663"},{"label":"Игра на выживание","value":"2182"},{"label":"Игровая система","value":"384"},{"label":"Игровые элементы","value":"720"},{"label":"Извращения","value":"651"},{"label":"Измена","value":"1874"},{"label":"Изменение характера","value":"1113"},{"label":"Изменения внешности","value":"259"},{"label":"Изменения личности","value":"1080"},{"label":"Изобретения","value":"126"},{"label":"Изуку мидория","value":"6967"},{"label":"Император","value":"867"},{"label":"Империи","value":"712"},{"label":"Империя","value":"1716"},{"label":"Инвалидность","value":"2073"},{"label":"Инквизитор","value":"143"},{"label":"Инкуб","value":"3264"},{"label":"Инопланетное вторжение","value":"209"},{"label":"Инопланетяне","value":"866"},{"label":"Интерактив с читателями","value":"472"},{"label":"Интересный сюжет","value":"7374"},{"label":"Интернет","value":"739"},{"label":"Интимные сцены","value":"3450"},{"label":"Интрига","value":"317"},{"label":"Интриги и заговоры","value":"1009"},{"label":"Иные миры","value":"35"},{"label":"Исекай","value":"2979"},{"label":"Искусственный интеллект","value":"1900"},{"label":"Исследование","value":"1626"},{"label":"Исторический роман","value":"573"},{"label":"Итачи учиха","value":"4556"},{"label":"Ичиго","value":"7254"},{"label":"Йода","value":"6829"},{"label":"Йоруичи","value":"6755"},{"label":"Калипсо","value":"8062"},{"label":"Каннибализм","value":"2249"},{"label":"Капитан америка","value":"6301"},{"label":"Каракура","value":"7473"},{"label":"Карточная игра","value":"1557"},{"label":"Кастиэль","value":"6954"},{"label":"Кафе","value":"3934"},{"label":"Кацуки бакуго","value":"7696"},{"label":"Квесты","value":"1707"},{"label":"Киберспорт","value":"1984"},{"label":"Кино","value":"7126"},{"label":"Китай","value":"3762"},{"label":"Кицунэ","value":"241"},{"label":"Кланы","value":"834"},{"label":"Клоны","value":"1624"},{"label":"Книги","value":"1068"},{"label":"Книжный червь","value":"521"},{"label":"Колдовство","value":"2681"},{"label":"колледж","value":"5058"},{"label":"Коллекционер","value":"2588"},{"label":"Кольцо","value":"1628"},{"label":"Коммунисты","value":"1042"},{"label":"Коноха","value":"2827"},{"label":"Контракт","value":"4304"},{"label":"Контроль разума","value":"485"},{"label":"Конфеты","value":"341"},{"label":"Корейцы","value":"6535"},{"label":"Корея","value":"2443"},{"label":"Королевская власть","value":"55"},{"label":"Королевская семья","value":"276"},{"label":"Королевство","value":"1695"},{"label":"Короткий рассказ","value":"239"},{"label":"Коррупция","value":"831"},{"label":"Космическая опера","value":"2245"},{"label":"Космические рейнджеры","value":"5860"},{"label":"Космос","value":"329"},{"label":"Кот","value":"5171"},{"label":"Кража навыков","value":"1159"},{"label":"Красивая главная героиня","value":"186"},{"label":"Красивые женщины","value":"66"},{"label":"Красивые персонажи","value":"5787"},{"label":"Красивый главный герой","value":"895"},{"label":"Крафт","value":"1599"},{"label":"Кроссовер","value":"75"},{"label":"Ктулху","value":"920"},{"label":"Кузнец","value":"853"},{"label":"Кукла","value":"3085"},{"label":"Кулинария","value":"2230"},{"label":"Культивация","value":"1901"},{"label":"Культивирование","value":"1860"},{"label":"Курама","value":"5709"},{"label":"Курилин","value":"6134"},{"label":"Кушина узумаки","value":"5222"},{"label":"Лавкрафт","value":"6063"},{"label":"Лара крофт","value":"6435"},{"label":"Легенда о зельде","value":"5707"},{"label":"Ленивый главный герой","value":"1516"},{"label":"Леон золдик","value":"7469"},{"label":"Лес","value":"6645"},{"label":"Лечебная магия","value":"562"},{"label":"Локи","value":"1725"},{"label":"Лоли","value":"1576"},{"label":"Лопата","value":"4989"},{"label":"Лорд","value":"8404"},{"label":"Лориен","value":"7397"},{"label":"Лошади","value":"6110"},{"label":"Лунатизм","value":"3520"},{"label":"Луффи","value":"274"},{"label":"Лучник","value":"1038"},{"label":"Любовный интерес влюбляется первым","value":"7753"},{"label":"Любовный треугольник","value":"2109"},{"label":"Любовь","value":"2297"},{"label":"Любовь с первого взгляда","value":"7748"},{"label":"Любящие родители","value":"2699"},{"label":"Люди","value":"3572"},{"label":"Люцифер","value":"5883"},{"label":"Маг","value":"780"},{"label":"Магазин","value":"4762"},{"label":"Маги","value":"58"},{"label":"Магическая академия","value":"6788"},{"label":"Магические звери","value":"684"},{"label":"Магические предметы","value":"1648"},{"label":"Магический мир","value":"578"},{"label":"Магия","value":"150"},{"label":"Магия воды","value":"6450"},{"label":"Магия воздуха","value":"7627"},{"label":"Магия земли","value":"7626"},{"label":"Магия и технология","value":"107"},{"label":"Магия крови","value":"7976"},{"label":"Магия льда","value":"1379"},{"label":"Магия огня","value":"7625"},{"label":"Магия призыва","value":"885"},{"label":"Магия природы","value":"6226"},{"label":"Магия стихий","value":"7673"},{"label":"Магия тьмы","value":"3596"},{"label":"Мадара","value":"2929"},{"label":"Мазохизм","value":"1961"},{"label":"Мама","value":"12"},{"label":"Мама и дочь","value":"7894"},{"label":"Мама и сын","value":"7895"},{"label":"Манга","value":"2464"},{"label":"Манипуляция временем","value":"932"},{"label":"Маньяк","value":"2026"},{"label":"Маргери тирелл","value":"3935"},{"label":"Марионетки","value":"3175"},{"label":"Марс","value":"4013"},{"label":"Марти стью","value":"594"},{"label":"Мастер на все руки","value":"3189"},{"label":"Матриархат","value":"7197"},{"label":"Мать и сестры","value":"7946"},{"label":"Мафия","value":"353"},{"label":"Мачеха","value":"4664"},{"label":"Мегаполис","value":"3322"},{"label":"Медицина","value":"441"},{"label":"Медленная романтика","value":"8383"},{"label":"Медленное развитие истории","value":"7462"},{"label":"Мелиодас","value":"7224"},{"label":"Мелодрама","value":"1507"},{"label":"Менеджмент","value":"368"},{"label":"Мерлин","value":"3977"},{"label":"Месть","value":"1218"},{"label":"Меч","value":"48"},{"label":"Мечники","value":"969"},{"label":"Мечта","value":"527"},{"label":"Мизуки","value":"4269"},{"label":"Микото","value":"3862"},{"label":"Милая главная героиня","value":"134"},{"label":"Милф","value":"1987"},{"label":"Милый главный герой","value":"2678"},{"label":"Мимик","value":"5706"},{"label":"Мина ашидо","value":"7695"},{"label":"Минато намикадзе","value":"5223"},{"label":"Мир будущего","value":"1770"},{"label":"Мир земли","value":"8394"},{"label":"Мир меча и магии","value":"1271"},{"label":"Мистер пропер","value":"565"},{"label":"Мифические существа","value":"1878"},{"label":"Мифы и легенды","value":"4463"},{"label":"Младшая сестра","value":"1523"},{"label":"Мморпг","value":"620"},{"label":"Много главных героев","value":"1191"},{"label":"Много крови","value":"5318"},{"label":"Много персонажей","value":"1539"},{"label":"Множество королевств","value":"32"},{"label":"Модерн","value":"5457"},{"label":"Мокутон","value":"4438"},{"label":"Молоко","value":"5469"},{"label":"Монархия","value":"3590"},{"label":"Монстры","value":"307"},{"label":"Море","value":"922"},{"label":"Моритика ринносукэ","value":"1142"},{"label":"Мортал комбат","value":"5861"},{"label":"Мошенник","value":"959"},{"label":"Мрачный мир","value":"1"},{"label":"Мужчина в женском теле","value":"8405"},{"label":"Музыка","value":"1183"},{"label":"Мультивселенная","value":"7410"},{"label":"Мурим","value":"7342"},{"label":"Мутанты","value":"2392"},{"label":"Мутация","value":"29"},{"label":"Мясо","value":"1503"},{"label":"На реальных событиях","value":"26"},{"label":"Навыки","value":"415"},{"label":"Нагато узумаки","value":"5221"},{"label":"Наемники","value":"1668"},{"label":"Назарик","value":"5369"},{"label":"Наивный главный герой","value":"159"},{"label":"Наложница","value":"4867"},{"label":"Наноботы","value":"2332"},{"label":"Наруто","value":"7177"},{"label":"Наруто и хината","value":"5766"},{"label":"Насилие и жестокость","value":"1440"},{"label":"Наука","value":"2150"},{"label":"Национализм","value":"5556"},{"label":"Нацу","value":"5826"},{"label":"Нацуки субару","value":"6656"},{"label":"Начальная школа","value":"3920"},{"label":"Наши дни","value":"1814"},{"label":"Не всесильный главный герой","value":"42"},{"label":"Не по канону","value":"1611"},{"label":"Неверность","value":"5735"},{"label":"Невеста","value":"6011"},{"label":"Неджи хьюга","value":"3099"},{"label":"Недооценённый главный герой","value":"43"},{"label":"Нежить","value":"1949"},{"label":"Некромаг","value":"7441"},{"label":"Некромант","value":"1914"},{"label":"Некромантия","value":"754"},{"label":"Ненормативная лексика","value":"160"},{"label":"Необычные герои","value":"67"},{"label":"Нет людей","value":"7486"},{"label":"Нетораре","value":"403"},{"label":"Нетори","value":"5393"},{"label":"Нефилимы","value":"7764"},{"label":"Нецензурная лексика","value":"4912"},{"label":"Нечисть","value":"4559"},{"label":"Ник фьюри","value":"6304"},{"label":"Ниндзюцу","value":"2354"},{"label":"Ниндзя","value":"1330"},{"label":"Новелла","value":"2105"},{"label":"Нэко","value":"147"},{"label":"Оби ван кеноби","value":"6830"},{"label":"Обито учиха","value":"2814"},{"label":"Оборотни","value":"53"},{"label":"Обратный гарем","value":"3303"},{"label":"Овощ","value":"6098"},{"label":"Огнестрельное оружие","value":"3155"},{"label":"Одержимость","value":"708"},{"label":"Один в поле воин","value":"6498"},{"label":"Онлайн игра","value":"1565"},{"label":"Ооками теппей","value":"849"},{"label":"Оригинальные персонажи","value":"7741"},{"label":"Орки","value":"1597"},{"label":"Оружие","value":"125"},{"label":"Основано на видео игре","value":"602"},{"label":"Особые способности","value":"2904"},{"label":"От бедности к богатству","value":"901"},{"label":"От слабого до сильного","value":"118"},{"label":"Отель","value":"2879"},{"label":"Отец","value":"3290"},{"label":"Отношения","value":"398"},{"label":"Отношения человек/нечеловек","value":"7406"},{"label":"Офис","value":"3460"},{"label":"Охотники","value":"2263"},{"label":"Оцуцуки","value":"5101"},{"label":"Ошейник","value":"2362"},{"label":"Ояш","value":"8048"},{"label":"Падчерица","value":"7023"},{"label":"Падший ангел","value":"184"},{"label":"Палач","value":"852"},{"label":"Палочка","value":"2682"},{"label":"Пандорум","value":"4360"},{"label":"Папа и дочь","value":"7647"},{"label":"Паразит","value":"1213"},{"label":"Параллельный мир","value":"2092"},{"label":"Парень","value":"619"},{"label":"Паркур","value":"3391"},{"label":"Пародия","value":"898"},{"label":"Пасхалки","value":"455"},{"label":"Паук","value":"2209"},{"label":"Пекарь","value":"5073"},{"label":"Первая книга","value":"269"},{"label":"Первая любовь","value":"640"},{"label":"Первый раз","value":"1465"},{"label":"Переводы","value":"24"},{"label":"Перевоплощение","value":"1596"},{"label":"Перевоплощение в игровом мире","value":"92"},{"label":"Перемещение в другой мир","value":"1288"},{"label":"Перемещение во времени","value":"146"},{"label":"Перерождение","value":"894"},{"label":"Перерождение в демона","value":"1111"},{"label":"Перерождение в дракона","value":"6867"},{"label":"Перерождение в злодейку","value":"5619"},{"label":"Перерождение в злодея","value":"749"},{"label":"Перерождение в ином мире","value":"109"},{"label":"Перерождение в монстра","value":"917"},{"label":"Перерождений","value":"335"},{"label":"Переселение","value":"813"},{"label":"Переселение души","value":"1864"},{"label":"Перси джексон","value":"6329"},{"label":"Пилот","value":"5521"},{"label":"Пилюли","value":"1531"},{"label":"Пират","value":"1579"},{"label":"Пирог","value":"80"},{"label":"Писатель","value":"734"},{"label":"Пистолеты","value":"4916"},{"label":"Письмо","value":"840"},{"label":"Питомцы","value":"3122"},{"label":"Планомерное развитие событий","value":"62"},{"label":"Племянник","value":"8303"},{"label":"Пленница","value":"4897"},{"label":"Плети","value":"4839"},{"label":"Пляж","value":"4243"},{"label":"Повар","value":"658"},{"label":"Повествование от первого лица","value":"1054"},{"label":"Повествование от разных лиц","value":"600"},{"label":"Повествование от третьего лица","value":"2116"},{"label":"Подавитель","value":"497"},{"label":"Подземелье","value":"798"},{"label":"Подростки","value":"636"},{"label":"Подруга","value":"5804"},{"label":"Подчинение","value":"8343"},{"label":"Подчинение и унижение","value":"4500"},{"label":"Покемоны","value":"2840"},{"label":"Полиамория","value":"1300"},{"label":"Полигамия","value":"1336"},{"label":"Политика","value":"1313"},{"label":"Полицейский","value":"1907"},{"label":"Полубог","value":"7170"},{"label":"Полукровка","value":"999"},{"label":"Полулюди","value":"2273"},{"label":"Поношенные трусики","value":"1204"},{"label":"Попаданец","value":"2396"},{"label":"Попаданец в другой мир","value":"685"},{"label":"Попаданец в игру","value":"6466"},{"label":"Попадание в книгу","value":"6957"},{"label":"Постапокалипсис","value":"1079"},{"label":"Похищение","value":"7452"},{"label":"Поэзия","value":"1120"},{"label":"Правитель","value":"2261"},{"label":"Превращения в животных","value":"3410"},{"label":"Преданный любовный интерес","value":"2055"},{"label":"Предательство","value":"70"},{"label":"Президент","value":"4334"},{"label":"Преступник","value":"4049"},{"label":"Преступный мир","value":"965"},{"label":"Призрак","value":"511"},{"label":"Призыв","value":"332"},{"label":"Призыв в другой мир","value":"781"},{"label":"Призыв существ","value":"412"},{"label":"Приложение на телефоне","value":"5345"},{"label":"Принудительный брак","value":"2954"},{"label":"Принуждение","value":"1442"},{"label":"Принц","value":"362"},{"label":"Принцесса","value":"2403"},{"label":"Приручение мостров","value":"2338"},{"label":"Прислуга","value":"5185"},{"label":"Пришельцы","value":"273"},{"label":"Проза","value":"2012"},{"label":"Прокачка","value":"1070"},{"label":"Проклятия","value":"1347"},{"label":"Проработанный мир","value":"1711"},{"label":"Пророчество","value":"7762"},{"label":"Против наркотиков","value":"8406"},{"label":"Псайкеры","value":"3659"},{"label":"Псионика","value":"5216"},{"label":"Психбольница","value":"6969"},{"label":"Психические расстройства","value":"2445"},{"label":"Психологические травмы","value":"3418"},{"label":"Публичный дом","value":"7860"},{"label":"Путешествие в другой мир","value":"10"},{"label":"Пух","value":"4286"},{"label":"Пушечное мясо","value":"7234"},{"label":"Пытки","value":"1756"},{"label":"Пьяный мастер","value":"1655"},{"label":"Пэнси паркинсон","value":"7411"},{"label":"Раб","value":"977"},{"label":"Рабы","value":"1240"},{"label":"Разведение животных","value":"3990"},{"label":"Развитие","value":"208"},{"label":"Развитие персонажа","value":"1780"},{"label":"Развитие поселения","value":"7203"},{"label":"Развитие технологий","value":"1875"},{"label":"Раздвоение личности","value":"2062"},{"label":"Разные расы","value":"1188"},{"label":"Разорванная помолвка","value":"2057"},{"label":"Разработчик","value":"2333"},{"label":"Ранги","value":"1568"},{"label":"Ранобэ","value":"1764"},{"label":"Расизм","value":"3554"},{"label":"Растение","value":"407"},{"label":"Реализм","value":"1180"},{"label":"Ребенок","value":"2881"},{"label":"Ревность","value":"293"},{"label":"Революция","value":"3996"},{"label":"Реинкарнация","value":"1302"},{"label":"Реинкарнация в другом мире","value":"2180"},{"label":"Реинкарнация в игровой мир","value":"304"},{"label":"Рейджер","value":"5147"},{"label":"Религия","value":"2184"},{"label":"Рем","value":"6655"},{"label":"Ремесленник","value":"1483"},{"label":"Ремонт","value":"5703"},{"label":"Репликаторы","value":"3495"},{"label":"Ресторан","value":"7519"},{"label":"Риас гремори","value":"6950"},{"label":"Рим","value":"612"},{"label":"Риннеган","value":"4230"},{"label":"Ритуал","value":"1233"},{"label":"Робот","value":"4011"},{"label":"Роботы","value":"467"},{"label":"Рок ли","value":"7002"},{"label":"Рокси","value":"7380"},{"label":"Рон уизли","value":"4279"},{"label":"Ророноа зоро","value":"1590"},{"label":"Росомаха","value":"1035"},{"label":"Российская империя","value":"2146"},{"label":"Россия","value":"4246"},{"label":"Рудеус","value":"7379"},{"label":"Руны","value":"2393"},{"label":"Русалки","value":"3127"},{"label":"Русь","value":"2016"},{"label":"Рыцари","value":"1902"},{"label":"Рэо хатаке","value":"2823"},{"label":"Сабли","value":"6136"},{"label":"Сайян","value":"6802"},{"label":"Сакура","value":"2515"},{"label":"Самец","value":"1592"},{"label":"Самураи","value":"576"},{"label":"Санса старк","value":"3925"},{"label":"Сарказм","value":"4658"},{"label":"Саске","value":"7237"},{"label":"Сатира","value":"215"},{"label":"Сборник","value":"7367"},{"label":"Свадьба","value":"1524"},{"label":"Сверхсила","value":"1055"},{"label":"Свинцовые книги","value":"5322"},{"label":"Связывание","value":"4506"},{"label":"Священик","value":"61"},{"label":"Северус снейп","value":"5783"},{"label":"Сёдзе","value":"2219"},{"label":"Секты","value":"1234"},{"label":"Сельское хозяйство","value":"787"},{"label":"Семейный конфликт","value":"935"},{"label":"Семья","value":"728"},{"label":"Сенджу","value":"6069"},{"label":"Серийный убийца","value":"261"},{"label":"Сестра","value":"2342"},{"label":"Сила глаза","value":"1019"},{"label":"Сильная героиня","value":"7292"},{"label":"Сильная главная героиня","value":"1994"},{"label":"Сильный главный герой","value":"570"},{"label":"Сильфиетта","value":"7381"},{"label":"Симбиот","value":"2648"},{"label":"Сириус блэк","value":"7655"},{"label":"Сирота","value":"297"},{"label":"Система","value":"251"},{"label":"Система уровней","value":"2174"},{"label":"Ситх","value":"1618"},{"label":"Сказка","value":"3570"},{"label":"Скайрим","value":"4032"},{"label":"Скайуокер","value":"6828"},{"label":"Сквиб","value":"4101"},{"label":"Скелет","value":"1315"},{"label":"Скрытые способности","value":"3417"},{"label":"Скульптор","value":"1178"},{"label":"Слабая главная героиня","value":"5805"},{"label":"Слабый главный герой","value":"731"},{"label":"Славяне","value":"2168"},{"label":"Слизерин","value":"6979"},{"label":"Слизь","value":"1095"},{"label":"Сломанная игрушка","value":"8396"},{"label":"Служанка","value":"3486"},{"label":"Смартфон","value":"457"},{"label":"Смена сущности","value":"8391"},{"label":"Смерть","value":"1779"},{"label":"Смерть основного персонажа","value":"1530"},{"label":"Собаки","value":"6109"},{"label":"Соблазн","value":"7994"},{"label":"Соблазнение","value":"2290"},{"label":"Современность","value":"568"},{"label":"Современные знания","value":"988"},{"label":"Сожительство","value":"3026"},{"label":"Создание армии","value":"1992"},{"label":"Создание королевства","value":"1497"},{"label":"Создание пилюль","value":"816"},{"label":"Создатель","value":"1045"},{"label":"Сокровища","value":"6521"},{"label":"Сокрытие истинной личности","value":"2894"},{"label":"Сома и эрина","value":"5737"},{"label":"Соперничество","value":"7699"},{"label":"Соседи","value":"4075"},{"label":"Сотрудник","value":"6339"},{"label":"Социология","value":"7618"},{"label":"Спокойная главная героиня","value":"236"},{"label":"Спокойный главный герой","value":"1656"},{"label":"Спор","value":"3484"},{"label":"Спортивное тело","value":"8317"},{"label":"Способность кражи","value":"7784"},{"label":"Сражения","value":"23"},{"label":"Средневековье","value":"1022"},{"label":"Сталкер","value":"1932"},{"label":"Становление государства","value":"111"},{"label":"Старшая школа","value":"1658"},{"label":"Стёб","value":"454"},{"label":"Стекло","value":"7453"},{"label":"Стеснительный персонаж","value":"152"},{"label":"Стимпанк","value":"1894"},{"label":"Стихи","value":"1309"},{"label":"Стратегия","value":"569"},{"label":"Строительство","value":"921"},{"label":"Студент","value":"1464"},{"label":"Студентка","value":"7518"},{"label":"Суккубы","value":"2662"},{"label":"Супер зрение","value":"6574"},{"label":"Супер удача","value":"489"},{"label":"Супергерои","value":"1481"},{"label":"Суперзлодеи","value":"2125"},{"label":"Супермен","value":"6997"},{"label":"Суперсилы","value":"2276"},{"label":"Существа","value":"6033"},{"label":"Сферы","value":"1077"},{"label":"Схемы и заговоры","value":"7116"},{"label":"Сценарий","value":"7489"},{"label":"Счастливый конец","value":"3293"},{"label":"Сын","value":"3297"},{"label":"Сэм винчестер","value":"7461"},{"label":"Сюаньхуа","value":"2560"},{"label":"Сюжетные повороты","value":"7202"},{"label":"Таблетки для развития","value":"589"},{"label":"Таинственное прошлое","value":"769"},{"label":"Тайная личность","value":"8096"},{"label":"Тайная любовь","value":"113"},{"label":"Тайны","value":"7481"},{"label":"Тайные отношения","value":"7450"},{"label":"Тайцы","value":"6413"},{"label":"Танки","value":"1787"},{"label":"Творчество","value":"20"},{"label":"Тейлор эберт","value":"3526"},{"label":"Телекинез","value":"2203"},{"label":"Телепортация","value":"914"},{"label":"Телохранитель","value":"723"},{"label":"Темари","value":"4810"},{"label":"Темная магия","value":"4788"},{"label":"Темное фэнтези","value":"1675"},{"label":"Темные эльфы","value":"7198"},{"label":"Тенсейган","value":"4367"},{"label":"Тетя","value":"4194"},{"label":"Техномагия","value":"508"},{"label":"Тиран","value":"1174"},{"label":"Титаны","value":"3308"},{"label":"Тодороки шото","value":"5105"},{"label":"Токио","value":"5791"},{"label":"Том реддл","value":"6652"},{"label":"Тони старк","value":"1338"},{"label":"Тор","value":"1800"},{"label":"Тор и локи","value":"2645"},{"label":"Торговля","value":"1637"},{"label":"Травничество","value":"221"},{"label":"Трагическое прошлое","value":"644"},{"label":"Трактир","value":"1918"},{"label":"Трансмиграция","value":"1071"},{"label":"Трансформация","value":"156"},{"label":"Трансформеры","value":"4616"},{"label":"Тревор филипс","value":"5427"},{"label":"Тройняшки","value":"7169"},{"label":"Троли","value":"4250"},{"label":"Трудолюбивый главный герой","value":"248"},{"label":"Тупой главный герой","value":"3710"},{"label":"Тьма","value":"1919"},{"label":"Тюрьма","value":"5597"},{"label":"Тяжёлое детство","value":"2253"},{"label":"Убийства","value":"378"},{"label":"Убийцы","value":"1766"},{"label":"Убийцы драконов","value":"1484"},{"label":"Увечья","value":"3266"},{"label":"Удача","value":"6575"},{"label":"Узумаки","value":"7579"},{"label":"Укротитель","value":"367"},{"label":"Умения","value":"531"},{"label":"Умная главная героиня","value":"1381"},{"label":"Умные персонажи","value":"2756"},{"label":"Умный главный герой","value":"2093"},{"label":"Университет","value":"2102"},{"label":"Унижение","value":"8342"},{"label":"Уничтожение мира","value":"81"},{"label":"Управление временем","value":"5648"},{"label":"Уровни","value":"8"},{"label":"Усиление","value":"3549"},{"label":"Усопп","value":"6737"},{"label":"Устроенный брак","value":"2223"},{"label":"Усыновление","value":"395"},{"label":"Утопия","value":"4677"},{"label":"Уход за детьми","value":"7609"},{"label":"Учеба в университете","value":"2797"},{"label":"Учебное заведение","value":"1817"},{"label":"Ученые","value":"1843"},{"label":"Учитель","value":"845"},{"label":"Учиха","value":"5348"},{"label":"Фамильяры","value":"1471"},{"label":"Фанатичная любовь","value":"6721"},{"label":"Фанаты","value":"7739"},{"label":"Фантастический мир","value":"2414"},{"label":"Фармацевт","value":"1706"},{"label":"Фашисты","value":"3118"},{"label":"Феи","value":"7185"},{"label":"Фелляция","value":"5880"},{"label":"Феминизм","value":"6527"},{"label":"Феникс","value":"2413"},{"label":"Фенрир","value":"2740"},{"label":"Феодализм","value":"280"},{"label":"Ферма","value":"285"},{"label":"Фехтовальщик","value":"4685"},{"label":"Филиппины","value":"128"},{"label":"Философия","value":"1859"},{"label":"Флафф","value":"5048"},{"label":"Флер делакур","value":"5191"},{"label":"Флэш","value":"4667"},{"label":"Фокусник","value":"7602"},{"label":"Фольклор","value":"4086"},{"label":"Фугаку","value":"6161"},{"label":"Фурри","value":"6631"},{"label":"Футбол","value":"1121"},{"label":"Фэнтезийный мир","value":"1556"},{"label":"Хакер","value":"475"},{"label":"Халк","value":"1196"},{"label":"Хан нуньен синг","value":"4817"},{"label":"Ханма юджиро","value":"4369"},{"label":"Хаос","value":"3117"},{"label":"Харизматичный главный герой","value":"2350"},{"label":"Хатаке какаши","value":"2820"},{"label":"Хиддлстон","value":"5903"},{"label":"Химавари","value":"2583"},{"label":"Хината","value":"2513"},{"label":"Хитрый главный герой","value":"2036"},{"label":"Хоббит","value":"6698"},{"label":"Хогвартс","value":"5954"},{"label":"Холодная главная героиня","value":"6507"},{"label":"Холодное оружие","value":"4889"},{"label":"Холодный главный герой","value":"2686"},{"label":"Храм","value":"2135"},{"label":"Христианство","value":"877"},{"label":"Художественная литература","value":"2380"},{"label":"Художница","value":"518"},{"label":"Хулиганы","value":"854"},{"label":"Цветок","value":"902"},{"label":"Цезарь","value":"1705"},{"label":"Целители","value":"4523"},{"label":"Церковь","value":"1980"},{"label":"Цундере","value":"1078"},{"label":"Чакра","value":"1393"},{"label":"Чат-система","value":"8407"},{"label":"Черный юмор","value":"2868"},{"label":"Честная главная героиня","value":"5855"},{"label":"Честный главный герой","value":"129"},{"label":"Читы","value":"451"},{"label":"Шантаж","value":"7175"},{"label":"Шаринган","value":"5165"},{"label":"Шинигами","value":"4661"},{"label":"Шиноби","value":"1227"},{"label":"Школьная жизнь","value":"284"},{"label":"Школьники","value":"218"},{"label":"Школьницы","value":"5946"},{"label":"Шлюха","value":"5822"},{"label":"Шоу-бизнес","value":"7119"},{"label":"Шпионы","value":"4262"},{"label":"Эволюция","value":"2040"},{"label":"Экзорцизм","value":"676"},{"label":"Экономика","value":"121"},{"label":"Экспансия","value":"110"},{"label":"Эксперименты над людьми","value":"7408"},{"label":"Элементальная магия","value":"1264"},{"label":"Эльфы","value":"1362"},{"label":"Эротика","value":"2053"},{"label":"Юмор","value":"7360"},{"label":"Яды","value":"201"},{"label":"Якудза","value":"4599"},{"label":"Яндере","value":"7111"},{"label":"Rpg","value":"90"},{"label":"Star wars","value":"1985"},{"label":"Time skip","value":"824"},{"label":"Warrior of light","value":"5289"}],"inputType":FilterInputs.Checkbox},{"key":"fandoms_ex","label":"Исключить фэндомы:","values":[{"label":"19 Дней - Один день / 19 Days - One Day","value":"838"},{"label":"47-й / Хитмэн: Агент 47 / Наёмный убийца / Hitman","value":"589"},{"label":"Абсолютный дуэт / Absolute Duo","value":"1029"},{"label":"Аватар (Короля; об Аанге; об Корре) / Avatar","value":"1889"},{"label":"Аватар: Легенда о Корре / Avatar legend of Korra","value":"351"},{"label":"Аватар: Легенда об Аанге / Avatar: The Legend of Aang / Avatar: The Last Airbender","value":"303"},{"label":"Аватар(Фильм, 2009) / Avatar","value":"19"},{"label":"Ад Данте(Данте Алигьери) / Dante's Inferno(Dante Alighieri)","value":"1502"},{"label":"Азур Лейн / Azur Lane","value":"1009"},{"label":"Айон / Aion","value":"1005"},{"label":"Аладдин / Aladdin","value":"502"},{"label":"Алиса в Стране чудес / Alice in Wonderland","value":"616"},{"label":"Альдноа.Зеро / Aldnoah.Zero","value":"1799"},{"label":"Амагами СС / Amagami SS","value":"900"},{"label":"Амано Мегуми полна любви! / Amano Megumi wa Sukidarake!","value":"991"},{"label":"Американские боги / American Gods","value":"1843"},{"label":"Американский папаша! / American Dad","value":"348"},{"label":"Ангельские ритмы! / Angel Beats!","value":"880"},{"label":"Анлимитед: Хёбу Кёске / Zettai Karen Children: The Unlimited - Hyoubu Kyousuke","value":"74"},{"label":"Апостол карточек / The Apostle of Cards","value":"1504"},{"label":"Арифурэта: сильнейший ремесленник в мире / Arifureta: From Commonplace to World's Strongest","value":"62"},{"label":"Аркан: О Паровых Заводах и Магии Обскуры / Arcanum: Of Steamworks and Magick Obscura","value":"1495"},{"label":"Аркейн / Arcane: League of Legends","value":"1154"},{"label":"Аркнайтс(Games) / Arknights","value":"1210"},{"label":"Армелло(Games) / Armello","value":"1846"},{"label":"Астра, затерянная в космосе / Kanata no Astra","value":"1851"},{"label":"Атака титанов / Атака на титанов / Attack on Titan","value":"106"},{"label":"Атлантида: Затерянный мир / Atlantis: The Lost Empire","value":"985"},{"label":"Бакуган Отчаянные бойцы / Bakugan Battle Brawlers","value":"1069"},{"label":"Банановая рыба / Banana Fish","value":"1685"},{"label":"Баскетбол Куроко / Kuroko no basuke","value":"582"},{"label":"Баффи - Истребительница вампиров / Buffy the Vampire Slayer","value":"115"},{"label":"Башня Бога / Tower of God","value":"58"},{"label":"Бездарная Нана / Munou na Nana","value":"954"},{"label":"Бездомный бог / Норагами / Noragami","value":"1014"},{"label":"Безумные Мотивы / Looney Tunes","value":"1140"},{"label":"Безумный азарт / Kakegurui","value":"334"},{"label":"Бейблэйд / Beyblade","value":"921"},{"label":"Бен - 10 / Ben 10","value":"475"},{"label":"Берсерк / Berserk","value":"479"},{"label":"Бесконечное лето / Everlasting Summer","value":"966"},{"label":"Бесконечный ужас / Terror Infinity","value":"381"},{"label":"Бесподобный Воинственный Бог / Peerless Martial God","value":"419"},{"label":"Бессмертный Деревенщина(Games) / Immortal Redneck","value":"1524"},{"label":"Бесстыжие / Shameless","value":"1759"},{"label":"Био шок(Games) / BioShock","value":"1095"},{"label":"Блейд / Blade","value":"1479"},{"label":"Блич / Bleach","value":"7"},{"label":"Бог войны / God Of War","value":"352"},{"label":"Бог из машины / Deus Ex","value":"612"},{"label":"Боги поступают плохо / Игры богов / Gods Behaving Badly","value":"301"},{"label":"Боевая академия города Астериск / Gakusen Toshi Asterisk","value":"884"},{"label":"Боевой континент / Combat Continent / Douluo Dalu","value":"739"},{"label":"Боевой молот 40-го тысячелетия / WH40K / Warhammer 40,000","value":"341"},{"label":"Боевой молот Фэнтезийная битва / Warhammer Fantasy Battles","value":"1742"},{"label":"Боевые машины(Games) / BattleTech","value":"1667"},{"label":"Боец Баки / Baki the Grappler","value":"821"},{"label":"Божественность II: Эго Дракона(Games) / Divinity II: Ego Draconis","value":"1538"},{"label":"Божественные Врата / Divine Gate","value":"1490"},{"label":"Большая автомобильная кража 5 / GTA V / Grand Theft Auto V","value":"1139"},{"label":"Большая автомобильная кража: Сан-Андреас / GTA: SA / Grand Theft Auto: San Andreas","value":"820"},{"label":"Большая разница / Far Cry","value":"939"},{"label":"Большой куш / Ван Пис / One Piece","value":"25"},{"label":"Боруто: Следующие поколения Наруто / Boruto: Naruto Next Generations","value":"602"},{"label":"Брак по договоренности с принцессой красных скорпионов / Arranged marriage to the princess of the Red Scorpions","value":"1386"},{"label":"Бэтмен за гранью: Наследие / Batman Beyond: Legacy","value":"1380"},{"label":"В другом мире со смартфоном / Isekai wa Smartphone to Tomo ni","value":"947"},{"label":"В объятиях шлюхи / JK Bitch ni Shiboraretai","value":"1283"},{"label":"В ожидании бедности, я собираюсь стать кузнецом / Expecting to Fall into Ruin, I Aim to Become a Blacksmith","value":"1475"},{"label":"В Повелителе как Довакин / In Overlord as a Dovahkiin","value":"1816"},{"label":"Вакфу / Wakfu","value":"814"},{"label":"ВАЛЛ-И / Wally","value":"801"},{"label":"Вампир: Маскарад - Родословные / Vampire: The Masquerade Bloodline","value":"1212"},{"label":"Вампирелла / Vampirella","value":"1214"},{"label":"Варфрейм / Warframe","value":"967"},{"label":"Ведьмак / The Witcher","value":"278"},{"label":"Великий из бродячих псов / Bungou Stray Dogs","value":"75"},{"label":"Великолепный парк Амаги / Amagi Brilliant Park","value":"813"},{"label":"Вельзепуз / Вельзевул / Beelzebub","value":"765"},{"label":"Веном / Venom","value":"978"},{"label":"Веселая ферма / Fun Farm","value":"1124"},{"label":"Вечная история / The Neverending Story","value":"547"},{"label":"Вечные(Фильм, 2021) / Eternal","value":"1234"},{"label":"Виви: Песнь флюоритового глаза / Vivy: Fluorite Eye's Song","value":"1819"},{"label":"Викинги / Vikings","value":"369"},{"label":"Владелец ранчо со слизью(Games) / Ранчо слизи / Slime Rancher","value":"1529"},{"label":"Властелин колец / Lord of the Ring","value":"254"},{"label":"Власть книжного червя / Honzuki no Gekokujou","value":"1399"},{"label":"Внук Мудрец / Kenjo no Mago","value":"1260"},{"label":"Внук Нурарихёна / Nurarihyon no Mago","value":"66"},{"label":"Во всеоружии / Overgeared","value":"1021"},{"label":"Во тьме(Games) / The Darkness","value":"938"},{"label":"Военная хроника маленькой девочки / Сага о злой Тане / The Saga of Tanya the Evil / \tGekijouban Youjo Senki","value":"1726"},{"label":"Возвращение в детские годы / Gaki ni Modotte Yarinaoshi!!!","value":"1031"},{"label":"Возрождение Серийного Убийцы / Rebirth Of A Serial Killer","value":"1358"},{"label":"Воинственный Бог Асура / Martial God Asura","value":"771"},{"label":"Война будущего / The Tomorrow War","value":"1174"},{"label":"Война Любовь Снег / War Love Snow","value":"1417"},{"label":"Волейбол! / Haikyuu!!","value":"697"},{"label":"Волчонок / Teen Wolf","value":"795"},{"label":"Волшебная Девушка Спецоперация Аска / Magical Girl Spec-Ops Asuka","value":"1470"},{"label":"Волшебник-воин Орфен / Majutsushi Orphen Hagure Tabi: Kimluck-hen","value":"1128"},{"label":"Волшебники / The Magicians","value":"1314"},{"label":"Волшебный учитель Нэгима! / Negima!: Magister Negi Mag","value":"1777"},{"label":"Воля второго цикла мироздания. / Will of the second cycle of the Worldifice.","value":"1036"},{"label":"Воспитание хозяина / Yours to Claim","value":"839"},{"label":"Восставший против неба / Against the Gods","value":"957"},{"label":"Восстание стражей / Хранители снов / Rise of the Guardians","value":"1488"},{"label":"Восхождение в Голливуде / I'm in Hollywood","value":"1237"},{"label":"Восхождение героя щита / The Rising of the Shield Hero","value":"103"},{"label":"Врата Штейна / Steins: Gate","value":"1044"},{"label":"Врата: там бьются наши воины / Gate: Jieitai Kanochi nite, Kaku Tatakaeri","value":"727"},{"label":"Время / In Time","value":"542"},{"label":"Всегда вялый Танака-кун / Tanaka-kun wa Itsumo Kedaruge","value":"1082"},{"label":"Всего лишь восьмой сын? Я с этим не смирюсь! / Hachinan tte, Sore wa Nai Deshou! / Eighth son, I don’t think so!","value":"1473"},{"label":"Вселенная Марвел / Marvel Universe / Marvel Comics","value":"6"},{"label":"Вселенная монстров / Monsterverse / Monster Verse","value":"905"},{"label":"Вселенная Стивена / Steven universe","value":"573"},{"label":"Вселенная Стрелы / Arrowverse","value":"488"},{"label":"Вселенная Тип Луны(Игровая компания) / Universe Type Moon","value":"1221"},{"label":"Вселенная DC / DC Universe / DC Comics","value":"36"},{"label":"Выпадение радиоактивных осадков / Fallout","value":"55"},{"label":"Выращивание онлайн / Cultivation Online","value":"1252"},{"label":"Галактическая секс-звезда / Galaxy Sex Star","value":"1539"},{"label":"Гало(Games) / Halo","value":"1338"},{"label":"Ганц / Gantz","value":"256"},{"label":"Гарем рабов в лабиринте другого мира / Slave Harem in the Labyrinth of the Other World","value":"1853"},{"label":"Гарри Поттер / Harry Potter","value":"1"},{"label":"Гвен-паук / Spider-Gwen","value":"920"},{"label":"Генерал маньяк с его сумасшедшей системой / The Maniacal General with his Crazy System","value":"1356"},{"label":"Генерал, вы вправе уйти. / General, You May Leave Now","value":"1385"},{"label":"Геншин Импакт / Genshin Impact","value":"689"},{"label":"Геркулес / Hercules","value":"721"},{"label":"Герои и замки / Heroes & Castles","value":"940"},{"label":"Герои меча и магии / Heroes of Might and Magic","value":"1002"},{"label":"Герои(телесериал) / Heroes","value":"864"},{"label":"Гильгамеш / Gilgamesh","value":"1143"},{"label":"Гинтама / Gintama","value":"129"},{"label":"Глубина(Фильм, 2002) / Below","value":"1186"},{"label":"Гнев Асуры / Asura's wrath","value":"100"},{"label":"Годзилла / Godzilla","value":"922"},{"label":"Голодные игры / The Hunger Games","value":"859"},{"label":"Горец / Highlander","value":"1761"},{"label":"Горожане(Games) / Townsmen","value":"1599"},{"label":"Госпожа Кагуя: в любви как на войне / Kaguya sama: Love is war","value":"533"},{"label":"Готика / Gothic","value":"418"},{"label":"Готов ли ты влюбиться в извращенку до тех пор, пока она милая? / Hentai demo Suki ni Natte Kuremasu ka","value":"1383"},{"label":"Гоэтия / Гоетия / Yοητεία / Ars Goetia","value":"772"},{"label":"Гравити Фолз / Gravity Falls","value":"491"},{"label":"Граница пустоты / Kara no Kyoukai","value":"1101"},{"label":"Гриффины / Family Guy","value":"349"},{"label":"Гром над небом / Thunder over the sky","value":"793"},{"label":"Гуррен-Лаганн / Tengen Toppa Gurren Lagann","value":"719"},{"label":"Да будет благословенен этот прекрасный мир! / Konosuba / Kono Subarashii Sekai ni Shukufuku wo!","value":"82"},{"label":"Да Здравствует Призыв! / Long Live Summons!","value":"948"},{"label":"Да, я паук, и что с того? / So I'm a Spider, So What? / Kumo Desu ga, Nani ka?","value":"910"},{"label":"Данганронпа / Danganronpa","value":"972"},{"label":"Две звезды Онмёджи / Sousei no Onmyouji","value":"1108"},{"label":"Дворянство / Благородство / Noblesse","value":"636"},{"label":"Девочка-волшебница Мадока Магика / Mahou Shoujo Madoka Magica","value":"1412"},{"label":"Девочка, которая видит это / Mieruko-chan","value":"1645"},{"label":"Декстер(телесериал) / Dexter","value":"1543"},{"label":"Демон Бездны всех царств / Abyss Demon of All Realms","value":"1419"},{"label":"Демоны старшей школы / High School DxD","value":"8"},{"label":"День независимости(Фильм, 1996) / Independence Day","value":"850"},{"label":"Детектив Конан / Detective Conan","value":"1554"},{"label":"Дети индиго из другого мира / Mondaiji-tachi ga isekai kara kuru sô desu yo","value":"1484"},{"label":"Джаггед Альянс 2: Агония Власти(Games) / Jagged Alliance 2","value":"1668"},{"label":"Джессика Джонс / Marvel's Jessica Jones","value":"1817"},{"label":"Джон Уик / John Wick","value":"388"},{"label":"Дисней / The Walt Disney Company","value":"503"},{"label":"Для тебя, Бессмертный / Fumetsu no Anata e / To Your Eternity","value":"1802"},{"label":"Дневник Будущего / Mirai Nikki","value":"368"},{"label":"Дневники вампира / The Vampire Diaries","value":"160"},{"label":"Доблесть рыцаря-неудачника / Chivalry of a Failed Knight","value":"1462"},{"label":"Добро пожаловать в ад, Ирума / Welcome to Demon School! Iruma-kun","value":"261"},{"label":"Добро пожаловать в класс превосходства / Classroom of the Elite","value":"122"},{"label":"Добро пожаловать! В лес похотливых эльфов! / Youkoso! Sukebe Elf no Mori e","value":"1034"},{"label":"Добывать ремесло / Майнкрафт / Minecraft","value":"102"},{"label":"Доктор Кто / Doctor Who","value":"277"},{"label":"Доктор Стоун / Dr. Stone","value":"720"},{"label":"Доля секунды: скорость / Split - second: velocity","value":"890"},{"label":"Дом кролика / Кофейня "Кроличий домик" / Gochuumon wa Usagi Desu ka?","value":"642"},{"label":"Домашний очаг / Hearthstone: Heroes of Warcraft / Hearthstone","value":"934"},{"label":"Домекано / Domestic Na Kanojo","value":"632"},{"label":"Дорогой звёзд / Звёздное преобразование / Stellar Transformation / Xing Chen Bian","value":"1155"},{"label":"Доспехи Бога 2: Операция Кондор / Armour of God II: Operation Condor","value":"1829"},{"label":"Дота 2 / Dota 2","value":"1105"},{"label":"Дофус / Dofus","value":"817"},{"label":"Дракенгард / Drakengard / Drag-On Dragoon","value":"919"},{"label":"Дракон-горничная госпожи Кобаяси / Kobayashi-san Chi no Maid Dragon","value":"673"},{"label":"Дракон-сама из семьи Касумигаока / Dragon-sama of the Kasumigaoka Family","value":"1458"},{"label":"Драконий жемчуг Зет / Dragon Ball Z","value":"307"},{"label":"Дракониум Онлайн / Draconic Online","value":"1360"},{"label":"Дракула / Dracula","value":"709"},{"label":"Древнегреческая мифология / Ancient Greek mythology","value":"1159"},{"label":"Дре́вние / Первородные / The Originals","value":"863"},{"label":"Древние свитки / The Elder Scrolls","value":"428"},{"label":"Древние свитки: Скайрим / TES: Skyrim","value":"337"},{"label":"Другой мир / Underworld","value":"480"},{"label":"Друид с Сеульской станции / Seoul Station Druid","value":"1178"},{"label":"Дьявол / Диабло / Diablo","value":"1787"},{"label":"Дьявол может плакать / Devil May Cry / DMC","value":"339"},{"label":"Дьявол Юраги-су / The Devil of Yuragi-sou","value":"431"},{"label":"Дьявол II(Games) / Диабло II / Diablo II","value":"1055"},{"label":"Дэдпул / Deadpool","value":"810"},{"label":"Дэнни-призрак / Danny Phantom","value":"109"},{"label":"Евангелион / Neon Genesis Evangelion","value":"583"},{"label":"Единство семи магов / Тринити: Семь Магов / Trinity Seven","value":"442"},{"label":"Еженедельный прыжок сёнэн / Weekly Shōnen Jump","value":"1629"},{"label":"Ёрмунганд / Jormungand","value":"77"},{"label":"Жажда скорости / Need For Speed","value":"1493"},{"label":"Железный человек / Iron Man","value":"710"},{"label":"Жемчуг дракона / Dragon Ball","value":"309"},{"label":"Женщина-Халк(телесериал) / She-Hulk: Attorney at Law","value":"1593"},{"label":"Жизнь девушки в игровом мире / A Girl’s Life In A Gaming World","value":"1406"},{"label":"Жизнь после / Days Gone","value":"1279"},{"label":"За гранью / Beyond the Boundary","value":"357"},{"label":"Загипнотизировать Семью / Kyonyuu Kazoku Saimin","value":"1032"},{"label":"Закон Уэки / The Law of Ueki","value":"790"},{"label":"Закулисье / Backrooms","value":"1827"},{"label":"Зачарованные / Charmed","value":"113"},{"label":"Защитники / Defenders","value":"1832"},{"label":"Защитница Химари / Omamori Himari","value":"279"},{"label":"Звёздная принцесса и силы зла\t / Стар против сил зла / Star vs. The Forces of Evil","value":"782"},{"label":"Звёздное дитя / Oshi no Ko","value":"1903"},{"label":"Звёздное ремесло / StarCraft","value":"386"},{"label":"Звездные Войны / Star Wars","value":"40"},{"label":"Звёздные войны: Войны клонов - Все типы носителей(мультсериал, 2008) / Star Wars: The Clone Wars","value":"1182"},{"label":"Звёздные врата / Stargate","value":"770"},{"label":"Звёздные врата: Атлантида / Stargate: Atlantis","value":"1097"},{"label":"Звездный путь / Стартрек / Star Trek","value":"849"},{"label":"Зверополис / Zootopia","value":"1449"},{"label":"Зеленая Жизнь / Green Life","value":"1196"},{"label":"Зеленый фонарь / The Green Lantern","value":"1222"},{"label":"Зетмен / Zetman","value":"1191"},{"label":"Игра в кальмара(телесериал) / Squid game","value":"1065"},{"label":"Игра престолов / Game of Thrones","value":"22"},{"label":"Игрок / The Gamer","value":"126"},{"label":"Идеальная судьба / The Perfect Destiny","value":"781"},{"label":"Идолмастер / The Idolmaster","value":"807"},{"label":"Иерихон Клайва Баркера / Иерихон / Clive Barker’s Jericho /Jericho","value":"320"},{"label":"Извивающийся дракон / Coiling Dragon","value":"692"},{"label":"Изгнаные королевства РПГ / Exiled Kingdoms RPG","value":"1375"},{"label":"Импульс Валькирии: Сирена / Варукири Дораиву: Сирена / Valkyrie Drive: Mermaid","value":"1736"},{"label":"Индекс волшебства / A Certain Magical Index","value":"68"},{"label":"Инуяша - Пес-демон / InuYasha","value":"481"},{"label":"Искусственный отбор / Triage X","value":"1037"},{"label":"Истинный мир боевых искусств / Zhenwu Shijie / True Martial World","value":"867"},{"label":"История монстров / Monogatari","value":"911"},{"label":"История о второстепенном персонаже который стал игроком в другой игре. / The story is about a minor character who became a player in another game.","value":"868"},{"label":"Кабанери железной крепости / Koutetsujou no Kabaneri","value":"1494"},{"label":"Каждый раз, когда я сплю, моя душа покидает мое тело / Every Day I Sleep, My Soul Goes Out of My Body","value":"1048"},{"label":"Как воспитать героиню из обычной девушки / Saenai Heroine no Sodatekata","value":"1637"},{"label":"Как игрок глупой FPS попал в иной мир / Как дурачок из стрелялки в другой мир попал / Manuke na FPS Player ga Isekai e Ochita Baai","value":"746"},{"label":"Как приручить дракона / How to Train Your Dragon","value":"687"},{"label":"Капитан Америка / Captain America","value":"1425"},{"label":"Капитан Марвел(Фильм, 2019) / Captain Marvel","value":"1594"},{"label":"Каратель / The Punisher","value":"387"},{"label":"Касл / Castle","value":"389"},{"label":"Касльвания / Castlevania","value":"1215"},{"label":"Катаклизм: Тёмные дни впереди / DDA / Cataclysm: Dark Days Ahead","value":"680"},{"label":"Квайзер со Стигматом / Адепт Святого Знака / The Qwaser of Stigmata","value":"72"},{"label":"Квартет из альтернативного мира / Isekai Quartet","value":"1801"},{"label":"Квест Девушки-монстра / Monster Girl Questt","value":"928"},{"label":"Квест титана(Games) / Титанический квест / Titan Quest","value":"1483"},{"label":"Кенши(Games) / Kenshi","value":"1230"},{"label":"Киберпанк 2077 / Cyberpunk 2077","value":"416"},{"label":"Ким Пять-с-плюсом / Kim Possible","value":"436"},{"label":"Киру ра Киру / Круши Кромсай / Убей или умри / Kill la Kill","value":"763"},{"label":"Класс убийц / Assassination classroom","value":"610"},{"label":"Клеймор / Claymore","value":"110"},{"label":"Клинок зла / Evil Blade / Übel Blatt","value":"722"},{"label":"Клинок королевы / Queen’s Blade","value":"757"},{"label":"Клинок Маню: Тайна сисечного свитка / Manyuu Hiken-chou","value":"501"},{"label":"Клинок рассекающий демонов / Demon Slayer: Kimetsu no Yaiba","value":"21"},{"label":"Клуб Винкс / Winx Club","value":"397"},{"label":"Книга джунглей / The Jungle Book","value":"1688"},{"label":"Князь тьмы с задней парты / Demon King Daimao / Ichiban Ushiro no Daimaou","value":"1207"},{"label":"Код Гиас / Code Geass","value":"340"},{"label":"Код Квалидеи / Qualidea Code","value":"76"},{"label":"Кольцо Элдена / Elden Ring","value":"1408"},{"label":"Комната / The Room","value":"889"},{"label":"Конь и клинок: Боевой отряд(Games) / Mount and Blade:Warband","value":"1477"},{"label":"Королевства Сердец / Kingdom Hearts","value":"407"},{"label":"Короли крестоносцев / Crusader kings","value":"572"},{"label":"Король бойцов / The King of Fighters","value":"1378"},{"label":"Король лев / The Lion king","value":"1705"},{"label":"Король Шаманов / Shaman King","value":"744"},{"label":"Корона греха / Guilty Crown","value":"1007"},{"label":"Корпорация лоботомии / Lobotomy corporation","value":"852"},{"label":"Космические рейнджеры(Games) / Space Rangers","value":"1508"},{"label":"Кошечка из Сакурасо / Sakurasou no Pet na Kanojo","value":"605"},{"label":"Красавица и чудовище / Beauty and the Beast","value":"1765"},{"label":"Красная угроза 3 / Command & Conquer: Red Alert 3","value":"742"},{"label":"Красный, Белый, Черный, Желтый / RWBY","value":"131"},{"label":"Кредо убийцы / Assassin's Creed","value":"690"},{"label":"Кризис / Crysis","value":"1734"},{"label":"Крушитель / The Breaker","value":"1080"},{"label":"Кунг-фу панда / Kung Fu Panda","value":"831"},{"label":"Кэйон! / K-On!","value":"1785"},{"label":"Кэнган Асура / Kengan Asura","value":"726"},{"label":"Лаборатория Декстера / Dexter Lab","value":"639"},{"label":"Лавкрафт / Говард Филлипс Лавкрафт / Howard Phillips Lovecraft","value":"1259"},{"label":"Легенда о восьми псах востока / Hakkenden: Touhou Hakken Ibun","value":"1699"},{"label":"Легенда о Зельде / The Legend of Zelda","value":"870"},{"label":"Легенда о Короле Драконов / Legend of the Dragon King","value":"623"},{"label":"Легенда о Легендарных Героях / Densetsu no Yuusha no Densetsu","value":"193"},{"label":"Легион Супергероев / The Legion of Super-Heroes","value":"450"},{"label":"Леди Баг и Супер-Кот / Miraculous Ladybug","value":"327"},{"label":"Летняя сага / Summertime Saga","value":"1441"},{"label":"Лига Легенд / League of Legends","value":"65"},{"label":"Линия фронта для девочек / Girls' Frontline","value":"1686"},{"label":"Литературный клуб Доки Доки / Литературный клуб / Doki Doki literature club!","value":"819"},{"label":"Лорд героев(Games) / Lord of Heroes","value":"1771"},{"label":"Лорд человечества / Lord of the People","value":"1896"},{"label":"Лориенская Сага / Lorien Legacies","value":"521"},{"label":"Любимая жена господина генерального директора / Mr.CEO's Beloved Wife","value":"1389"},{"label":"Любовные неприятности / To love ru","value":"353"},{"label":"Любовь, Деньги, Рок-н-Ролл / Love, Money, Rock'n'Roll","value":"1890"},{"label":"Люди в чёрном(Фильм) / Men in Black","value":"1193"},{"label":"Люди Икс / X-Men","value":"371"},{"label":"Лютер Строуд Сага / The Luther Strode Saga","value":"1700"},{"label":"Люцифер(телесериал) / Lucifer","value":"681"},{"label":"Маг на полную ставку / Quanzhi Fashi","value":"291"},{"label":"Маг смерти не желающий четвертой реинкарнации / The Death Mage Who Doesn’t Want a Fourth Time","value":"1775"},{"label":"Маг-целитель: Новый старт / Kaifuku Jutsushi no Yarinaoshi","value":"1311"},{"label":"Маги: Волшебный лабиринт / Magi: The Labyrinth of Magic","value":"1581"},{"label":"Магистр дьявольского культа / The Grandmaster of Demonic Cultivation","value":"608"},{"label":"Магическая академия Атараксия: Гибрид х Сердце / Hybrid x Heart Magias Academy Ataraxia","value":"1898"},{"label":"Магическая битва / Magic Battle / Jujutsu Kaisen","value":"671"},{"label":"Маленькие кошмары 2 / Little Nightmares 2","value":"601"},{"label":"Малефисента / Maleficent","value":"775"},{"label":"Мальчик с оленьими рогами / Сладкоежка / Sweet tooth","value":"1772"},{"label":"Маска / The mask","value":"847"},{"label":"Мастер Урадана / The Master of Uradan","value":"1395"},{"label":"Мастера меча онлайн / Sword Art Online / SAO","value":"324"},{"label":"Межвидовые Рецензенты / Interspecies Reviewers","value":"1555"},{"label":"Менеджер среднего звена Тонэгава / Chuukan Kanriroku Tonegawa","value":"1084"},{"label":"Мерлин / Merlin","value":"486"},{"label":"Мертвы к Рассвету / Dead by Daylight","value":"899"},{"label":"Мертвый или живой / Dead or Alive","value":"1563"},{"label":"Мертвый остров / Dead Island","value":"124"},{"label":"Месть Масамуне-куна! / Masamune-kun no Revenge","value":"571"},{"label":"Метавселенная Рудазова / Rudazov's Metauniverse","value":"1211"},{"label":"Метро 2033(Games) / Metro 2033","value":"1584"},{"label":"Милый во Франксе / Любимый во Франксе / Darling in the Franxx","value":"942"},{"label":"Мир боевых искусств / 武极天下 / Wuji Tianxia / Martial World","value":"620"},{"label":"Мир зомби / Zombie World","value":"1880"},{"label":"Мир Льда и Пламени / The World of Ice & Fire","value":"415"},{"label":"Мир приключений Джеки Чана(мультсериал, 2000) / ackie Chan Adventures","value":"1544"},{"label":"Мир танков / WoT Blitz / World of Tanks Blitz","value":"525"},{"label":"Мир Тьмы / World of Darkness","value":"145"},{"label":"Мир Эрастай / The World of Erasthay","value":"1836"},{"label":"Мир Warcraft / World of Warcraft","value":"89"},{"label":"Мировая война Z / Война миров Z / World War Z","value":"1217"},{"label":"Моана / Moana","value":"686"},{"label":"Моб психо 100 / Mob Psycho 100","value":"866"},{"label":"Мобильные легенды: Бах-Бах(Games) / Mobile Legends: Bang Bang","value":"1497"},{"label":"Могучие рейнджеры / Power Rangers","value":"1486"},{"label":"Может, я встречу тебя в подземелье? / DanMachi","value":"9"},{"label":"Мой жених сбежал / My Groom Ran Away","value":"1047"},{"label":"Мой маленький пони / My Little Pony","value":"655"},{"label":"Мой маленький пони: Дружба — это чудо / My Little Pony: Friendship is Magic","value":"658"},{"label":"Мой шумный дом(мультсериал, 2016) / The Loud House","value":"1467"},{"label":"Монстер Хай / Monster High","value":"1012"},{"label":"Моя возлюбленная чпокается со всеми / Kanojo wa Dare to demo Sex Sur","value":"1274"},{"label":"Моя геройская академия / Boku no Hero Academia","value":"69"},{"label":"Моя девушка - зомби / My Girlfriend is a Zombie","value":"754"},{"label":"Моя жена - красивый генеральный директор / My Wife is a Beautiful CEO","value":"1025"},{"label":"Моя жена — президент студенческого совета! / My Wife is the Student Council President / Okusama ga Seitokaichou","value":"241"},{"label":"Моя Марвел Академия / My marvel academia","value":"696"},{"label":"Моя первая модница / Hajimete no Gal","value":"1835"},{"label":"Моя Супер-Бывшая / My Super Ex-Girlfriend","value":"1828"},{"label":"Мрачный рассвет / Grim Dawn","value":"1113"},{"label":"Мстители / The Avengers","value":"1747"},{"label":"Мстители. Эра Альтрона / The Avengers. Age of Ultron","value":"784"},{"label":"Мулан / Mulan","value":"706"},{"label":"Мы не можем учится / Bokutachi wa Benkyou ga Dekinai","value":"912"},{"label":"Мэй Гунцин / Mei Gongqing","value":"753"},{"label":"Наблюдать / Overwatch","value":"607"},{"label":"Надпись / Inscription","value":"1718"},{"label":"Нам Ён / Nam Yeon","value":"1188"},{"label":"Наруто / Naruto","value":"3"},{"label":"Начало после конца / The Beginning After The End","value":"888"},{"label":"Не голодай / Don't Starve","value":"274"},{"label":"Не издевайся надо мной, Нагаторо / Ijiranaide / Nagatoro-san Don't Toy with Me, Miss Nagatoro","value":"1041"},{"label":"Не люблю боль, так что вкачаю все в защиту / Itai no wa Iya nano de Bougyoryoku ni Kyokufuri Shitai to Omoimasu","value":"517"},{"label":"Не моя вина, что я непопулярна! / Watashi ga Motenai no wa Dou Kangaetemo Omaera ga Warui","value":"1381"},{"label":"Небесный замок Лапута / Tenkuu no Shiro Laputa","value":"1109"},{"label":"Невероятные приключения ДжоДжо / JoJo's Bizarre Adventure","value":"20"},{"label":"Негодник, которому не снилась девочка-зайка / Rascal Does Not Dream of Bunny Girl Senpai","value":"1897"},{"label":"Негодяй спасает мужскую роль / The Villain Saves the Male Lead","value":"1224"},{"label":"Неизвестен / Persona","value":"205"},{"label":"Некий магический индекс / To Aru Majutsu no Index","value":"562"},{"label":"Некий научный акселератор / Toaru Kagaku no Accelerator","value":"1487"},{"label":"Ненасытный Берсерк / Boushoku no Berserk: Ore dake Level to Iu Gainen wo Toppa suru the Comic","value":"1195"},{"label":"Необъятные небеса / Infinite Stratos / IS","value":"280"},{"label":"Необъятный океан / Grand Blue","value":"531"},{"label":"Непревзойденная / Master Piece The Animation","value":"712"},{"label":"Непризнанный школой владыка демонов / Maou Gakuin no Futekigousha","value":"1476"},{"label":"Непутевый ученик в школе магии / Mahouka Koukou No Rettousei","value":"982"},{"label":"Непутевый ученик в школе магии / The Irregular at Magic High School","value":"630"},{"label":"Несокрушимая механическая кукла / Machine-Doll wa Kizutsukanai","value":"1030"},{"label":"Несправедливость / Injustice","value":"1026"},{"label":"Нет игры - нет жизни / Без игры жизни нет / No Game No Life","value":"718"},{"label":"Неуязвимый / Invincible","value":"702"},{"label":"НиоХ(Games) / NioH","value":"1465"},{"label":"Новый завет Владыки тьмы / Shinmai Maou no Testament","value":"1432"},{"label":"Ну и ну! Земляничные яйца / I My Me! Strawberry Eggs","value":"1485"},{"label":"Нулевой Уровень Целомудрия / Teisou Kannen Zero","value":"1209"},{"label":"О моём перерождении в меч / Tensei Shitara Ken deshita","value":"53"},{"label":"О моём перерождении в слизь / Tensei shitara Slime Datta Ken","value":"64"},{"label":"О моя Богиня / Aa! Megami-sama! / Ah! My Goddess","value":"915"},{"label":"Обесчещенный(Games) / Dishonored","value":"1073"},{"label":"Обитель зла / Resident Evil","value":"86"},{"label":"Огненная эмблема / Fire Emblem","value":"1615"},{"label":"Огненная эмблема: Пробуждение / Fire Emblem: Awakening","value":"1616"},{"label":"Огненная эмблема: Три Дома / Fire Emblem:Three Houses","value":"1716"},{"label":"Одинокий рокер! / Bocchi the Rock!","value":"1904"},{"label":"Одному лишь Богу ведомый мир / World God Only Knows","value":"1248"},{"label":"Она становится гламурной после расторжения помолвки / She gets glamorous after the engagement is annulled","value":"1404"},{"label":"Орк-рубака / Orc Grunt","value":"779"},{"label":"Освободите эту ведьму / Release that witch","value":"994"},{"label":"Острые козырьки(телесериал) / Peaky Blinders","value":"1177"},{"label":"От заката до рассвета! / From Dusk till Dawn!","value":"1416"},{"label":"Отброс из семьи графа / Trash of counts family","value":"853"},{"label":"Отряд самоубийц / The Suicide Squad","value":"1844"},{"label":"Отчаянные домохозяйки / Desperate Housewives","value":"1011"},{"label":"Отчет о буйстве духов / YuYu Hakusho","value":"1008"},{"label":"Охота демонического короля на свою жену / Xie Wang Zhui Qi","value":"1737"},{"label":"Охотник х Охотник / Hunter x Hunter","value":"101"},{"label":"Охотницы на демонов / Taimanin Asagi","value":"1463"},{"label":"Очень приятно Бог! / Kamisama Hajimemashita","value":"1585"},{"label":"Очень Странные Дела(телесериал) / Stranger Things","value":"1834"},{"label":"ПАЗЛ / PUZZLE","value":"1762"},{"label":"Палач Рока / DOOM","value":"132"},{"label":"Параграф 78(Фильм) / Paragraph 78","value":"923"},{"label":"Паразит: Учение о жизни / Parasyte: The Maxim","value":"1176"},{"label":"Пастырь(Фильм, 2011) / Priest","value":"1173"},{"label":"Пацаны / The Boys","value":"133"},{"label":"Первый детский сад во вселенной / The First Kindergarten in the Universe","value":"1049"},{"label":"Перевозчик / Le Transporteur","value":"365"},{"label":"Передающийся через кровь / Bloodborne","value":"229"},{"label":"Пережить / Outlast","value":"645"},{"label":"Перерождение / Rebirth","value":"550"},{"label":"Перерождение бессмертного горожанина-культиватора / Rebirth – City Cultivation / Rebirth of the Urban Immortal Cultivator","value":"843"},{"label":"Перерождение в монстра / Re:Monster","value":"85"},{"label":"Перестрой мир / Sekai O Sai Kochiku / Rebuild World","value":"961"},{"label":"Период полураспада(Valve) / Half-Life","value":"895"},{"label":"Перси Джексон / Percy Jackson","value":"308"},{"label":"Персона 5 / Persona 5","value":"1614"},{"label":"Печать ветра / Kaze no Stigma","value":"845"},{"label":"Пик боевых искусств / Martial Peak","value":"414"},{"label":"Пираты Карибского моря / Pirates of the Caribbean","value":"932"},{"label":"Пираты черной лагуны / Black Lagoon","value":"621"},{"label":"Пламенная бригада пожарных / Fire Force / Enen no Shouboutai","value":"841"},{"label":"Пламя бесчисленых невзгод / I' m really not demon god's lackey","value":"1452"},{"label":"Планетарная аннигиляция / Planetary Annihilation","value":"487"},{"label":"Плоскостной пейзаж: Мучение / Planescape: Torment","value":"1768"},{"label":"По велению адской сестры / The Testament of Sister New Devil","value":"18"},{"label":"Поборники тьмы / Darksiders","value":"1028"},{"label":"Повар небесной гостиницы / Чем кормят в ином мире / Kakuriyo no Yadomeshi","value":"998"},{"label":"Повар-боец Сома / В поисках божественного рецепта / Shokugeki no Souma","value":"191"},{"label":"Повелитель тьмы на подработке! / Hataraku Maou-sama!","value":"674"},{"label":"Повелитель тьмы: Другая история мира / How Not to Summon a Demon Lord / Isekai Maou to Shoukan Shoujo no Dorei Majutsu","value":"699"},{"label":"Повелитель(Куганэ Маруяма) / Overlord","value":"27"},{"label":"Повелитель(Games) / Overlord","value":"1623"},{"label":"Повесть о Конце Света / Record of Ragnarok","value":"332"},{"label":"Повесть о лунной принцессе / Tsukihime: Lunar Legend","value":"750"},{"label":"Повесть о Небесных островах / Фэнтези Гранблю / Granblue Fantasy","value":"808"},{"label":"Повседневная жизнь бессмертного короля / The Daily Life of the Immortal King / Xian Wang de Richang Shenghuo","value":"1466"},{"label":"Повседневная жизнь с девушкой-монстром / Monster Musume","value":"760"},{"label":"Пограничье(Games) / Borderlands","value":"992"},{"label":"Под лунами Драконьих глаз / Beneath the Dragoneye Moons","value":"1735"},{"label":"Подземелья и драконы / Dungeons & Dragons","value":"81"},{"label":"Подземная история / Андертейл / Undertale","value":"390"},{"label":"Поднявшийся(Games) / Risen","value":"1273"},{"label":"Поднятие уровня в одиночку / Solo Leveling","value":"127"},{"label":"Подручный Луизы-Нулизы / Zero no Tsukaima","value":"580"},{"label":"Пожиратель богов / God Eater","value":"1321"},{"label":"Поймай себя ! Моя дорогая жена / Catch You ! My Dear Wife","value":"1317"},{"label":"Покемон / Pokemon","value":"43"},{"label":"Политическая Хроника Молодой Девушки / A Young Woman's Political Record","value":"1306"},{"label":"Полностью пленённые / Totally Captivated","value":"1086"},{"label":"Полый Рыцарь(Games) / Hollow Knight","value":"1198"},{"label":"Пользователи Силы / Forceusers","value":"1162"},{"label":"Поля битвы Неизвестного игрока / ПАБГ / Player Unknown's Battlegrounds / PUBG","value":"622"},{"label":"Попытка приручить злого повелителя / Trying to Tame an Evil Overlord","value":"983"},{"label":"Поработитель Ада / Helltaker","value":"776"},{"label":"Порновселенная / Porn Universe","value":"1776"},{"label":"Портал(Valve) / Portal","value":"800"},{"label":"Последние из нас / Last Of Us","value":"1717"},{"label":"Последний Серафим / Owari no Seraph","value":"551"},{"label":"Последняя из рода Блау(Тайга Ри) / The last of the Blau family","value":"1507"},{"label":"Последняя фантазия / ファイナルファンタジ / Final Fantasy","value":"769"},{"label":"Преподобное безумие / Reverend Insanity","value":"1280"},{"label":"Преподобный Гу / Gu Zhen Ren / Daoist Gu","value":"1464"},{"label":"Призрачный бегун / Ghostrunner","value":"613"},{"label":"Призрачный гонщик / Ghost Rider","value":"823"},{"label":"Принц Драконов Хаоса / The Chaos Dragon Prince","value":"1397"},{"label":"Принц Персии / Prince of Persia","value":"1535"},{"label":"Принцесса монстров / Princess Resurrection","value":"1304"},{"label":"Принцесса Цу / Не проиграю! / Maken Ki","value":"675"},{"label":"Проект „Восток“ / Touhou Project","value":"809"},{"label":"Проект Кей / K Project","value":"73"},{"label":"Проклятие: Автоматизация / NieR:Automata","value":"1496"},{"label":"Противостояние святого / Renegade Immortal","value":"926"},{"label":"Прототип / Prototype","value":"54"},{"label":"Пуленепробиваемый / Bang-Tan / BTS","value":"520"},{"label":"Путешествие на Запад / Journey to the West","value":"1833"},{"label":"Пять невест / Go-Toubun no Hanayome","value":"713"},{"label":"Пять ночей у Фредди / Five nights at freddy's","value":"930"},{"label":"Рагнарёк Онлайн / Ragnarok Online","value":"953"},{"label":"Радуга 6: Осада / Rainbow Six: Siege","value":"421"},{"label":"Развращение Дочери / Daraku Reijou Hakoiri Ojou-sama Netorare Choukyou Kiroku","value":"1284"},{"label":"Рай Грисайи / Эдем в серых тонах / Grisaia no Rakuen","value":"584"},{"label":"Рандеву с жизнью / Date A live","value":"851"},{"label":"Ранма ½ / Ranma ½","value":"1192"},{"label":"Рапунцель: Запутанная история / Tangled","value":"773"},{"label":"Расколотая битвой синева небес / Battle Through the Heavens","value":"927"},{"label":"Рассказ служанки / The Handmaid's Tale","value":"1135"},{"label":"Расхитительница гробниц / Tomb Raider","value":"988"},{"label":"Резатель / Лангриссер / Langrisser","value":"792"},{"label":"Реинкарнация безработного / Mushoku Tensei","value":"569"},{"label":"Реинкарнация Богини / Megami Tensei","value":"1161"},{"label":"Репликант НиеР / NieR Replicant / NieR Gestalt","value":"1299"},{"label":"Рецеттия: Повесть о магазине предметов / Recettear: An Item Shop's Tale","value":"858"},{"label":"Ривердэйл / Riverdale","value":"637"},{"label":"Рик и Морти / Rick and Morty","value":"315"},{"label":"Розарий и Вампир / Rosario+Vampire","value":"83"},{"label":"Розовая пора моей школьной жизни сплошной обман / Yahari Ore no Seishun Love Come wa Machigatteiru","value":"856"},{"label":"Рок шоу! / Show By Rock!!","value":"344"},{"label":"Русалочка / The Little Mermaid","value":"892"},{"label":"Рыцарь и маг / Knight's & Magic","value":"1491"},{"label":"Сага о Винланде / Vinland Saga","value":"1200"},{"label":"Садистская смесь / Blend S","value":"1120"},{"label":"Сайт волшебниц / Mahou Shoujo Site","value":"909"},{"label":"Сверхъестественное(телесериал) / Supernatural","value":"916"},{"label":"Связь принцесс: повторное погружение / Princess Connect! Re:Dive","value":"1481"},{"label":"Святые / Saints Row","value":"1390"},{"label":"Сейлор Мун / Sailor Moon","value":"114"},{"label":"Секире: Тени Умирают Дважды / Sekiro: Shadows Die Twice","value":"1076"},{"label":"Семь смертных грехов / Nanatsu no Taizai","value":"61"},{"label":"Семья шпиона / Spy x Family","value":"1646"},{"label":"Сердца Пандоры / Pandora Hearts","value":"497"},{"label":"Серия Метроидов / Metroid Series","value":"1612"},{"label":"Серый человек / Ди: Гурэйман / D.Gray-man","value":"367"},{"label":"Си Тянь Гуань / Si Tian Guan","value":"1189"},{"label":"Сильнейший в истории ученик Кэнити / Shijou Saikyou no Deshi Kenichi","value":"242"},{"label":"Сильнейший в истории ученик Кэнъити / KenIchi: The Mightiest Disciple","value":"745"},{"label":"Сильнейший магнат / The Strongest Tycoon","value":"1340"},{"label":"Сильнейший мудрец низшей эмблемы / Shikkakumon no Saikyou Kenja","value":"1472"},{"label":"Симпсоны / The Simpsons","value":"1461"},{"label":"Симс / The Sims","value":"654"},{"label":"Симфония морской стали / Aoki Hagane no Arpeggio","value":"958"},{"label":"Сингулярность(Games) / Singularity","value":"1793"},{"label":"Синий Архив / Blue Archive","value":"1411"},{"label":"Синий экзорцист / Blue Exorcist","value":"312"},{"label":"Синяя Тюрьма: Блю Лок / Blue Lock","value":"1792"},{"label":"Система Богов и Демонов / God and Devil World","value":"1648"},{"label":"Система Спаси-Себя-Сам / The Scum Villain's Self-Saving System: Ren Zha Fanpai Zijiu Xitong","value":"1505"},{"label":"Система: Восьмой уровень(Д. Серебряков) / System: Eighth level","value":"1175"},{"label":"Сисястая Принцесса под гипнозом / Kyonyuu Princess Saimin","value":"1618"},{"label":"Сказание о Демонах и Богах / Tales of Demons and Gods","value":"59"},{"label":"Сказание о Тёмном Рыцаре ~ Призван, чтобы одолеть Героя ~ / Tale of Dark Knight~Summoned to Defeat The Hero~","value":"1647"},{"label":"Сказки хранителей(Games) / Guardian tales","value":"1068"},{"label":"Скрытая Похотливая Натура Моих Русских Сестренок и Мачехи / Muttsuri do Sukebe ro Gibo Shimai","value":"1282"},{"label":"Скуби-Ду / Scooby-Doo","value":"638"},{"label":"Скучный мир, где не существует самой идеи похабных шуток / Shimoneta to Iu Gainen ga Sonzai Shinai Taikutsu na Sekai","value":"830"},{"label":"Сладкая жизнь / Happy Sugar Life","value":"1099"},{"label":"Сладкий флирт / Amour Sucré / Sweet Crush","value":"495"},{"label":"Сладости и Сигареты / Candy & Cigarettes","value":"778"},{"label":"Следопыт Гнев Праведников / Pathfinder Wrath Of The Righteous","value":"1077"},{"label":"Следопыт: Творец королей / Pathfinder: Kingmaker","value":"1770"},{"label":"Смертельная битва / Мортал Комбат / Mortal Kombat","value":"806"},{"label":"Смертельный укус","value":"1902"},{"label":"Созданный в бездне / Made in Abyss","value":"952"},{"label":"Сок джунглей","value":"1901"},{"label":"Сокрушитель: Новые волны / The Breaker: New Waves","value":"1500"},{"label":"Соник еж / Sonic the hedgehog","value":"1052"},{"label":"Сорвиголова / Daredevil","value":"1690"},{"label":"Сотня / Hundred","value":"885"},{"label":"Спаун / Spawn","value":"1254"},{"label":"Спецагент Арчер / Archer","value":"624"},{"label":"Специалист по апгрейду из другого мира / Endless Sea of Clouds ESC","value":"1499"},{"label":"Спираль / Удзумаки / Uzumaki","value":"1164"},{"label":"СТАЛКЕР / STALKER / S.T.A.L.K.E.R","value":"677"},{"label":"Стальная тревога / Full Metal Panic! The Second Raid","value":"1489"},{"label":"Стальной алхимик / Fullmetal Alchemist","value":"1123"},{"label":"Стальной Гигант / The Iron Giant","value":"1241"},{"label":"Становление богом / Bai Lian Cheng Shen","value":"1315"},{"label":"Старгерл / Stargirl","value":"1137"},{"label":"Стелларис / Stellaris","value":"1098"},{"label":"Сторожевые Псы / Watch Dogs","value":"1886"},{"label":"Стражи Галактики / Guardians of the Galaxy","value":"1426"},{"label":"Страна Самоцветов / Houseki no Kuni","value":"1305"},{"label":"Страна чудес смертников / Зона-парк смертников / Deadman Wonderland","value":"857"},{"label":"Страношары / Кантриболз / Countryballs","value":"1895"},{"label":"Студии 20-й век / 20th Century Studios","value":"1715"},{"label":"Судьба / Fate","value":"1740"},{"label":"Судьба: Апокриф / Fate: Apocrypha","value":"231"},{"label":"Судьба: Великий Орден / Fate: Grand Order","value":"60"},{"label":"Судьба: Девочка волшебница Илия / Fate: Kaleid Liner Prisma","value":"789"},{"label":"Судьба: Истоки / Fate: Zero","value":"230"},{"label":"Судьба: Ночь схватки / Fate: Stay Night","value":"536"},{"label":"Сумерки / Twilight","value":"471"},{"label":"Супер ген бога / Super God Gene","value":"316"},{"label":"Супер Марио / Super Mario","value":"1661"},{"label":"Супергёрл(телесериал, 2015) / Supergirl","value":"1088"},{"label":"Супермедицинский ниндзя / Super medical ninja","value":"1391"},{"label":"Суперсемейка / The Incredibles","value":"306"},{"label":"Сэкирэй / Sekirei","value":"111"},{"label":"Тада не может влюбиться! / Tada-kun wa koi wo shinai!","value":"1905"},{"label":"Тайны Смолвиля / Smallville","value":"449"},{"label":"Танец клинка Элементалиста / Seireitsukai no Blade Dance","value":"1498"},{"label":"Твоя апрельская ложь / Your lie in april","value":"532"},{"label":"Те, кто охотятся на эльфов / エルフを狩るモノたち / Those Who Hunt Elves","value":"1168"},{"label":"Темнейшее подземелье / Darkest dungeon","value":"1405"},{"label":"Темные Души / Dark Souls","value":"200"},{"label":"Темный Ангел / Dark Angel","value":"1010"},{"label":"Тёмный Дворецкий / Kuroshitsuj / Dark Butler","value":"411"},{"label":"Темный дворецкий / Kuroshitsuji","value":"1043"},{"label":"Темный призыватель Апокалипсиса / The Dark Summoner of the Apocalypse","value":"1407"},{"label":"Тень ежа / Ёж Шэдоу / Shadow the hedgehog","value":"796"},{"label":"Терминатор / The Terminator","value":"759"},{"label":"Террарий / Terraria","value":"805"},{"label":"Тетрадь смерти / Death Note","value":"78"},{"label":"Тибериумные войны / Tiberium Wars","value":"1893"},{"label":"Титаник / Titanic","value":"1842"},{"label":"Тихий Холм / Сайлент Хилл / Silent Hill","value":"848"},{"label":"Тихоокеанский рубеж / Pacific Rim","value":"832"},{"label":"Тогайну но Чи ~Потерял кровь~(Games) / Togainu no Chi ~Lost Blood~","value":"1540"},{"label":"Токийские вороны / Tokyo Ravens","value":"836"},{"label":"Токийские мстители / Tokyo Revengers","value":"1064"},{"label":"Токийский Гуль / Tokyo Ghoul","value":"271"},{"label":"Тор / Thor","value":"764"},{"label":"Торико / Toriko","value":"342"},{"label":"Точка зрения Всеведущего читателя / Omniscient Reader’s Viewpoint","value":"1872"},{"label":"Трансформеры / Transformers","value":"117"},{"label":"Трес Наварра / Tres Navarre","value":"1197"},{"label":"Три Икса / xXx","value":"364"},{"label":"Трон: Восстание / Tron: Uprising","value":"1887"},{"label":"Тропико / Tropico","value":"694"},{"label":"Ты единственная, кто любит Великого Меня / Ore wo Suki nano wa Omae dake ka yo","value":"1818"},{"label":"Ты же любишь мамочку, удары которой бьют по площади двойным уроном? / Tsuujou Kougeki ga Zentai Kougeki de Ni-kai Kougeki no Okaasan wa Suki Desu ka?","value":"333"},{"label":"Тэнти - лишний! / Tenchi Muyo","value":"1316"},{"label":"У Коми-сан проблемы с общением / 古見さんは、コミュ症です / Komi Can't Communicate","value":"591"},{"label":"У меня мало друзей / Boku wa Tomodachi ga Sukunai","value":"1506"},{"label":"Убийца Акаме / Akame ga Kill","value":"30"},{"label":"Убийца Брайан / Carl Robert Brown","value":"1092"},{"label":"Убийца гоблинов / Goblin slayer","value":"803"},{"label":"Удар крови / Very AU strike the blood","value":"1255"},{"label":"Уж не зомби ли это? / Kore wa Zombie Desu ka?","value":"725"},{"label":"Уличный боец(Games) / Суторито Фаита / Street Fighter","value":"1203"},{"label":"Ультрафиолет / Ultraviolet","value":"1831"},{"label":"Усио и Тора / Ushio and Tora","value":"1501"},{"label":"Утраченное небесами / Sora no Otoshimoto / Lost Property of the Sky","value":"627"},{"label":"Ученик Мудреца / Kenja no Deshi wo Nanoru Kenja","value":"1474"},{"label":"Ученик чародея / The Sorcerer's Apprentice","value":"862"},{"label":"Ученики(Games) / Disciples","value":"1478"},{"label":"Учитель Хокаге / Hokage Master","value":"1319"},{"label":"Учитель-мафиози Реборн! / Katekyo Hitman Reborn!","value":"134"},{"label":"Ушастые Друзья / Kemono Friends","value":"578"},{"label":"Фальшивая любовь / Nisekoi","value":"1103"},{"label":"Фантастическая четвёрка / Fantastic Four","value":"625"},{"label":"Фантастические твари и где они обитают / Fantastic Beasts and Where to Find Them","value":"246"},{"label":"Финес и Ферб / Phineas and Ferb","value":"898"},{"label":"Флотская коллекция / Kantai Collection","value":"1194"},{"label":"Флэш / The Flash","value":"1136"},{"label":"Фонд SCP / SCP / SCP Foundation","value":"822"},{"label":"Форма голоса / A Silent Voice","value":"1100"},{"label":"Форсаж / The Fast and the Furious","value":"363"},{"label":"Фронт кровавой блокады / Кровавый круг - линия фронта / Kekkai Sensen / Blood Blockade Battlefront","value":"794"},{"label":"Футадом мир / Futadom world","value":"984"},{"label":"Халк / Hulk","value":"973"},{"label":"Хвост Феи / Fairy Tail","value":"13"},{"label":"Хеллбой / Hellboy","value":"1171"},{"label":"Хеллсинг: Война с нечистью / Hellsing","value":"116"},{"label":"Хикару и го / Hikaru no Go","value":"1121"},{"label":"Хищник / Predator","value":"747"},{"label":"Хоббит(Дж. Р. Р. Толкина) / The Hobbit(John R.R. Tolkien)","value":"1127"},{"label":"Ходячие мертвецы / The Walking Dead","value":"704"},{"label":"Холодное сердце / Frozen","value":"633"},{"label":"Хонкай удар / Honkai impact","value":"1332"},{"label":"Хранители Пандоры / The guardians of Pandora","value":"1187"},{"label":"Хранитель вечности / UQ Holder","value":"1469"},{"label":"Хроники Акаши / Rokudenashi Majutsu Koushi to Akashic Records","value":"1166"},{"label":"Хроники Ксенобладания / Дзэнобурэйдо / Xenoblade Chronicles","value":"1110"},{"label":"Хроники Миров(Е. Лукин) / Chronicles of the Worlds(E. Lukin)","value":"346"},{"label":"Хроники расхитителей гробниц / Даому Биджи / Grave Robbery Note / Dao Mu Bi Ji / Daomu Biji","value":"724"},{"label":"Хроники Ренегата / The Renegade Chronicles","value":"1225"},{"label":"Царь Горы / The Gog of the Highschool","value":"1285"},{"label":"Чародейки / W.I.T.C.H.","value":"118"},{"label":"Человек — бензопила / Chainsaw Man","value":"797"},{"label":"Человек — летучая мышь / Бэтмен / Bat-man / Batman","value":"440"},{"label":"Человек одного удара / Ванпанчмен / One Punch-Man","value":"70"},{"label":"Человек-паук / Spider-Man","value":"326"},{"label":"Чемпион! / Campione!","value":"534"},{"label":"Червь(Джон Маккрей) / Worm(John C. McCrae(Wildbow))","value":"700"},{"label":"Черная Пантера(Фильм, 2018) / Black Panther","value":"1605"},{"label":"Черновик(С.Лукьяненко) / Draft","value":"1023"},{"label":"Чернокнижник в Мире Магов / Варлок / Warlock","value":"635"},{"label":"Чёрные души / Black Souls","value":"1439"},{"label":"Чёрный зверь / Чёрный Пёс / Kuroinu","value":"755"},{"label":"Чёрный зверь: Развращение Благородных Воительниц / Black Beast: Corruption of the Noble Warriors","value":"1733"},{"label":"Чёрный клевер / Black Clover","value":"11"},{"label":"Что такое настоящий мир? / What is real peace?","value":"1336"},{"label":"Чудачества любви не помеха! / Chuunibyou Demo Koi ga Shitai!","value":"1719"},{"label":"Чужой / Чужие / Aliens","value":"1791"},{"label":"Чужой / Alien","value":"748"},{"label":"Чума инкорпорейтед / Plague Inc","value":"125"},{"label":"Шазам! / Shazam!","value":"1560"},{"label":"Шальной последний босс появился! / A Wild Last Boss Appeared!","value":"968"},{"label":"Шальные девчонки / Girl the Wild's","value":"965"},{"label":"Шан Чи и легенда десяти колец / Shang-Chi and the Legend of the Ten Rings","value":"1424"},{"label":"Шарлотта / Charlotte","value":"71"},{"label":"Шерлок (ВВС) / Sherlock","value":"492"},{"label":"Шестерни войны / Gears of War","value":"1346"},{"label":"Школа мертвецов / Highschool of the Dead","value":"98"},{"label":"Школа строгого режима / Prison School","value":"676"},{"label":"Школьные воины / Сила тысячи / Ikki Tosen","value":"818"},{"label":"Шрек(мультфильм) / Шрэк / Shrek","value":"1586"},{"label":"Шухер, у нас новый студент / Transfer Student The Storm Bringer","value":"628"},{"label":"Эволюционировать(Games) / Evolve","value":"1789"},{"label":"Эволюция. Естественный Отбор / Game Evolution","value":"287"},{"label":"Эльсворд: Эль-ий Йоин / Elsword","value":"199"},{"label":"Эльфийская песнь / Elfen Lied","value":"1899"},{"label":"Эпоха Драконов / Dragon Age","value":"253"},{"label":"Эр Ген Я запечатаю небеса / ISSTH / Er Gen I shall seal the heavens","value":"1170"},{"label":"Эрагон(Кристофер Паолини) / Eragon","value":"417"},{"label":"Эроманга-сэнсэй / Ero-manga Sensei","value":"1094"},{"label":"Эстетика заблудшего героя / Hagure Yuusha no Aesthetica","value":"1310"},{"label":"Эта гяру будет встречаться с отаку через 100 дней. / 100-nichigo ni Otaku-kun to Tsukiau Gal","value":"1246"},{"label":"Эта фарфоровая кукла влюбилась / Sono Bisque Doll wa Koi wo Suru My Dress-Up Darling","value":"1335"},{"label":"Это не Гарри Поттер / This is not Harry Potter","value":"1219"},{"label":"Этот герой неуязвим, но очень осторожен / This Hero Is Invincible but Too Cautious","value":"1276"},{"label":"Эффект массы / Mass Effect","value":"213"},{"label":"Эхо пули / Bullet Echo","value":"1523"},{"label":"Югио: Дуэльные монстры / Yu-Gi-Oh","value":"1814"},{"label":"Югио! Вреинс / Yu-Gi-Oh! VRAINS","value":"1888"},{"label":"Юна из гостиницы Юраги / Yuuna of Yuragi Manor","value":"493"},{"label":"Юная Лига Справедливости / Young Justice","value":"1020"},{"label":"Юные Титаны / Teen Titans","value":"420"},{"label":"Я - Четвертый / I Am Number Four","value":"590"},{"label":"Я Король-Волшебник / I Am The Sorcerer King","value":"1292"},{"label":"Я мачеха, но моя дочь слишком милая / I'm stepmother but daughter is too cute","value":"777"},{"label":"Я не родился счастливчиком / I Wasn’t Born Lucky","value":"996"},{"label":"Я получил читерские способности в другом мире и стал экстраординарным в реальном мире / I Got a Cheat Skill in Another World and Became Unrivaled in The Real World, Too","value":"1900"},{"label":"Я стала потерянной дочерью злодея / I Became the Villain’s Lost Daughter","value":"1387"},{"label":"Ядерный трон / Nuclear Throne","value":"1456"},{"label":"Ярость [Пересмотрено] / Rage [Revised]","value":"1337"},{"label":"Ящик предложений Мэдаки / Medaka box","value":"874"},{"label":"Cказка для Дьявола / Tale For Satan","value":"1271"},{"label":"D&D стиль / D&D style","value":"1289"},{"label":"Dying Light 2: Stay Human","value":"1906"},{"label":"Fallout: Нью-Вегас / Fallout: New Vegas","value":"1249"},{"label":"Re: Жизнь в альтернативном мире с нуля / Re: Zero, Starting Life in Another World","value":"57"},{"label":"Re:Zero Начало жизни в другом мире / Re:Zero Starting Life in Another World","value":"1531"},{"label":"Rimworld","value":"1894"},{"label":"The Second Coming of Gluttony / The Second Coming of Avarice","value":"1236"},{"label":"Vfhdbk","value":"1884"},{"label":"XCOM: Враг внутри / XCOM: Enemy Unknown","value":"476"},{"label":"Xenus: Точка кипения / Boiling point: Road To Hell / Xenus: Boiling Point","value":"695"}],"inputType":FilterInputs.Checkbox},{"key":"atmosphere","label":"Атмосфера:","values":[{"label":"Неважно","value":"0"},{"label":"Позитивная","value":"1"},{"label":"Dark","value":"2"}],"inputType":FilterInputs.Picker},{"key":"adult","label":"Возрастные ограничения:","values":[{"label":"Все","value":"0"},{"label":"Только 18+","value":"2"},{"label":"Убрать 18+","value":"1"}],"inputType":FilterInputs.Picker}]; \ No newline at end of file diff --git a/plugins/russian/authortoday.ts b/plugins/russian/authortoday.broken.ts similarity index 100% rename from plugins/russian/authortoday.ts rename to plugins/russian/authortoday.broken.ts diff --git a/plugins/russian/bookriver.ts b/plugins/russian/bookriver.broken.ts similarity index 100% rename from plugins/russian/bookriver.ts rename to plugins/russian/bookriver.broken.ts diff --git a/plugins/russian/ficbook.ts b/plugins/russian/ficbook.broken.ts similarity index 100% rename from plugins/russian/ficbook.ts rename to plugins/russian/ficbook.broken.ts diff --git a/plugins/russian/jaomix.ts b/plugins/russian/jaomix.broken.ts similarity index 100% rename from plugins/russian/jaomix.ts rename to plugins/russian/jaomix.broken.ts diff --git a/plugins/russian/novelTL.ts b/plugins/russian/novelTL.broken.ts similarity index 100% rename from plugins/russian/novelTL.ts rename to plugins/russian/novelTL.broken.ts diff --git a/plugins/russian/ranobehub.ts b/plugins/russian/ranobehub.broken.ts similarity index 100% rename from plugins/russian/ranobehub.ts rename to plugins/russian/ranobehub.broken.ts diff --git a/plugins/russian/ranobelib.ts b/plugins/russian/ranobelib.broken.ts similarity index 100% rename from plugins/russian/ranobelib.ts rename to plugins/russian/ranobelib.broken.ts diff --git a/plugins/russian/ranoberf.ts b/plugins/russian/ranoberf.broken.ts similarity index 100% rename from plugins/russian/ranoberf.ts rename to plugins/russian/ranoberf.broken.ts diff --git a/plugins/russian/renovels.ts b/plugins/russian/renovels.broken.ts similarity index 100% rename from plugins/russian/renovels.ts rename to plugins/russian/renovels.broken.ts diff --git a/plugins/spanish/.spanish b/plugins/spanish/.spanish deleted file mode 100644 index e69de29..0000000 diff --git a/plugins/spanish/hasutl.ts b/plugins/spanish/hasutl.broken.ts similarity index 100% rename from plugins/spanish/hasutl.ts rename to plugins/spanish/hasutl.broken.ts diff --git a/plugins/spanish/novelasligera.ts b/plugins/spanish/novelasligera.broken.ts similarity index 100% rename from plugins/spanish/novelasligera.ts rename to plugins/spanish/novelasligera.broken.ts diff --git a/plugins/spanish/skynovels.ts b/plugins/spanish/skynovels.broken.ts similarity index 100% rename from plugins/spanish/skynovels.ts rename to plugins/spanish/skynovels.broken.ts diff --git a/plugins/spanish/tunovelaligera.ts b/plugins/spanish/tunovelaligera.ts index 6134a7e..4b80f3a 100644 --- a/plugins/spanish/tunovelaligera.ts +++ b/plugins/spanish/tunovelaligera.ts @@ -1,56 +1,72 @@ +import { CheerioAPI, load as parseHTML } from "cheerio"; import { fetchApi, fetchFile } from "@libs/fetch"; -import { load as parseHTML } from "cheerio"; -import { NovelStatus } from "@libs/novelStatus"; +import { Filter, FilterInputs } from "@libs/filterInputs"; +import { Plugin } from "@typings/plugin"; +import { showToast } from "@libs/showToast"; import { defaultCover } from "@libs/defaultCover"; -import { Chapter, Novel, Plugin } from "@typings/plugin"; +import { NovelStatus } from "@libs/novelStatus"; -export const id = "TNL.com"; -export const name = "TuNovelaLigera"; -export const site = "https://tunovelaligera.com/"; -export const version = "1.0.0"; -export const icon = "src/es/tunovelaligera/icon.png"; +class TuNovelaLigera implements Plugin.PluginBase { + id = "tunovelaligera"; + name = "TuNovelaLigera"; + icon = "src/es/tunovelaligera/icon.png"; + site = "https://tunovelaligera.com/"; + version = "1.0.0"; + userAgent = ""; + cookieString = ""; -const baseUrl = site; + async popularNovels(pageNo: number, {filters}: Plugin.PopularNovelsOptions): Promise { + let link = `${this.site}`; -export const popularNovels: Plugin.popularNovels = async function (page) { - let url = baseUrl + "novelas/page/" + page + "/?m_orderby=rating"; + link += (filters?.genres ? `genero/` + filters.genres : "novelas"); - const result = await fetchApi(url); - const body = await result.text(); + link += `/page/${pageNo}`; - let loadedCheerio = parseHTML(body); + link += (filters?.order ? filters.order : "?m_orderby=rating") - let novels: Novel.Item[] = []; + const headers = new Headers(); + if(this.cookieString){ + headers.append("cookie", this.cookieString); + } + const result = await fetchApi(link, {headers}) + const body = await result.text(); - loadedCheerio(".page-item-detail").each(function () { - const novelName = loadedCheerio(this).find(".h5 > a").text(); - const novelCover = loadedCheerio(this).find("img").attr("src"); + const loadedCheerio = parseHTML(body); - let novelUrl = loadedCheerio(this).find(".h5 > a").attr("href"); - if (!novelUrl) return; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; + const novels: Plugin.NovelItem[] = []; - novels.push(novel); - }); + loadedCheerio(".page-item-detail").each((i,el) => { + const novelName = loadedCheerio(el).find(".h5 > a").text(); + const novelCover = loadedCheerio(el).find("img").attr("src"); + const novelUrl = loadedCheerio(el).find(".h5 > a").attr("href"); - return novels; -}; + if (!novelUrl) return; + const novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; -export const parseNovelAndChapters: Plugin.parseNovelAndChapters = - async function (novelUrl) { + novels.push(novel); + }); + + return novels; + }; + + async parseNovelAndChapters(novelUrl: string): Promise { const url = novelUrl; - - const result = await fetchApi(url); + const headers = new Headers(); + if(this.cookieString){ + headers.append("cookie", this.cookieString); + } + const result = await fetchApi(url, {headers}); const body = await result.text(); let loadedCheerio = parseHTML(body); - let novel: Novel.instance = { + const novel: Plugin.SourceNovel = { url, + chapters: [], }; loadedCheerio(".manga-title-badges").remove(); @@ -62,6 +78,7 @@ export const parseNovelAndChapters: Plugin.parseNovelAndChapters = novel.cover = novelCover.attr("data-src") || novelCover.attr("src") || + novelCover.attr('data-cfsrc') || defaultCover; loadedCheerio(".post-content_item").each(function () { @@ -93,69 +110,264 @@ export const parseNovelAndChapters: Plugin.parseNovelAndChapters = novel.summary = loadedCheerio("div.summary__content > p").text().trim(); - let novelChapters: Chapter.Item[] = []; + let chapter: Plugin.ChapterItem[] = []; - loadedCheerio(".lcp_catlist li").each(function () { - const chapterName = loadedCheerio(this) - .find("a") - .text() - .replace(/[\t\n]/g, "") - .trim(); + const delay = (ms: number) => new Promise((res) => setTimeout(res, ms)); + let lastPage = 1; + lastPage = +loadedCheerio('.lcp_paginator li:last').prev().text(); - const releaseDate = loadedCheerio(this).find("span").text().trim(); + const getChapters = async () => { + const n = url.split('/'); + const novelName = n[4]; + showToast('Cargando desde Archivo...'); - let chapterUrl = loadedCheerio(this).find("a").attr("href"); - if (!chapterUrl) return; - novelChapters.push({ - name: chapterName, - releaseTime: releaseDate, - url: chapterUrl, + const formData = new FormData() + formData.append("action", "madara_load_more"); + formData.append("page", "0"); + formData.append("template", "html/loop/content"); + formData.append("vars[category_name]", novelName); + formData.append("vars[posts_per_page]", "10000"); + + const result = await fetchApi( + `${this.site}wp-admin/admin-ajax.php`, + { + method: "POST", + body: formData, + headers + }, + ); + const text = await result.text(); + + loadedCheerio = parseHTML(text); + + loadedCheerio('.heading').each((i, el) => { + const chapterName = loadedCheerio(el) + .text() + .replace(/[\t\n]/g, '') + .trim(); + const releaseDate = null; + const chapterUrl = loadedCheerio(el).find('a').attr('href') || ""; + + chapter.push({ + name: chapterName, + url: chapterUrl, + releaseTime: releaseDate, + }); }); - }); + return chapter.reverse(); + }; + + const getPageChapters = async () => { + for (let i = 1; i <= lastPage; i++) { + const chaptersUrl = `${novelUrl}?lcp_page0=${i}`; + showToast(`Cargando desde la página ${i}/${lastPage}...`); + const result = await fetchApi(chaptersUrl, {headers}); + const chaptersHTML = await result.text(); - novel.chapters = novelChapters.reverse(); + let chapterCheerio = parseHTML(chaptersHTML); + chapterCheerio('.lcp_catlist li').each((i, el) => { + const chapterName = chapterCheerio(el) + .find('a') + .text() + .replace(/[\t\n]/g, '') + .trim(); + + const releaseDate = chapterCheerio(el) + .find('span') + .text() + .trim(); + + const chapterUrl = + chapterCheerio(el).find('a').attr('href') || ""; + + chapter.push({ + name: chapterName, + releaseTime: releaseDate, + url: chapterUrl, + }); + }); + await delay(1000); + } + return chapter.reverse(); + } + + novel.chapters = await getChapters(); + + if (!novel.chapters.length) { + showToast('¡Archivo no encontrado!'); + await delay(1000); + novel.chapters = await getPageChapters(); + } + return novel; + } + + async parseChapter(chapterUrl: string): Promise { + const headers = new Headers(); + if(this.cookieString){ + headers.append("cookie", this.cookieString); + } + const result = await fetchApi(chapterUrl); + const body = await result.text(); + + const loadedCheerio = parseHTML(body); + + loadedCheerio("#hola_siguiente").next().find('div').remove(); + const chapterText = loadedCheerio("#hola_siguiente").next().html() || ""; + + return chapterText; }; -export const parseChapter: Plugin.parseChapter = async function (chapterUrl) { - const url = chapterUrl; + async searchNovels(searchTerm: string, pageNo?: number | undefined): Promise { + const url = `${this.site}?s=${searchTerm}&post_type=wp-manga`; - const result = await fetchApi(url); - const body = await result.text(); + const result = await fetchApi(url); + const body = await result.text(); - let loadedCheerio = parseHTML(body); + const loadedCheerio = parseHTML(body); - let chapterText = loadedCheerio("#hola_siguiente").next().text(); + const novels: Plugin.NovelItem[] = []; - return chapterText; -}; + loadedCheerio(".c-tabs-item__content").each((i, el) => { + const novelName = loadedCheerio(el).find(".h4 > a").text(); + const novelCover = loadedCheerio(el).find("img").attr("src"); + const novelUrl = loadedCheerio(el).find(".h4 > a").attr("href"); + if (!novelUrl) return; + novels.push({ + name: novelName, + url: novelUrl, + cover: novelCover, + }); + }); -export const searchNovels: Plugin.searchNovels = async function (searchTerm) { - const url = `${baseUrl}?s=${searchTerm}&post_type=wp-manga`; + return novels; + }; - const result = await fetchApi(url); - const body = await result.text(); + async fetchImage(url: string): Promise { + return await fetchFile(url); + } - let loadedCheerio = parseHTML(body); + filters = [ + { + key: "order", + label: "Ordenado por", + values: [ + { label: "Lo mas reciente", value: "?m_orderby=latest" }, - let novels: Novel.Item[] = []; + { label: "A-Z", value: "?m_orderby=alphabet" }, + + { label: "Clasificación", value: "?m_orderby=rating" }, + + { label: "Trending", value: "?m_orderby=trending" }, + + { label: "Mas visto", value: "?m_orderby=views" }, + + { label: "Nuevo", value: "?m_orderby=new-manga" }, + ], + inputType: FilterInputs.Picker, + }, + { + key: "genres", + label: "Generos", + values: [ + { label: "Acción", value: "accion" }, - loadedCheerio(".c-tabs-item__content").each(function () { - const novelName = loadedCheerio(this).find(".h4 > a").text(); - const novelCover = loadedCheerio(this).find("img").attr("src"); + { label: "Adulto", value: "adulto" }, + + { label: "Artes Marciales", value: "artes-marciales" }, + + { label: "Aventura", value: "aventura" }, + + { label: "Ciencia Ficción", value: "ciencia-ficcion" }, + + { label: "Comedia", value: "comedia" }, + + { label: "Deportes", value: "deportes" }, + + { label: "Drama", value: "drama" }, + + { label: "Eastern Fantasy", value: "eastern-fantasy" }, + + { label: "Ecchi", value: "ecchi" }, + + { label: "FanFiction", value: "fan-fiction" }, + + { label: "Fantasía", value: "fantasia" }, + + { label: "Fantasía oriental", value: "fantasia-oriental" }, + + { label: "Ficción Romántica", value: "ficcion-romantica" }, + + { label: "Gender Bender", value: "gender-bender" }, + + { label: "Harem", value: "harem" }, + + { label: "Histórico", value: "historico" }, + + { label: "Horror", value: "horror" }, + + { label: "Josei", value: "josei" }, + + { label: "Maduro", value: "maduro" }, + + { label: "Mecha", value: "mecha" }, + + { label: "Misterio", value: "misterio" }, + + { label: "Novela China", value: "novela-china" }, + + { label: "Novela FanFiction", value: "novela-fanfiction" }, + + { label: "Novela Japonesa", value: "novela-japonesa" }, + + { label: "Novela Koreana", value: "novela-koreana" }, + + { label: "Novela ligera", value: "novela-ligera" }, + + { label: "Novela original", value: "novela-original" }, + + { label: "Novela Web", value: "web-novel" }, + + { label: "Psicológico", value: "psicologico" }, + + { label: "Realismo Mágico", value: "realismo-magico" }, + + { label: "Recuento de vida", value: "recuento-de-vida" }, + + { label: "Romance", value: "romance" }, + + { label: "Romance contemporáneo", value: "romance-contemporaneo" }, + + { label: "Romance Moderno", value: "romance-moderno" }, + + { label: "Seinen", value: "seinen" }, + + { label: "Shoujo", value: "shoujo" }, + + { label: "Shounen", value: "shounen" }, + + { label: "Sobrenatural", value: "sobrenatural" }, + + { label: "Tragedia", value: "tragedia" }, + + { label: "Vampiros", value: "vampiros" }, + + { label: "Vida Escolar", value: "vida-escolar" }, + + { label: "Western Fantasy", value: "western-fantasy" }, + + { label: "Wuxia", value: "wuxia" }, + + { label: "Xianxia", value: "xianxia" }, + + { label: "Xuanhuan", value: "xuanhuan" }, + + { label: "Yaoi", value: "yaoi" }, + ], + inputType: FilterInputs.Picker, + }, + ]; +} - let novelUrl = loadedCheerio(this).find(".h4 > a").attr("href"); - if (!novelUrl) return; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - - novels.push(novel); - }); - - return novels; -}; -export const fetchImage: Plugin.fetchImage = fetchFile; +export default new TuNovelaLigera(); diff --git a/plugins/spanish/yukitls.ts b/plugins/spanish/yukitls.broken.ts similarity index 100% rename from plugins/spanish/yukitls.ts rename to plugins/spanish/yukitls.broken.ts diff --git a/plugins/turkish/.turkish b/plugins/turkish/.turkish deleted file mode 100644 index e69de29..0000000 diff --git a/plugins/turkish/TurkceLightNovels[madara].ts b/plugins/turkish/TurkceLightNovels[madara].ts index 6fea7a9..dd0b746 100644 --- a/plugins/turkish/TurkceLightNovels[madara].ts +++ b/plugins/turkish/TurkceLightNovels[madara].ts @@ -1,213 +1,252 @@ +import { fetchApi, fetchFile } from "@libs/fetch"; +import { Filter } from "@libs/filterInputs"; +import { Plugin } from '@typings/plugin' import { load as parseHTML } from "cheerio"; -import { fetchFile, fetchApi } from "@libs/fetch"; -import { Novel, Plugin, Chapter } from "@typings/plugin"; -import { FilterInputs } from "@libs/filterInputs"; import { defaultCover } from "@libs/defaultCover"; -import { NovelStatus } from "@libs/novelStatus" +import { NovelStatus } from "@libs/novelStatus"; import { parseMadaraDate } from "@libs/parseMadaraDate"; import dayjs from "dayjs"; -export const id = "turkcelightnovels"; -export const name = "TurkceLightNovels [madara]"; -export const icon = "multisrc/madara/icons/turkcelightnovels.png"; -export const version = "1.0.0"; -export const site = "https://turkcelightnovels.com/"; -const baseUrl = site; +interface MadaraOptionPath{ + genres?: string, + novels?: string, + novel?: string, + chapter?: string, +} -export const popularNovels: Plugin.popularNovels = async (pageNo, {filters, showLatestNovels}) => { - const novels: Novel.Item[] = []; +const MadaraDefaultPath: MadaraOptionPath = { + novels: 'novel', + novel: 'novel', + chapter: 'novel' +} - let url = site; +interface MadaraOptions { + useNewChapterEndpoint?: boolean, + path?: MadaraOptionPath, + lang?: string, + orderBy?: string +} - if (filters?.genres) { - url += "novel-genre/" + filters.genres + '/'; - } else { - url += "light-novel/"; +export interface MadaraMetadata { + id: string, + sourceSite: string, + sourceName: string, + options?: MadaraOptions, + filters?: Filter[], +} +class MadaraPlugin implements Plugin.PluginBase { + id: string; + name: string; + icon: string; + site: string; + version: string; + userAgent: string; + cookieString: string; + options?: MadaraOptions; + filter?: Filter[] | undefined; + + constructor(metadata: MadaraMetadata){ + this.id = metadata.id; + this.name = metadata.sourceName + "[madara]"; + const iconFileName = metadata.sourceName.replace(/\s+/g, "").toLowerCase(); + this.icon = `multisrc/madara/icons/${iconFileName}.png`; + this.site = metadata.sourceSite; + this.version = "1.0.0"; + this.userAgent = ""; + this.cookieString = ""; + this.options = metadata.options; + this.filter = metadata.filters; } + async popularNovels(pageNo: number, {filters, showLatestNovels}: Plugin.PopularNovelsOptions): Promise { + const novels: Plugin.NovelItem[] = []; - url += '/page/' + pageNo + '/' + - '?m_orderby=' + (showLatestNovels ? 'latest' : (filters?.sort || 'rating')); - - const body = await fetchApi(url).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - - loadedCheerio('.manga-title-badges').remove(); - - loadedCheerio('.page-item-detail').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - - let novelUrl = loadedCheerio(this).find('.post-title') - .find('a') - .attr('href') || ''; - const novel: Novel.Item = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - - novels.push(novel); - }); - - return novels; -}; - -export const parseNovelAndChapters: Plugin.parseNovelAndChapters = async ( - novelUrl -) => { - const novel: Novel.instance = { - url: novelUrl, - }; - - const body = await fetchApi(novelUrl).then(res => res.text()); - - let loadedCheerio = parseHTML(body); - - loadedCheerio('.manga-title-badges').remove(); - - novel.name = loadedCheerio('.post-title h1').text().trim(); - - novel.cover = - loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || - loadedCheerio('.summary_image > a > img').attr('data-src') || - loadedCheerio('.summary_image > a > img').attr('src') || - defaultCover; - - loadedCheerio('.post-content_item, .post-content').each(function () { - const detailName = loadedCheerio(this).find('h5').text().trim(); - const detail = loadedCheerio(this).find('.summary-content').text().trim(); - - switch (detailName) { - case 'Genre(s)': - case 'التصنيفات': - novel.genres = detail.replace(/[\t\n]/g, ','); - break; - case 'Author(s)': - case 'المؤلف': - case 'المؤلف (ين)': - novel.author = detail; - break; - case 'Status': - case 'الحالة': - novel.status = - detail.includes('OnGoing') || detail.includes('مستمرة') - ? NovelStatus.Ongoing - : NovelStatus.Completed; - break; - } - }); - - loadedCheerio('div.summary__content .code-block,script').remove(); - novel.summary = loadedCheerio('div.summary__content').text().trim(); - - - let html; - - if (false) { - const novelId = - loadedCheerio('.rating-post-id').attr('value') || - loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; - - const body = { - action: "manga_get_chapters", - manga: novelId, - } - html = await fetchApi( - baseUrl + 'wp-admin/admin-ajax.php', - { - method: 'POST', - body: JSON.stringify(body), - }) - .then(res => res.text()); - } else { - html = await fetchApi( - baseUrl + 'ajax/chapters/', - { method: 'POST' }) - .then(res => res.text()); - } - - if (html !== '0') { - loadedCheerio = parseHTML(html); - } - - const chapters: Chapter.Item[] = []; - loadedCheerio('.wp-manga-chapter').each(function () { - const chapterName = loadedCheerio(this).find('a').text().trim(); - - let releaseDate = null; - releaseDate = loadedCheerio(this) - .find('span.chapter-release-date') - .text() - .trim(); - - if (releaseDate) { - releaseDate = parseMadaraDate(releaseDate); + let url = this.site; + if (filters?.genres && this.options?.path?.genres) { + url += this.options?.path?.genres + filters.genres + '/'; } else { - /** - * Insert current date - */ - - releaseDate = dayjs().format('LL'); + url += this.options?.path?.novels ? this.options.path.novels : MadaraDefaultPath.novels; } + + url += '/page/' + pageNo + '/' + + '?m_orderby=' + (showLatestNovels ? 'latest' : (filters?.sort || 'rating')); + + const body = await fetchApi(url).then(res => res.text()); + + const loadedCheerio = parseHTML(body); + + loadedCheerio('.manga-title-badges').remove(); + + loadedCheerio('.page-item-detail').each(function () { + const novelName = loadedCheerio(this).find('.post-title').text().trim(); + let image = loadedCheerio(this).find('img'); + const novelCover = image.attr('data-src') || image.attr('src'); + + let novelUrl = loadedCheerio(this).find('.post-title') + .find('a') + .attr('href') || ''; + const novel: Plugin.NovelItem = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + + novels.push(novel); + }); + + return novels; + } + async parseNovelAndChapters(novelUrl: string): Promise { + const novel: Plugin.SourceNovel = { + url: novelUrl, + }; + + const body = await fetchApi(novelUrl).then(res => res.text()); + + let loadedCheerio = parseHTML(body); + + loadedCheerio('.manga-title-badges, #manga-title span').remove(); + novel.name = + loadedCheerio('.post-title h1').text().trim() || + loadedCheerio('#manga-title h1').text(); + + novel.cover = + loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || + loadedCheerio('.summary_image > a > img').attr('data-src') || + loadedCheerio('.summary_image > a > img').attr('src') || + defaultCover; + + loadedCheerio('.post-content_item, .post-content').each(function () { + const detailName = loadedCheerio(this).find('h5').text().trim(); + const detail = loadedCheerio(this).find('.summary-content').text().trim(); + + switch (detailName) { + case 'Genre(s)': + case 'التصنيفات': + novel.genres = detail.replace(/[\\t\\n]/g, ','); + break; + case 'Author(s)': + case 'المؤلف': + case 'المؤلف (ين)': + novel.author = detail; + break; + case 'Status': + case 'الحالة': + novel.status = + detail.includes('OnGoing') || detail.includes('مستمرة') + ? NovelStatus.Ongoing + : NovelStatus.Completed; + break; + } + }); + + loadedCheerio('div.summary__content .code-block,script').remove(); + novel.summary = + loadedCheerio('div.summary__content').text().trim() || + loadedCheerio('#tab-manga-about').text().trim() || + loadedCheerio('.post-content_item h5:contains("Summary")').next().text().trim(); + + let html; + + if (this.options?.useNewChapterEndpoint !== true) { + const novelId = + loadedCheerio('.rating-post-id').attr('value') || + loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; + + const formData = new FormData() + formData.append("action", "manga_get_chapters"); + formData.append("manga", novelId); - let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + html = await fetchApi( + this.site + 'wp-admin/admin-ajax.php', + { + method: 'POST', + body: formData, + }) + .then(res => res.text()); + } else { + html = await fetchApi( + novelUrl + 'ajax/chapters/', + { method: 'POST' }) + .then(res => res.text()); + } + + if (html !== '0') { + loadedCheerio = parseHTML(html); + } + + const chapters: Plugin.ChapterItem[] = []; + loadedCheerio('.wp-manga-chapter').each(function () { + const chapterName = loadedCheerio(this).find('a').text().trim(); + + let releaseDate = null; + releaseDate = loadedCheerio(this) + .find('span.chapter-release-date') + .text() + .trim(); + + if (releaseDate) { + releaseDate = parseMadaraDate(releaseDate); + } else { + /** + * Insert current date + */ + + releaseDate = dayjs().format('LL'); + } + + let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + + chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); + }); + + novel.chapters = chapters.reverse(); + return novel; + } + async parseChapter(chapterUrl: string): Promise { + const body = await fetchApi(chapterUrl).then(res => res.text()); - chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); - }); + const loadedCheerio = parseHTML(body); + const chapterText = + loadedCheerio('.text-left').html() || + loadedCheerio('.text-right').html() || + loadedCheerio('.entry-content').html() || ""; - novel.chapters = chapters.reverse(); - return novel; -}; - -export const parseChapter: Plugin.parseChapter = async (chapterUrl) => { - const url = baseUrl + "/" + "light-novel" + "/" + chapterUrl; - - const body = await fetchApi(chapterUrl).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - const chapterText = - loadedCheerio('.text-left').html() || - loadedCheerio('.text-right').html() || - loadedCheerio('.entry-content').html(); - - return chapterText; -}; - -export const searchNovels: Plugin.searchNovels = async (searchTerm) => { - const novels: Novel.Item[] = []; - const url = baseUrl + "?s=" + searchTerm + "&post_type=wp-manga"; - - const body = await fetchApi(url).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - - - loadedCheerio('.c-tabs-item__content').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - - let novelUrl = loadedCheerio(this) - .find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - - novels.push(novel); - }); - return novels; -}; - -export const fetchImage: Plugin.fetchImage = async (url) => { - return await fetchFile(url); -}; - -export const filters = [{"key":"sort","label":"Order by","values":[{"label":"Rating","value":"rating"},{"label":"A-Z","value":"alphabet"},{"label":"Latest","value":"latest"},{"label":"Most Views","value":"views"},{"label":"New","value":"new-manga"},{"label":"Trending","value":"trending"}],"inputType":FilterInputs.Picker}]; \ No newline at end of file + return chapterText; + } + async searchNovels(searchTerm: string, pageNo?: number | undefined): Promise { + const novels: Plugin.NovelItem[] = []; + const url = this.site + "?s=" + searchTerm + "&post_type=wp-manga"; + + const body = await fetchApi(url).then(res => res.text()); + + const loadedCheerio = parseHTML(body); + + + loadedCheerio('.c-tabs-item__content').each(function () { + const novelName = loadedCheerio(this).find('.post-title').text().trim(); + + let image = loadedCheerio(this).find('img'); + const novelCover = image.attr('data-src') || image.attr('src'); + + let novelUrl = loadedCheerio(this) + .find('.post-title') + .find('a') + .attr('href') || ''; + const novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + + novels.push(novel); + }); + return novels; + } + async fetchImage(url: string): Promise { + return await fetchFile(url, {}); + } +} +const plugin = new MadaraPlugin({"id":"turkcelightnovels","sourceSite":"https://turkcelightnovels.com/","sourceName":"TurkceLightNovels","filters":[{"key":"sort","label":"Order by","values":[{"label":"Rating","value":"rating"},{"label":"A-Z","value":"alphabet"},{"label":"Latest","value":"latest"},{"label":"Most Views","value":"views"},{"label":"New","value":"new-manga"},{"label":"Trending","value":"trending"}],"inputType":"Picker"}],"options":{"path":{"novels":"light-novel","novel":"light-novel","chapter":"light-novel"},"lang":"Turkish"}}); +export default plugin; + \ No newline at end of file diff --git a/plugins/turkish/WebNovelOku[madara].ts b/plugins/turkish/WebNovelOku[madara].ts index 3a0557d..9587bdc 100644 --- a/plugins/turkish/WebNovelOku[madara].ts +++ b/plugins/turkish/WebNovelOku[madara].ts @@ -1,213 +1,252 @@ +import { fetchApi, fetchFile } from "@libs/fetch"; +import { Filter } from "@libs/filterInputs"; +import { Plugin } from '@typings/plugin' import { load as parseHTML } from "cheerio"; -import { fetchFile, fetchApi } from "@libs/fetch"; -import { Novel, Plugin, Chapter } from "@typings/plugin"; -import { FilterInputs } from "@libs/filterInputs"; import { defaultCover } from "@libs/defaultCover"; -import { NovelStatus } from "@libs/novelStatus" +import { NovelStatus } from "@libs/novelStatus"; import { parseMadaraDate } from "@libs/parseMadaraDate"; import dayjs from "dayjs"; -export const id = "webnoveloku"; -export const name = "WebNovelOku [madara]"; -export const icon = "multisrc/madara/icons/webnoveloku.png"; -export const version = "1.0.0"; -export const site = "https://www.webnoveloku.com/"; -const baseUrl = site; +interface MadaraOptionPath{ + genres?: string, + novels?: string, + novel?: string, + chapter?: string, +} -export const popularNovels: Plugin.popularNovels = async (pageNo, {filters, showLatestNovels}) => { - const novels: Novel.Item[] = []; +const MadaraDefaultPath: MadaraOptionPath = { + novels: 'novel', + novel: 'novel', + chapter: 'novel' +} - let url = site; +interface MadaraOptions { + useNewChapterEndpoint?: boolean, + path?: MadaraOptionPath, + lang?: string, + orderBy?: string +} - if (filters?.genres) { - url += "novel-genre/" + filters.genres + '/'; - } else { - url += "novel/"; +export interface MadaraMetadata { + id: string, + sourceSite: string, + sourceName: string, + options?: MadaraOptions, + filters?: Filter[], +} +class MadaraPlugin implements Plugin.PluginBase { + id: string; + name: string; + icon: string; + site: string; + version: string; + userAgent: string; + cookieString: string; + options?: MadaraOptions; + filter?: Filter[] | undefined; + + constructor(metadata: MadaraMetadata){ + this.id = metadata.id; + this.name = metadata.sourceName + "[madara]"; + const iconFileName = metadata.sourceName.replace(/\s+/g, "").toLowerCase(); + this.icon = `multisrc/madara/icons/${iconFileName}.png`; + this.site = metadata.sourceSite; + this.version = "1.0.0"; + this.userAgent = ""; + this.cookieString = ""; + this.options = metadata.options; + this.filter = metadata.filters; } + async popularNovels(pageNo: number, {filters, showLatestNovels}: Plugin.PopularNovelsOptions): Promise { + const novels: Plugin.NovelItem[] = []; - url += '/page/' + pageNo + '/' + - '?m_orderby=' + (showLatestNovels ? 'latest' : (filters?.sort || 'rating')); - - const body = await fetchApi(url).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - - loadedCheerio('.manga-title-badges').remove(); - - loadedCheerio('.page-item-detail').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - - let novelUrl = loadedCheerio(this).find('.post-title') - .find('a') - .attr('href') || ''; - const novel: Novel.Item = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - - novels.push(novel); - }); - - return novels; -}; - -export const parseNovelAndChapters: Plugin.parseNovelAndChapters = async ( - novelUrl -) => { - const novel: Novel.instance = { - url: novelUrl, - }; - - const body = await fetchApi(novelUrl).then(res => res.text()); - - let loadedCheerio = parseHTML(body); - - loadedCheerio('.manga-title-badges').remove(); - - novel.name = loadedCheerio('.post-title h1').text().trim(); - - novel.cover = - loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || - loadedCheerio('.summary_image > a > img').attr('data-src') || - loadedCheerio('.summary_image > a > img').attr('src') || - defaultCover; - - loadedCheerio('.post-content_item, .post-content').each(function () { - const detailName = loadedCheerio(this).find('h5').text().trim(); - const detail = loadedCheerio(this).find('.summary-content').text().trim(); - - switch (detailName) { - case 'Genre(s)': - case 'التصنيفات': - novel.genres = detail.replace(/[\t\n]/g, ','); - break; - case 'Author(s)': - case 'المؤلف': - case 'المؤلف (ين)': - novel.author = detail; - break; - case 'Status': - case 'الحالة': - novel.status = - detail.includes('OnGoing') || detail.includes('مستمرة') - ? NovelStatus.Ongoing - : NovelStatus.Completed; - break; - } - }); - - loadedCheerio('div.summary__content .code-block,script').remove(); - novel.summary = loadedCheerio('div.summary__content').text().trim(); - - - let html; - - if (false) { - const novelId = - loadedCheerio('.rating-post-id').attr('value') || - loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; - - const body = { - action: "manga_get_chapters", - manga: novelId, - } - html = await fetchApi( - baseUrl + 'wp-admin/admin-ajax.php', - { - method: 'POST', - body: JSON.stringify(body), - }) - .then(res => res.text()); - } else { - html = await fetchApi( - baseUrl + 'ajax/chapters/', - { method: 'POST' }) - .then(res => res.text()); - } - - if (html !== '0') { - loadedCheerio = parseHTML(html); - } - - const chapters: Chapter.Item[] = []; - loadedCheerio('.wp-manga-chapter').each(function () { - const chapterName = loadedCheerio(this).find('a').text().trim(); - - let releaseDate = null; - releaseDate = loadedCheerio(this) - .find('span.chapter-release-date') - .text() - .trim(); - - if (releaseDate) { - releaseDate = parseMadaraDate(releaseDate); + let url = this.site; + if (filters?.genres && this.options?.path?.genres) { + url += this.options?.path?.genres + filters.genres + '/'; } else { - /** - * Insert current date - */ - - releaseDate = dayjs().format('LL'); + url += this.options?.path?.novels ? this.options.path.novels : MadaraDefaultPath.novels; } + + url += '/page/' + pageNo + '/' + + '?m_orderby=' + (showLatestNovels ? 'latest' : (filters?.sort || 'rating')); + + const body = await fetchApi(url).then(res => res.text()); + + const loadedCheerio = parseHTML(body); + + loadedCheerio('.manga-title-badges').remove(); + + loadedCheerio('.page-item-detail').each(function () { + const novelName = loadedCheerio(this).find('.post-title').text().trim(); + let image = loadedCheerio(this).find('img'); + const novelCover = image.attr('data-src') || image.attr('src'); + + let novelUrl = loadedCheerio(this).find('.post-title') + .find('a') + .attr('href') || ''; + const novel: Plugin.NovelItem = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + + novels.push(novel); + }); + + return novels; + } + async parseNovelAndChapters(novelUrl: string): Promise { + const novel: Plugin.SourceNovel = { + url: novelUrl, + }; + + const body = await fetchApi(novelUrl).then(res => res.text()); + + let loadedCheerio = parseHTML(body); + + loadedCheerio('.manga-title-badges, #manga-title span').remove(); + novel.name = + loadedCheerio('.post-title h1').text().trim() || + loadedCheerio('#manga-title h1').text(); + + novel.cover = + loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || + loadedCheerio('.summary_image > a > img').attr('data-src') || + loadedCheerio('.summary_image > a > img').attr('src') || + defaultCover; + + loadedCheerio('.post-content_item, .post-content').each(function () { + const detailName = loadedCheerio(this).find('h5').text().trim(); + const detail = loadedCheerio(this).find('.summary-content').text().trim(); + + switch (detailName) { + case 'Genre(s)': + case 'التصنيفات': + novel.genres = detail.replace(/[\\t\\n]/g, ','); + break; + case 'Author(s)': + case 'المؤلف': + case 'المؤلف (ين)': + novel.author = detail; + break; + case 'Status': + case 'الحالة': + novel.status = + detail.includes('OnGoing') || detail.includes('مستمرة') + ? NovelStatus.Ongoing + : NovelStatus.Completed; + break; + } + }); + + loadedCheerio('div.summary__content .code-block,script').remove(); + novel.summary = + loadedCheerio('div.summary__content').text().trim() || + loadedCheerio('#tab-manga-about').text().trim() || + loadedCheerio('.post-content_item h5:contains("Summary")').next().text().trim(); + + let html; + + if (this.options?.useNewChapterEndpoint !== true) { + const novelId = + loadedCheerio('.rating-post-id').attr('value') || + loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; + + const formData = new FormData() + formData.append("action", "manga_get_chapters"); + formData.append("manga", novelId); - let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + html = await fetchApi( + this.site + 'wp-admin/admin-ajax.php', + { + method: 'POST', + body: formData, + }) + .then(res => res.text()); + } else { + html = await fetchApi( + novelUrl + 'ajax/chapters/', + { method: 'POST' }) + .then(res => res.text()); + } + + if (html !== '0') { + loadedCheerio = parseHTML(html); + } + + const chapters: Plugin.ChapterItem[] = []; + loadedCheerio('.wp-manga-chapter').each(function () { + const chapterName = loadedCheerio(this).find('a').text().trim(); + + let releaseDate = null; + releaseDate = loadedCheerio(this) + .find('span.chapter-release-date') + .text() + .trim(); + + if (releaseDate) { + releaseDate = parseMadaraDate(releaseDate); + } else { + /** + * Insert current date + */ + + releaseDate = dayjs().format('LL'); + } + + let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + + chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); + }); + + novel.chapters = chapters.reverse(); + return novel; + } + async parseChapter(chapterUrl: string): Promise { + const body = await fetchApi(chapterUrl).then(res => res.text()); - chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); - }); + const loadedCheerio = parseHTML(body); + const chapterText = + loadedCheerio('.text-left').html() || + loadedCheerio('.text-right').html() || + loadedCheerio('.entry-content').html() || ""; - novel.chapters = chapters.reverse(); - return novel; -}; - -export const parseChapter: Plugin.parseChapter = async (chapterUrl) => { - const url = baseUrl + "/" + "novel" + "/" + chapterUrl; - - const body = await fetchApi(chapterUrl).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - const chapterText = - loadedCheerio('.text-left').html() || - loadedCheerio('.text-right').html() || - loadedCheerio('.entry-content').html(); - - return chapterText; -}; - -export const searchNovels: Plugin.searchNovels = async (searchTerm) => { - const novels: Novel.Item[] = []; - const url = baseUrl + "?s=" + searchTerm + "&post_type=wp-manga"; - - const body = await fetchApi(url).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - - - loadedCheerio('.c-tabs-item__content').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - - let novelUrl = loadedCheerio(this) - .find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - - novels.push(novel); - }); - return novels; -}; - -export const fetchImage: Plugin.fetchImage = async (url) => { - return await fetchFile(url); -}; - -export const filters = [{"key":"sort","label":"Sırala","values":[{"label":"A-Z","value":"alphabet"},{"label":"En Son","value":"latest"},{"label":"Görüntülenme","value":"views"},{"label":"Popülarite","value":"trending"},{"label":"Reyting","value":"rating"},{"label":"Yeni","value":"new-manga"}],"inputType":FilterInputs.Picker}]; \ No newline at end of file + return chapterText; + } + async searchNovels(searchTerm: string, pageNo?: number | undefined): Promise { + const novels: Plugin.NovelItem[] = []; + const url = this.site + "?s=" + searchTerm + "&post_type=wp-manga"; + + const body = await fetchApi(url).then(res => res.text()); + + const loadedCheerio = parseHTML(body); + + + loadedCheerio('.c-tabs-item__content').each(function () { + const novelName = loadedCheerio(this).find('.post-title').text().trim(); + + let image = loadedCheerio(this).find('img'); + const novelCover = image.attr('data-src') || image.attr('src'); + + let novelUrl = loadedCheerio(this) + .find('.post-title') + .find('a') + .attr('href') || ''; + const novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + + novels.push(novel); + }); + return novels; + } + async fetchImage(url: string): Promise { + return await fetchFile(url, {}); + } +} +const plugin = new MadaraPlugin({"id":"webnoveloku","sourceSite":"https://www.webnoveloku.com/","sourceName":"WebNovelOku ","filters":[{"key":"sort","label":"Sırala","values":[{"label":"A-Z","value":"alphabet"},{"label":"En Son","value":"latest"},{"label":"Görüntülenme","value":"views"},{"label":"Popülarite","value":"trending"},{"label":"Reyting","value":"rating"},{"label":"Yeni","value":"new-manga"}],"inputType":"Picker"}],"options":{"lang":"Turkish"}}); +export default plugin; + \ No newline at end of file diff --git a/plugins/turkish/epiknovel.ts b/plugins/turkish/epiknovel.broken.ts similarity index 100% rename from plugins/turkish/epiknovel.ts rename to plugins/turkish/epiknovel.broken.ts diff --git a/plugins/turkish/lshnovel.ts b/plugins/turkish/lshnovel.ts index 473a98a..6ccd147 100644 --- a/plugins/turkish/lshnovel.ts +++ b/plugins/turkish/lshnovel.ts @@ -1,75 +1,76 @@ import { load as parseHTML } from "cheerio"; import { fetchApi, fetchFile } from "@libs/fetch"; -import { FilterInputs } from "@libs/filterInputs"; -import { Chapter, Novel, Plugin } from "@typings/plugin"; +import { Filter, FilterInputs } from "@libs/filterInputs"; +import { Plugin } from "@typings/plugin"; -export const id = "lshnovel"; -export const name = "Liebe Schnee Hiver Novel"; -export const version = "1.0.0"; -export const icon = "multisrc/wpmangastream/icons/lshnovel.png"; -export const site = "https://lshnovel.com/"; +class LSHNovel implements Plugin.PluginBase { + id = "lshnovel"; + name = "Liebe Schnee Hiver Novel"; + icon = "multisrc/wpmangastream/icons/lshnovel.png"; + site = "https://lshnovel.com/"; + version = "1.0.0"; + userAgent = ""; + cookieString = ""; + async popularNovels(pageNo: number, {filters}: Plugin.PopularNovelsOptions): Promise { + let link = `${this.site}series/?page=${pageNo}`; + if (filters) { + if (Array.isArray(filters.genres) && filters.genres.length) { + link += filters.genres.map((i) => `&genre[]=${i}`).join(""); + } -const pluginId = id; -const baseUrl = site; - -export const popularNovels: Plugin.popularNovels = async function ( - page, - { filters } -) { - let link = `${baseUrl}series/?page=${page}`; - - if (filters) { - if (Array.isArray(filters.genres) && filters.genres.length) { - link += filters.genres.map((i) => `&genre[]=${i}`).join(""); + if (Array.isArray(filters.type) && filters.type.length) + link += filters.type.map((i) => `&lang[]=${i}`).join(""); } + link += "&status=" + (filters?.status ? filters.status : ""); - if (Array.isArray(filters.type) && filters.type.length) { - link += filters.type.map((i) => `&lang[]=${i}`).join(""); + link += "&order=" + (filters?.order ? filters.order : "popular"); + + const headers = new Headers(); + if(this.cookieString){ + headers.append("cookie", this.cookieString); } - } + const body = await fetchApi(link, {headers}).then((result) => + result.text() + ); - link += "&status=" + (filters?.status ? filters?.status : ""); + const loadedCheerio = parseHTML(body); - link += "&order=" + (filters?.order ? filters?.order : "popular"); + const novels: Plugin.NovelItem[] = []; - const body = await fetchApi(link, {}, pluginId).then((result) => - result.text() - ); + loadedCheerio("article.bs").each(function () { + const novelName = loadedCheerio(this).find(".ntitle").text().trim(); + let image = loadedCheerio(this).find("img"); + const novelCover = image.attr("data-src") || image.attr("src"); - const loadedCheerio = parseHTML(body); + const novelUrl = loadedCheerio(this).find("a").attr("href"); - const novels: Novel.Item[] = []; + if (!novelUrl) return; - loadedCheerio("article.bs").each(function () { - const novelName = loadedCheerio(this).find(".ntitle").text().trim(); - let image = loadedCheerio(this).find("img"); - const novelCover = image.attr("data-src") || image.attr("src"); + const novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; - const novelUrl = loadedCheerio(this).find("a").attr("href"); - if (!novelUrl) return; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; + novels.push(novel); + }); - novels.push(novel); - }); + return novels; + }; - return novels; -}; - -export const parseNovelAndChapters: Plugin.parseNovelAndChapters = - async function (novelUrl) { + async parseNovelAndChapters(novelUrl: string): Promise { const url = novelUrl; - - const result = await fetchApi(url, {}, pluginId); + const headers = new Headers(); + if(this.cookieString){ + headers.append("cookie", this.cookieString); + } + const result = await fetchApi(url, {headers}); const body = await result.text(); let loadedCheerio = parseHTML(body); - const novel: Novel.instance = { + const novel: Plugin.SourceNovel = { url, chapters: [], }; @@ -82,21 +83,12 @@ export const parseNovelAndChapters: Plugin.parseNovelAndChapters = loadedCheerio("div.spe > span").each(function () { const detailName = loadedCheerio(this).find("b").text().trim(); - const detail = loadedCheerio(this) - .find("b") - .remove() - .end() - .text() - .trim(); + const detail = loadedCheerio(this).find('b').remove().end().text().trim(); switch (detailName) { - case "المؤلف:": case "Yazar:": - case "Autor:": - case "Author:": novel.author = detail; break; - case "Status:": case "Seviye:": novel.status = detail; break; @@ -115,7 +107,7 @@ export const parseNovelAndChapters: Plugin.parseNovelAndChapters = .end() .text(); - let chapter: Chapter.Item[] = []; + let chapter: Plugin.ChapterItem[] = []; loadedCheerio(".eplister") .find("li") @@ -131,7 +123,9 @@ export const parseNovelAndChapters: Plugin.parseNovelAndChapters = .trim(); const chapterUrl = loadedCheerio(this).find("a").attr("href"); + if (!chapterUrl) return; + chapter.push({ name: chapterName, releaseTime: releaseDate, @@ -142,172 +136,179 @@ export const parseNovelAndChapters: Plugin.parseNovelAndChapters = novel.chapters = chapter.reverse(); return novel; - }; + } + async parseChapter(chapterUrl: string): Promise { + const headers = new Headers(); + if(this.cookieString){ + headers.append("cookie", this.cookieString); + } + const result = await fetchApi(chapterUrl, {headers}); + const body = await result.text(); -export const parseChapter: Plugin.parseChapter = async function (chapterUrl) { - const result = await fetchApi(chapterUrl, {}, pluginId); - const body = await result.text(); + const loadedCheerio = parseHTML(body); - const loadedCheerio = parseHTML(body); + let chapterText = loadedCheerio(".epcontent").html() || ""; - let chapterText = loadedCheerio("div.epcontent").html(); + return chapterText; + } - return chapterText; -}; + async searchNovels(searchTerm: string, pageNo?: number | undefined): Promise { + const url = `${this.site}?s=${searchTerm}`; + const headers = new Headers(); + if(this.cookieString){ + headers.append("cookie", this.cookieString); + } + const result = await fetchApi(url, {headers}); + const body = await result.text(); -export const searchNovels: Plugin.searchNovels = async function (searchTerm) { - const url = `${baseUrl}?s=${searchTerm}`; + const loadedCheerio = parseHTML(body); - const result = await fetchApi(url, {}, pluginId); - const body = await result.text(); + const novels: Plugin.NovelItem[] = []; - const loadedCheerio = parseHTML(body); + loadedCheerio("article.bs").each(function () { + const novelName = loadedCheerio(this).find(".ntitle").text().trim(); + const novelCover = loadedCheerio(this).find("img").attr("src"); + const novelUrl = loadedCheerio(this).find("a").attr("href"); + if (!novelUrl) return; - const novels: Novel.Item[] = []; - - loadedCheerio("article.bs").each(function () { - const novelName = loadedCheerio(this).find(".ntitle").text().trim(); - const novelCover = loadedCheerio(this).find("img").attr("src"); - const novelUrl = loadedCheerio(this).find("a").attr("href"); - if (!novelUrl) return; - novels.push({ - name: novelName, - url: novelUrl, - cover: novelCover, + novels.push({ + name: novelName, + url: novelUrl, + cover: novelCover, + }); }); - }); - return novels; -}; + return novels; + } + async fetchImage(url: string): Promise { + return await fetchFile(url); + } -export const fetchImage: Plugin.fetchImage = async function (url) { - const headers = { - Referer: baseUrl, - }; - return await fetchFile(url, { headers: headers }); -}; -export const filters = [ - { - key: "order", - label: "Önerilen", - values: [ - { label: "Varsayılan", value: "" }, + filters = [ + { + key: "order", + label: "Önerilen", + values: [ + { label: "Varsayılan", value: "" }, - { label: "A-Z", value: "title" }, + { label: "A-Z", value: "title" }, - { label: "Z-A", value: "titlereverse" }, + { label: "Z-A", value: "titlereverse" }, - { label: "Son Yüklemeler", value: "update" }, + { label: "Son Yüklemeler", value: "update" }, - { label: "Son Eklenenler", value: "latest" }, + { label: "Son Eklenenler", value: "latest" }, - { label: "Bestimiz", value: "popular" }, - ], - inputType: FilterInputs.Picker, - }, - { - key: "status", - label: "Statü", - values: [ - { label: "Tümü", value: "" }, + { label: "Bestimiz", value: "popular" }, + ], + inputType: FilterInputs.Picker, + }, + { + key: "status", + label: "Statü", + values: [ + { label: "Tümü", value: "" }, - { label: "Ongoing", value: "ongoing" }, + { label: "Ongoing", value: "ongoing" }, - { label: "Hiatus", value: "hiatus" }, + { label: "Hiatus", value: "hiatus" }, - { label: "Completed", value: "completed" }, - ], - inputType: FilterInputs.Picker, - }, - { - key: "type", - label: "Tür", - values: [ - { label: "Çeviri Novel", value: "ceviri-novel" }, + { label: "Completed", value: "completed" }, + ], + inputType: FilterInputs.Picker, + }, + { + key: "type", + label: "Tür", + values: [ + { label: "Çeviri Novel", value: "ceviri-novel" }, - { label: "Liz-Chan", value: "liz-chan" }, + { label: "Liz-Chan", value: "liz-chan" }, - { label: "Manhwa", value: "manhwa" }, + { label: "Manhwa", value: "manhwa" }, - { label: "Orijinal Novel", value: "orijinal-novel" }, + { label: "Orijinal Novel", value: "orijinal-novel" }, - { label: "Web Novel", value: "web-novel" }, - ], - inputType: FilterInputs.Checkbox, - }, - { - key: "genres", - label: "Kategori", - values: [ - { label: "+18", value: "18" }, + { label: "Web Novel", value: "web-novel" }, + ], + inputType: FilterInputs.Checkbox, + }, + { + key: "genres", + label: "Kategori", + values: [ + { label: "+18", value: "18" }, - { label: "Action", value: "action" }, + { label: "Action", value: "action" }, - { label: "Adult", value: "adult" }, + { label: "Adult", value: "adult" }, - { label: "Aksiyon", value: "aksiyon" }, + { label: "Aksiyon", value: "aksiyon" }, - { label: "BL", value: "bl" }, + { label: "BL", value: "bl" }, - { label: "Comedy", value: "comedy" }, + { label: "Comedy", value: "comedy" }, - { label: "Doğaüstü", value: "dogaustu" }, + { label: "Doğaüstü", value: "dogaustu" }, - { label: "Dram", value: "dram" }, + { label: "Dram", value: "dram" }, - { label: "Drama", value: "drama" }, + { label: "Drama", value: "drama" }, - { label: "Ecchi", value: "ecchi" }, + { label: "Ecchi", value: "ecchi" }, - { label: "Fantastik", value: "fantastik" }, + { label: "Fantastik", value: "fantastik" }, - { label: "Fantasy", value: "fantasy" }, + { label: "Fantasy", value: "fantasy" }, - { label: "Gizem", value: "gizem" }, + { label: "Gizem", value: "gizem" }, - { label: "Harem", value: "harem" }, + { label: "Harem", value: "harem" }, - { label: "Historical", value: "historical" }, + { label: "Historical", value: "historical" }, - { label: "Josei", value: "josei" }, + { label: "Josei", value: "josei" }, - { label: "Macera", value: "macera" }, + { label: "Macera", value: "macera" }, - { label: "Manhwa", value: "manhwa" }, + { label: "Manhwa", value: "manhwa" }, - { label: "Martial Arts", value: "martial-arts" }, + { label: "Martial Arts", value: "martial-arts" }, - { label: "Mature", value: "mature" }, + { label: "Mature", value: "mature" }, - { label: "Novel", value: "novel" }, + { label: "Novel", value: "novel" }, - { label: "Okul", value: "okul" }, + { label: "Okul", value: "okul" }, - { label: "Psikolojik", value: "psikolojik" }, + { label: "Psikolojik", value: "psikolojik" }, - { label: "Psychological", value: "psychological" }, + { label: "Psychological", value: "psychological" }, - { label: "Reverse Harem", value: "reverse-harem" }, + { label: "Reverse Harem", value: "reverse-harem" }, - { label: "Romance", value: "romance" }, + { label: "Romance", value: "romance" }, - { label: "Romantik", value: "romantik" }, + { label: "Romantik", value: "romantik" }, - { label: "Shoujo", value: "shoujo" }, + { label: "Shoujo", value: "shoujo" }, - { label: "Slice Of Life", value: "slice-of-life" }, + { label: "Slice Of Life", value: "slice-of-life" }, - { label: "Smut", value: "smut" }, + { label: "Smut", value: "smut" }, - { label: "Supernatural", value: "supernatural" }, + { label: "Supernatural", value: "supernatural" }, - { label: "Tarihi", value: "tarihi" }, + { label: "Tarihi", value: "tarihi" }, - { label: "Tragedy", value: "tragedy" }, + { label: "Tragedy", value: "tragedy" }, - { label: "Yaoi", value: "yaoi" }, - ], - inputType: FilterInputs.Checkbox, - }, -]; + { label: "Yaoi", value: "yaoi" }, + ], + inputType: FilterInputs.Checkbox, + }, + ]; +} + +export default new LSHNovel(); \ No newline at end of file diff --git a/plugins/ukraine/smakolykytl.ts b/plugins/ukraine/smakolykytl.broken.ts similarity index 100% rename from plugins/ukraine/smakolykytl.ts rename to plugins/ukraine/smakolykytl.broken.ts diff --git a/plugins/vietnamese/.vietnamese b/plugins/vietnamese/.vietnamese deleted file mode 100644 index e69de29..0000000 diff --git a/plugins/vietnamese/LNHako.ts b/plugins/vietnamese/LNHako.ts index a9ca1c7..43c22c1 100644 --- a/plugins/vietnamese/LNHako.ts +++ b/plugins/vietnamese/LNHako.ts @@ -1,197 +1,161 @@ -import { load as parseHTML } from "cheerio"; +import { CheerioAPI, load as parseHTML } from "cheerio"; import { fetchApi, fetchFile } from "@libs/fetch"; -import { Chapter, Novel, Plugin } from "@typings/plugin"; -// import dayjs from "dayjs"; -// import { FilterInputs } from "@libs/filterInputs"; -// import { NovelStatus } from "@libs/novelStatus"; +import { Plugin } from "@typings/plugin"; import { isUrlAbsolute } from "@libs/isAbsoluteUrl"; -// import { parseMadaraDate } from "@libs/parseMadaraDate"; +import { Filter } from "@libs/filterInputs"; +class HakoPlugin implements Plugin.PluginBase { + id: string; + name: string; + icon: string; + site: string; + version: string; + userAgent: string; + cookieString: string; + constructor(){ + this.id = "ln.hako"; + this.name = "Hako"; + this.icon = "src/vi/hakolightnovel/icon.png"; + this.site = "https://ln.hako.vn"; + this.version = "1.0.0"; + this.userAgent = ""; + this.cookieString = ""; + } + parseNovels(loadedCheerio: CheerioAPI){ + const novels: Plugin.NovelItem[] = []; + loadedCheerio(".row > .thumb-item-flow").each((index, ele) => { + let url = loadedCheerio(ele) + .find("div.thumb_attr.series-title > a") + .attr("href"); -const pluginId = "ln.hako"; -const baseUrl = "https://ln.hako.vn"; - -export const id = pluginId; // string and must be unique -export const name = "Hako"; -export const icon = "src/vi/hakolightnovel/icon.png"; // The relative path to the icon without @icons . For example: 'src/vi/hakolightnovel/icon.png' -export const version = "1.0.0"; // xx.xx.xx -export const site = baseUrl; // the link to the site - - -export const popularNovels: Plugin.popularNovels = async (pageNo) => { - const novels: Novel.Item[] = []; - const link = - baseUrl + "/danh-sach?truyendich=1&sapxep=topthang&page=" + pageNo; - const result = await fetchApi(link); - const body = await result.text(); - - const loadedCheerio = parseHTML(body); - - loadedCheerio("main.row > .thumb-item-flow").each(function () { - let url = loadedCheerio(this) - .find("div.thumb_attr.series-title > a") - .attr("href"); - - if (url && !isUrlAbsolute(url)) { - url = baseUrl + url; - } - - if (url) { - const name = loadedCheerio(this) - .find(".series-title") - .text() - .trim(); - let cover = loadedCheerio(this) - .find(".img-in-ratio") - .attr("data-bg"); - - if (cover && !isUrlAbsolute(cover)) { - cover = baseUrl + cover; + if (url && !isUrlAbsolute(url)) { + url = this.site + url; } - const novel = { - name, - url, - cover, - }; + if (url) { + const name = loadedCheerio(ele) + .find(".series-title") + .text() + .trim(); + let cover = loadedCheerio(ele) + .find(".img-in-ratio") + .attr("data-bg"); - novels.push(novel); - } - }); + if (cover && !isUrlAbsolute(cover)) { + cover = this.site + cover; + } - return novels; -}; + const novel = {name, url, cover}; -export const parseNovelAndChapters: Plugin.parseNovelAndChapters = async ( - novelUrl -) => { - const novel: Novel.instance = { - url: novelUrl, - }; - const result = await fetchApi(novelUrl); - const body = await result.text(); - - let loadedCheerio = parseHTML(body); - - novel.name = loadedCheerio(".series-name").text(); - - const background = - loadedCheerio(".series-cover > .a6-ratio > div").attr("style") || ""; - const novelCover = background.substring( - background.indexOf("http"), - background.length - 2 - ); - - novel.cover = novelCover - ? isUrlAbsolute(novelCover) - ? novelCover - : baseUrl + novelCover - : ""; - - novel.summary = loadedCheerio(".summary-content").text().trim(); - - novel.author = loadedCheerio( - "#mainpart > div:nth-child(2) > div > div:nth-child(1) > section > main > div.top-part > div > div.col-12.col-md-9 > div.series-information > div:nth-child(2) > span.info-value > a" - ) - .text() - .trim(); - - novel.genres = loadedCheerio(".series-gernes") - .text() - .trim() - .replace(/ +/g, " ") - .split("\n") - .filter((e) => e.trim()) - .join(", "); - - novel.status = loadedCheerio( - "#mainpart > div:nth-child(2) > div > div:nth-child(1) > section > main > div.top-part > div > div.col-12.col-md-9 > div.series-information > div:nth-child(4) > span.info-value > a" - ) - .text() - .trim(); - - const chapters: Chapter.Item[] = []; - loadedCheerio(".list-chapters li").each(function () { - let chapterUrl = loadedCheerio(this).find("a").attr("href"); - - if (chapterUrl && !isUrlAbsolute(chapterUrl)) { - chapterUrl = baseUrl + chapterUrl; - } - - if (chapterUrl) { - const chapterName = loadedCheerio(this) - .find(".chapter-name") - .text() - .trim(); - const releaseTime = loadedCheerio(this) - .find(".chapter-time") - .text(); - - const chapter = { - name: chapterName, - releaseTime: releaseTime, - url: chapterUrl, - }; - - chapters.push(chapter); - } - }); - novel.chapters = chapters; - return novel; -}; - -export const parseChapter: Plugin.parseChapter = async (chapterUrl) => { - const result = await fetchApi(chapterUrl); - const body = await result.text(); - - const loadedCheerio = parseHTML(body); - - const chapterText = loadedCheerio("#chapter-content").html() || ""; - - return chapterText; -}; - -export const searchNovels: Plugin.searchNovels = async (searchTerm) => { - const novels: Novel.Item[] = []; - - const url = baseUrl + "/tim-kiem?keywords=" + searchTerm; - const result = await fetchApi(url); - const body = await result.text(); - - const loadedCheerio = parseHTML(body); - - loadedCheerio("div.row > .thumb-item-flow").each(function () { - let novelUrl = loadedCheerio(this) - .find("div.thumb_attr.series-title > a") - .attr("href"); - - if (novelUrl && !isUrlAbsolute(novelUrl)) { - novelUrl = baseUrl + novelUrl; - } - - if (novelUrl) { - const novelName = loadedCheerio(this).find(".series-title").text(); - let novelCover = loadedCheerio(this) - .find(".img-in-ratio") - .attr("data-bg"); - - if (novelCover && !isUrlAbsolute(novelCover)) { - novelCover = baseUrl + novelCover; + novels.push(novel); } + }); + return novels; + } + async popularNovels(pageNo: number, options: Plugin.PopularNovelsOptions): Promise { + const link = this.site + "/danh-sach?truyendich=1&sapxep=topthang&page=" + pageNo; + const result = await fetch(link); + const body = await result.text(); + const loadedCheerio = parseHTML(body); + return this.parseNovels(loadedCheerio); + } + async parseNovelAndChapters(novelUrl: string): Promise { + const novel: Plugin.SourceNovel = { + url: novelUrl, + }; + const result = await fetch(novelUrl); + const body = await result.text(); + + let loadedCheerio = parseHTML(body); + + novel.name = loadedCheerio(".series-name").text(); + + const background = + loadedCheerio(".series-cover > .a6-ratio > div").attr("style") || ""; + const novelCover = background.substring( + background.indexOf("http"), + background.length - 2 + ); + + novel.cover = novelCover + ? isUrlAbsolute(novelCover) + ? novelCover + : this.site + novelCover + : ""; + + novel.summary = loadedCheerio(".summary-content").text().trim(); + + novel.author = loadedCheerio( + "#mainpart > div:nth-child(2) > div > div:nth-child(1) > section > main > div.top-part > div > div.col-12.col-md-9 > div.series-information > div:nth-child(2) > span.info-value > a" + ) + .text() + .trim(); + + novel.genres = loadedCheerio(".series-gernes") + .text() + .trim() + .replace(/ +/g, " ") + .split("\n") + .filter((e) => e.trim()) + .join(", "); + + novel.status = loadedCheerio( + "#mainpart > div:nth-child(2) > div > div:nth-child(1) > section > main > div.top-part > div > div.col-12.col-md-9 > div.series-information > div:nth-child(4) > span.info-value > a" + ) + .text() + .trim(); + + const chapters: Plugin.ChapterItem[] = []; + loadedCheerio(".list-chapters li").each((index, ele) => { + let chapterUrl = loadedCheerio(ele).find("a").attr("href"); + + if (chapterUrl && !isUrlAbsolute(chapterUrl)) { + chapterUrl = this.site + chapterUrl; + } + + if (chapterUrl) { + const chapterName = loadedCheerio(ele) + .find(".chapter-name") + .text() + .trim(); + const releaseTime = loadedCheerio(ele) + .find(".chapter-time") + .text(); + + const chapter = { + name: chapterName, + releaseTime: releaseTime, + url: chapterUrl, + }; + + chapters.push(chapter); + } + }); + novel.chapters = chapters; + return novel; + } + async parseChapter(chapterUrl: string): Promise { + const result = await fetch(chapterUrl); + const body = await result.text(); - novels.push({ - name: novelName, - url: novelUrl, - cover: novelCover, - }); - } - }); + const loadedCheerio = parseHTML(body); - return novels; -}; + const chapterText = loadedCheerio("#chapter-content").html() || ""; -export const fetchImage: Plugin.fetchImage = async (url) => { - const headers = { - Referer: "https://ln.hako.vn", - }; - return await fetchFile(url, { headers: headers }); -}; + return chapterText; + } + async searchNovels(searchTerm: string, pageNo?: number | undefined): Promise { + const url = this.site + "/tim-kiem?keywords=" + searchTerm; + const result = await fetch(url); + const body = await result.text(); + const loadedCheerio = parseHTML(body); + return this.parseNovels(loadedCheerio); + } + async fetchImage(url: string): Promise { + const headers = { + Referer: "https://ln.hako.vn", + }; + return await fetchFile(url, { headers: headers }); + } +} + +export default new HakoPlugin(); diff --git a/scripts/clearMultisrc.ts b/scripts/clearMultisrc.ts new file mode 100644 index 0000000..da3fcfa --- /dev/null +++ b/scripts/clearMultisrc.ts @@ -0,0 +1,12 @@ +import * as path from 'path' +import * as fs from 'fs' + +const pluginDir = 'plugins' +fs.readdirSync(pluginDir).forEach(lang => { + const langDir = path.join(pluginDir, lang); + fs.readdirSync(langDir).forEach(plugin => { + if(plugin.endsWith('.ts') && plugin.includes("[")){ + fs.unlinkSync(path.join(langDir, plugin)); + } + }) +}) \ No newline at end of file diff --git a/scripts/json_plugins.ts b/scripts/json_plugins.ts index dd8ebda..a7542b7 100644 --- a/scripts/json_plugins.ts +++ b/scripts/json_plugins.ts @@ -16,11 +16,11 @@ if (!username || !repo || !branch) { console.error("config.json not provided!"); process.exit(1); } -if (!fs.existsSync(path.join(outRoot, "dist", username))) { - fs.mkdirSync(path.join(outRoot, "dist", username)); +if (!fs.existsSync(path.join(outRoot, ".dist", username))) { + fs.mkdirSync(path.join(outRoot, ".dist", username)); } const githubIconsLink = `https://raw.githubusercontent.com/${username}/${repo}/${branch}/icons`; -const githubPluginsLink = `https://raw.githubusercontent.com/${username}/${repo}/${branch}/js/plugins`; +const githubPluginsLink = `https://raw.githubusercontent.com/${username}/${repo}/${branch}/.js/plugins`; const json: { [key: string]: { @@ -33,8 +33,8 @@ const json: { iconUrl: string; }[]; } = {}; -const jsonPath = path.join(outRoot, "dist", username, "plugins.json"); -const jsonMinPath = path.join(outRoot, "dist", username, "plugins.min.json"); +const jsonPath = path.join(outRoot, ".dist", username, "plugins.json"); +const jsonMinPath = path.join(outRoot, ".dist", username, "plugins.min.json"); const pluginSet = new Set(); for (let language in languages) { @@ -47,10 +47,10 @@ for (let language in languages) { plugins.forEach((plugin) => { if (plugin.startsWith(".")) return; const instance: - | Plugin.instance + | Plugin.PluginBase | unknown = require(`../plugins/${language.toLowerCase()}/${ plugin.split(".")[0] - }`); + }`).default; if (!isPlugin(instance)) { console.log(plugin); diff --git a/scripts/multisrc/generate.ts b/scripts/multisrc/generate.ts index b0c6f5c..a065a29 100644 --- a/scripts/multisrc/generate.ts +++ b/scripts/multisrc/generate.ts @@ -19,7 +19,6 @@ const generate = async (name: string): Promise => { if (!isScriptGenerator(generateAll)) return false; const sources = generateAll(); - for (let source of sources) { const { lang, filename, pluginScript } = source; if(!lang || !filename || !pluginScript){ diff --git a/scripts/multisrc/madara/generator.ts b/scripts/multisrc/madara/generator.ts index 360303f..b800651 100644 --- a/scripts/multisrc/madara/generator.ts +++ b/scripts/multisrc/madara/generator.ts @@ -1,244 +1,28 @@ import { ScrpitGeneratorFunction } from "../generate"; import list from "./sources.json"; +import { MadaraMetadata } from "./template"; +import { readFileSync } from 'fs'; +import path from "path"; -type sourceData = (typeof list)[number]; export const generateAll: ScrpitGeneratorFunction = function () { - return list.map((source) => { - return generator(source); + return list.map((metadata: MadaraMetadata) => { + return generator(metadata); }); }; -const generator = function generator(sourceJson: sourceData) { - const { id, sourceSite, sourceName, options } = sourceJson; - const lang = options?.lang || "English"; - const path = { - genres: options?.path?.genres || "novel-genre", - novels: options?.path?.novels || "novel", - novel: options?.path?.novel || "novel", - chapter: options?.path?.chapter || "novel", - }; - const useNewChapterEndpoint = options?.useNewChapterEndpoint || false; - const iconFileName = sourceName.replace(/\s+/g, "").toLowerCase(); - const filters = sourceJson.filters; - const filetersString = JSON.stringify(filters).replace(/(\"inputType\":)\s*\"([^\"]+)\"/g, "$1FilterInputs.$2"); +const generator = function generator(metadata: MadaraMetadata) { + const lang = metadata.options?.lang || "English"; + + const madaraTemplate = readFileSync(path.join(__dirname, 'template.ts'), {encoding: 'utf-8'}); const pluginScript = ` -import { load as parseHTML } from "cheerio"; -import { fetchFile, fetchApi } from "@libs/fetch"; -import { Novel, Plugin, Chapter } from "@typings/plugin"; -import { FilterInputs } from "@libs/filterInputs"; -import { defaultCover } from "@libs/defaultCover"; -import { NovelStatus } from "@libs/novelStatus" -import { parseMadaraDate } from "@libs/parseMadaraDate"; -import dayjs from "dayjs"; - -export const id = "${id}"; -export const name = "${sourceName} [madara]"; -export const icon = "multisrc/madara/icons/${iconFileName}.png"; -export const version = "1.0.0"; -export const site = "${sourceSite}"; -const baseUrl = site; - -export const popularNovels: Plugin.popularNovels = async (pageNo, {filters, showLatestNovels}) => { - const novels: Novel.Item[] = []; - - let url = site; - - if (filters?.genres) { - url += "${path.genres}/" + filters.genres + '/'; - } else { - url += "${path.novels}/"; - } - - url += '/page/' + pageNo + '/' + - '?m_orderby=' + (showLatestNovels ? 'latest' : (filters?.sort || 'rating')); - - const body = await fetchApi(url).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - - loadedCheerio('.manga-title-badges').remove(); - - loadedCheerio('.page-item-detail').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - - let novelUrl = loadedCheerio(this).find('.post-title') - .find('a') - .attr('href') || ''; - const novel: Novel.Item = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - - novels.push(novel); - }); - - return novels; -}; - -export const parseNovelAndChapters: Plugin.parseNovelAndChapters = async ( - novelUrl -) => { - const novel: Novel.instance = { - url: novelUrl, - }; - - const body = await fetchApi(novelUrl).then(res => res.text()); - - let loadedCheerio = parseHTML(body); - - loadedCheerio('.manga-title-badges').remove(); - - novel.name = loadedCheerio('.post-title h1').text().trim(); - - novel.cover = - loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || - loadedCheerio('.summary_image > a > img').attr('data-src') || - loadedCheerio('.summary_image > a > img').attr('src') || - defaultCover; - - loadedCheerio('.post-content_item, .post-content').each(function () { - const detailName = loadedCheerio(this).find('h5').text().trim(); - const detail = loadedCheerio(this).find('.summary-content').text().trim(); - - switch (detailName) { - case 'Genre(s)': - case 'التصنيفات': - novel.genres = detail.replace(/[\\t\\n]/g, ','); - break; - case 'Author(s)': - case 'المؤلف': - case 'المؤلف (ين)': - novel.author = detail; - break; - case 'Status': - case 'الحالة': - novel.status = - detail.includes('OnGoing') || detail.includes('مستمرة') - ? NovelStatus.Ongoing - : NovelStatus.Completed; - break; - } - }); - - loadedCheerio('div.summary__content .code-block,script').remove(); - novel.summary = loadedCheerio('div.summary__content').text().trim(); - - - let html; - - if (${useNewChapterEndpoint}) { - const novelId = - loadedCheerio('.rating-post-id').attr('value') || - loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; - - const body = { - action: "manga_get_chapters", - manga: novelId, - } - html = await fetchApi( - baseUrl + 'wp-admin/admin-ajax.php', - { - method: 'POST', - body: JSON.stringify(body), - }) - .then(res => res.text()); - } else { - html = await fetchApi( - baseUrl + 'ajax/chapters/', - { method: 'POST' }) - .then(res => res.text()); - } - - if (html !== '0') { - loadedCheerio = parseHTML(html); - } - - const chapters: Chapter.Item[] = []; - loadedCheerio('.wp-manga-chapter').each(function () { - const chapterName = loadedCheerio(this).find('a').text().trim(); - - let releaseDate = null; - releaseDate = loadedCheerio(this) - .find('span.chapter-release-date') - .text() - .trim(); - - if (releaseDate) { - releaseDate = parseMadaraDate(releaseDate); - } else { - /** - * Insert current date - */ - - releaseDate = dayjs().format('LL'); - } - - let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; - - chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); - }); - - novel.chapters = chapters.reverse(); - return novel; -}; - -export const parseChapter: Plugin.parseChapter = async (chapterUrl) => { - const url = baseUrl + "/" + "${path.chapter}" + "/" + chapterUrl; - - const body = await fetchApi(chapterUrl).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - const chapterText = - loadedCheerio('.text-left').html() || - loadedCheerio('.text-right').html() || - loadedCheerio('.entry-content').html(); - - return chapterText; -}; - -export const searchNovels: Plugin.searchNovels = async (searchTerm) => { - const novels: Novel.Item[] = []; - const url = baseUrl + "?s=" + searchTerm + "&post_type=wp-manga"; - - const body = await fetchApi(url).then(res => res.text()); - - const loadedCheerio = parseHTML(body); - - - loadedCheerio('.c-tabs-item__content').each(function () { - const novelName = loadedCheerio(this).find('.post-title').text().trim(); - - let image = loadedCheerio(this).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - - let novelUrl = loadedCheerio(this) - .find('.post-title') - .find('a') - .attr('href') || ''; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - - novels.push(novel); - }); - return novels; -}; - -export const fetchImage: Plugin.fetchImage = async (url) => { - return await fetchFile(url); -}; - -export const filters = ${filetersString};`; - +${madaraTemplate} +const plugin = new MadaraPlugin(${JSON.stringify(metadata)}); +export default plugin; + ` return { lang, - filename: sourceName, + filename: metadata.sourceName, pluginScript, }; }; diff --git a/scripts/multisrc/madara/sources.json b/scripts/multisrc/madara/sources.json index 1e1cda6..0eac867 100644 --- a/scripts/multisrc/madara/sources.json +++ b/scripts/multisrc/madara/sources.json @@ -5363,4 +5363,4 @@ "lang": "Turkish" } } -] \ No newline at end of file +] diff --git a/scripts/multisrc/madara/template.ts b/scripts/multisrc/madara/template.ts new file mode 100644 index 0000000..9a8a530 --- /dev/null +++ b/scripts/multisrc/madara/template.ts @@ -0,0 +1,248 @@ +import { fetchApi, fetchFile } from "@libs/fetch"; +import { Filter } from "@libs/filterInputs"; +import { Plugin } from '@typings/plugin' +import { load as parseHTML } from "cheerio"; +import { defaultCover } from "@libs/defaultCover"; +import { NovelStatus } from "@libs/novelStatus"; +import { parseMadaraDate } from "@libs/parseMadaraDate"; +import dayjs from "dayjs"; + +interface MadaraOptionPath{ + genres?: string, + novels?: string, + novel?: string, + chapter?: string, +} + +const MadaraDefaultPath: MadaraOptionPath = { + novels: 'novel', + novel: 'novel', + chapter: 'novel' +} + +interface MadaraOptions { + useNewChapterEndpoint?: boolean, + path?: MadaraOptionPath, + lang?: string, + orderBy?: string +} + +export interface MadaraMetadata { + id: string, + sourceSite: string, + sourceName: string, + options?: MadaraOptions, + filters?: Filter[], +} +class MadaraPlugin implements Plugin.PluginBase { + id: string; + name: string; + icon: string; + site: string; + version: string; + userAgent: string; + cookieString: string; + options?: MadaraOptions; + filter?: Filter[] | undefined; + + constructor(metadata: MadaraMetadata){ + this.id = metadata.id; + this.name = metadata.sourceName + "[madara]"; + const iconFileName = metadata.sourceName.replace(/\s+/g, "").toLowerCase(); + this.icon = `multisrc/madara/icons/${iconFileName}.png`; + this.site = metadata.sourceSite; + this.version = "1.0.0"; + this.userAgent = ""; + this.cookieString = ""; + this.options = metadata.options; + this.filter = metadata.filters; + } + async popularNovels(pageNo: number, {filters, showLatestNovels}: Plugin.PopularNovelsOptions): Promise { + const novels: Plugin.NovelItem[] = []; + + let url = this.site; + if (filters?.genres && this.options?.path?.genres) { + url += this.options?.path?.genres + filters.genres + '/'; + } else { + url += this.options?.path?.novels ? this.options.path.novels : MadaraDefaultPath.novels; + } + + url += '/page/' + pageNo + '/' + + '?m_orderby=' + (showLatestNovels ? 'latest' : (filters?.sort || 'rating')); + + const body = await fetchApi(url).then(res => res.text()); + + const loadedCheerio = parseHTML(body); + + loadedCheerio('.manga-title-badges').remove(); + + loadedCheerio('.page-item-detail').each(function () { + const novelName = loadedCheerio(this).find('.post-title').text().trim(); + let image = loadedCheerio(this).find('img'); + const novelCover = image.attr('data-src') || image.attr('src'); + + let novelUrl = loadedCheerio(this).find('.post-title') + .find('a') + .attr('href') || ''; + const novel: Plugin.NovelItem = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + + novels.push(novel); + }); + + return novels; + } + async parseNovelAndChapters(novelUrl: string): Promise { + const novel: Plugin.SourceNovel = { + url: novelUrl, + }; + + const body = await fetchApi(novelUrl).then(res => res.text()); + + let loadedCheerio = parseHTML(body); + + loadedCheerio('.manga-title-badges, #manga-title span').remove(); + novel.name = + loadedCheerio('.post-title h1').text().trim() || + loadedCheerio('#manga-title h1').text(); + + novel.cover = + loadedCheerio('.summary_image > a > img').attr('data-lazy-src') || + loadedCheerio('.summary_image > a > img').attr('data-src') || + loadedCheerio('.summary_image > a > img').attr('src') || + defaultCover; + + loadedCheerio('.post-content_item, .post-content').each(function () { + const detailName = loadedCheerio(this).find('h5').text().trim(); + const detail = loadedCheerio(this).find('.summary-content').text().trim(); + + switch (detailName) { + case 'Genre(s)': + case 'التصنيفات': + novel.genres = detail.replace(/[\\t\\n]/g, ','); + break; + case 'Author(s)': + case 'المؤلف': + case 'المؤلف (ين)': + novel.author = detail; + break; + case 'Status': + case 'الحالة': + novel.status = + detail.includes('OnGoing') || detail.includes('مستمرة') + ? NovelStatus.Ongoing + : NovelStatus.Completed; + break; + } + }); + + loadedCheerio('div.summary__content .code-block,script').remove(); + novel.summary = + loadedCheerio('div.summary__content').text().trim() || + loadedCheerio('#tab-manga-about').text().trim() || + loadedCheerio('.post-content_item h5:contains("Summary")').next().text().trim(); + + let html; + + if (this.options?.useNewChapterEndpoint !== true) { + const novelId = + loadedCheerio('.rating-post-id').attr('value') || + loadedCheerio('#manga-chapters-holder').attr('data-id') || ''; + + const formData = new FormData() + formData.append("action", "manga_get_chapters"); + formData.append("manga", novelId); + + html = await fetchApi( + this.site + 'wp-admin/admin-ajax.php', + { + method: 'POST', + body: formData, + }) + .then(res => res.text()); + } else { + html = await fetchApi( + novelUrl + 'ajax/chapters/', + { method: 'POST' }) + .then(res => res.text()); + } + + if (html !== '0') { + loadedCheerio = parseHTML(html); + } + + const chapters: Plugin.ChapterItem[] = []; + loadedCheerio('.wp-manga-chapter').each(function () { + const chapterName = loadedCheerio(this).find('a').text().trim(); + + let releaseDate = null; + releaseDate = loadedCheerio(this) + .find('span.chapter-release-date') + .text() + .trim(); + + if (releaseDate) { + releaseDate = parseMadaraDate(releaseDate); + } else { + /** + * Insert current date + */ + + releaseDate = dayjs().format('LL'); + } + + let chapterUrl = loadedCheerio(this).find('a').attr('href') || ''; + + chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); + }); + + novel.chapters = chapters.reverse(); + return novel; + } + async parseChapter(chapterUrl: string): Promise { + const body = await fetchApi(chapterUrl).then(res => res.text()); + + const loadedCheerio = parseHTML(body); + const chapterText = + loadedCheerio('.text-left').html() || + loadedCheerio('.text-right').html() || + loadedCheerio('.entry-content').html() || ""; + + return chapterText; + } + async searchNovels(searchTerm: string, pageNo?: number | undefined): Promise { + const novels: Plugin.NovelItem[] = []; + const url = this.site + "?s=" + searchTerm + "&post_type=wp-manga"; + + const body = await fetchApi(url).then(res => res.text()); + + const loadedCheerio = parseHTML(body); + + + loadedCheerio('.c-tabs-item__content').each(function () { + const novelName = loadedCheerio(this).find('.post-title').text().trim(); + + let image = loadedCheerio(this).find('img'); + const novelCover = image.attr('data-src') || image.attr('src'); + + let novelUrl = loadedCheerio(this) + .find('.post-title') + .find('a') + .attr('href') || ''; + const novel = { + name: novelName, + cover: novelCover, + url: novelUrl, + }; + + novels.push(novel); + }); + return novels; + } + async fetchImage(url: string): Promise { + return await fetchFile(url, {}); + } +} \ No newline at end of file diff --git a/scripts/multisrc/readwn/generator.ts b/scripts/multisrc/readwn/generator.ts deleted file mode 100644 index 19be43b..0000000 --- a/scripts/multisrc/readwn/generator.ts +++ /dev/null @@ -1,221 +0,0 @@ -import { ScrpitGeneratorFunction } from "../generate"; -import list from "./sources.json"; - -type sourceData = (typeof list)[number]; - -export const generateAll: ScrpitGeneratorFunction = function () { - return list.map((source) => { - return generator(source); - }); -}; - -const generator = function generator(sourceJson: sourceData) { - const pluginId = sourceJson.id; - const sourceName = sourceJson.sourceName; - const site = sourceJson.sourceSite; - const iconFileName = sourceName.split('.')[0].toLowerCase() + '.png'; - const filters = sourceJson.filters; - const filetersString = JSON.stringify(filters) - .replace(/(\"inputType\":)\s*\"([^\"]+)\"/g, " $1FilterInputs.$2"); - - const pluginScript = ` -import { load as parseHTML } from "cheerio"; -// import dayjs from 'dayjs'; -import { fetchFile, fetchApi } from "@libs/fetch"; -import { Novel, Plugin, Chapter } from "@typings/plugin"; -import { parseMadaraDate } from "@libs/parseMadaraDate"; -// import { isUrlAbsolute } from '@libs/isAbsoluteUrl'; -// import { showToast } from "@libs/showToast"; -import { FilterInputs } from "@libs/filterInputs"; -// import { NovelStatus } from '@libs/novelStatus'; -// import { defaultCover } from "@libs/defaultCover"; - -export const id = "${pluginId}"; -export const name = "${sourceName}"; -export const icon = "multisrc/readwn/icons/${iconFileName}"; -export const version = "1.0.0"; -export const site = "${site}"; - -export const popularNovels: Plugin.popularNovels = async function ( - page, - { filters, showLatestNovels } -) { - const novels: Novel.Item[] = []; - const pageNo = page - 1; - - let url = site + 'list/'; - url += (filters?.genres || 'all') + '/'; - url += (filters?.status || 'all') + '-'; - url += (showLatestNovels ? 'lastdotime' : filters?.sort || 'newstime') + '-'; - url += pageNo + '.html'; - - const result = await fetchApi(url); - const body = await result.text(); - - const loadedCheerio = parseHTML(body); - - - loadedCheerio('li.novel-item').each(function () { - const novelName = loadedCheerio(this).find('h4').text(); - const novelUrl = site + loadedCheerio(this).find('a').attr('href'); - - const coverUri = loadedCheerio(this) - .find('.novel-cover > img') - .attr('data-src'); - - const novelCover = site + coverUri; - - const novel = { name: novelName, cover: novelCover, url: novelUrl }; - - novels.push(novel); - }); - - return novels; -}; - - -export const parseNovelAndChapters: Plugin.parseNovelAndChapters = - async function (novelUrl) { - const result = await fetchApi(novelUrl); - const body = await result.text(); - - let loadedCheerio = parseHTML(body); - - const novel: Novel.instance = { - url: novelUrl, - chapters: [], - }; - - novel.name = loadedCheerio('h1.novel-title').text(); - - const coverUri = loadedCheerio('figure.cover > img').attr('data-src'); - novel.cover = site + coverUri; - - novel.summary = loadedCheerio('.summary') - .text() - .replace('Summary', '') - .trim(); - - novel.genres = ''; - - loadedCheerio('div.categories > ul > li').each(function () { - novel.genres += loadedCheerio(this).text().trim() + ','; - }); - - loadedCheerio('div.header-stats > span').each(function () { - if (loadedCheerio(this).find('small').text() === 'Status') { - novel.status = loadedCheerio(this).find('strong').text(); - } - }); - - novel.genres = novel.genres.slice(0, -1); - - novel.author = loadedCheerio('span[itemprop=author]').text(); - - let novelChapters: Chapter.Item[] = []; - - const novelId = novelUrl.replace('.html', '').replace(site, ''); - - const latestChapterNo = parseInt(loadedCheerio('.header-stats') - .find('span > strong') - .first() - .text() - .trim()); - - let lastChapterNo = 1; - loadedCheerio('.chapter-list li').each(function () { - const chapterName = loadedCheerio(this) - .find('a .chapter-title') - .text() - .trim(); - - const chapterUrl = site + loadedCheerio(this).find('a').attr('href')?.trim(); - - const releaseDate = loadedCheerio(this) - .find('a .chapter-update') - .text() - .trim(); - - lastChapterNo = parseInt(loadedCheerio(this).find('a .chapter-no').text().trim()); - - const chapter = { name: chapterName, releaseTime: parseMadaraDate(releaseDate), url: chapterUrl }; - - novelChapters.push(chapter); - }); - - // Itterate once more before loop to finish off - lastChapterNo++; - for (let i = lastChapterNo; i <= latestChapterNo; i++) { - const chapterName = 'Chapter ' + i; - const chapterUrl = site + novelId+'_'+ i +'.html'; - const releaseDate = null; - - const chapter = { name: chapterName, releaseTime: releaseDate,url: chapterUrl }; - - novelChapters.push(chapter); - } - - novel.chapters = novelChapters; - return novel; - }; - -export const parseChapter: Plugin.parseChapter = async function (chapterUrl) { - const result = await fetchApi(chapterUrl); - const body = await result.text(); - - const loadedCheerio = parseHTML(body); - - const chapterText = loadedCheerio('.chapter-content').html(); - return chapterText; -}; - -export const searchNovels: Plugin.searchNovels = async (searchTerm) => { - const novels: Novel.Item[] = []; - const searchUrl = site + 'e/search/index.php'; - - const result = await fetchApi(searchUrl, { - headers: { - 'Content-Type': 'application/x-www-form-urlencoded', - Referer: site + 'search.html', - Origin: site, - 'user-agent': - 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36', - }, - method: 'POST', - body: JSON.stringify({ - show: 'title', - tempid: 1, - tbname: 'news', - keyboard: searchTerm, - }), - }); - const body = await result.text(); - - const loadedCheerio = parseHTML(body); - - loadedCheerio('li.novel-item').each(function () { - const novelName = loadedCheerio(this).find('h4').text(); - const novelUrl = site + loadedCheerio(this).find('a').attr('href'); - - const coverUri = site + loadedCheerio(this).find('img').attr('data-src'); - const novelCover = site + coverUri; - const novel = { - name: novelName, - cover: novelCover, - url: novelUrl, - }; - - novels.push(novel); - }); - return novels; -}; - -export const fetchImage: Plugin.fetchImage = fetchFile; - -export const filters = ${filetersString};` - return { - lang: "English", - filename: sourceName, - pluginScript, - }; -}; diff --git a/scripts/multisrc/readwn/sources.json b/scripts/multisrc/readwn/sources.json deleted file mode 100644 index 9a7d358..0000000 --- a/scripts/multisrc/readwn/sources.json +++ /dev/null @@ -1,818 +0,0 @@ -[ - { - "id": "Readwn.com", - "sourceSite": "https://www.readwn.com/", - "sourceName": "Readwn.com", - "filters": [ - { - "key": "sort", - "label": "Sort By", - "values": [ - { - "label": "New", - "value": "newstime" - }, - { - "label": "Popular", - "value": "onclick" - }, - { - "label": "Updates", - "value": "lastdotime" - } - ], - "inputType": "Picker" - }, - { - "key": "status", - "label": "Status", - "values": [ - { - "label": "All", - "value": "all" - }, - { - "label": "Completed", - "value": "Completed" - }, - { - "label": "Ongoing", - "value": "Ongoing" - } - ], - "inputType": "Picker" - }, - { - "key": "genres", - "label": "Genre / Category", - "values": [ - { - "label": "All", - "value": "all" - }, - { - "label": "Action", - "value": "action" - }, - { - "label": "Adventure", - "value": "adventure" - }, - { - "label": "Chinese", - "value": "chinese" - }, - { - "label": "Comedy", - "value": "comedy" - }, - { - "label": "Contemporary Romance", - "value": "contemporary-romance" - }, - { - "label": "Drama", - "value": "drama" - }, - { - "label": "Eastern Fantasy", - "value": "eastern-fantasy" - }, - { - "label": "Ecchi", - "value": "ecchi" - }, - { - "label": "Erciyuan", - "value": "erciyuan" - }, - { - "label": "Faloo", - "value": "faloo" - }, - { - "label": "Fan-Fiction", - "value": "fan-fiction" - }, - { - "label": "Fantasy", - "value": "fantasy" - }, - { - "label": "Fantasy Romance", - "value": "fantasy-romance" - }, - { - "label": "Game", - "value": "game" - }, - { - "label": "Gender Bender", - "value": "gender-bender" - }, - { - "label": "Harem", - "value": "harem" - }, - { - "label": "Hentai", - "value": "hentai" - }, - { - "label": "Historical", - "value": "historical" - }, - { - "label": "Horror", - "value": "horror" - }, - { - "label": "Isekai", - "value": "isekai" - }, - { - "label": "Japanese", - "value": "japanese" - }, - { - "label": "Josei", - "value": "josei" - }, - { - "label": "Korean", - "value": "korean" - }, - { - "label": "Lolicon", - "value": "lolicon" - }, - { - "label": "Magic", - "value": "magic" - }, - { - "label": "Magical Realism", - "value": "magical-realism" - }, - { - "label": "Martial Arts", - "value": "martial-arts" - }, - { - "label": "Mecha", - "value": "mecha" - }, - { - "label": "Military", - "value": "military" - }, - { - "label": "Mystery", - "value": "mystery" - }, - { - "label": "Official Circles", - "value": "official_circles" - }, - { - "label": "Psychological", - "value": "psychological" - }, - { - "label": "Romance", - "value": "romance" - }, - { - "label": "School Life", - "value": "school-life" - }, - { - "label": "Sci-fi", - "value": "sci-fi" - }, - { - "label": "Science Fiction", - "value": "science_fiction" - }, - { - "label": "Seinen", - "value": "seinen" - }, - { - "label": "Shoujo", - "value": "shoujo" - }, - { - "label": "Shoujo Ai", - "value": "shoujo-ai" - }, - { - "label": "Shounen", - "value": "shounen" - }, - { - "label": "Shounen Ai", - "value": "shounen-ai" - }, - { - "label": "Slice of Life", - "value": "slice-of-life" - }, - { - "label": "Sports", - "value": "sports" - }, - { - "label": "Supernatural", - "value": "supernatural" - }, - { - "label": "Suspense Thriller", - "value": "suspense_thriller" - }, - { - "label": "Tragedy", - "value": "tragedy" - }, - { - "label": "Travel Through Time", - "value": "travel_through_time" - }, - { - "label": "Two-dimensional", - "value": "two-dimensional" - }, - { - "label": "Urban", - "value": "urban" - }, - { - "label": "Urban Life", - "value": "urban-life" - }, - { - "label": "Video Games", - "value": "video-games" - }, - { - "label": "Virtual Reality", - "value": "virtual-reality" - }, - { - "label": "Wuxia", - "value": "wuxia" - }, - { - "label": "Wuxia Xianxia", - "value": "wuxia_xianxia" - }, - { - "label": "Xianxia", - "value": "xianxia" - }, - { - "label": "Xuanhuan", - "value": "xuanhuan" - }, - { - "label": "Yaoi", - "value": "yaoi" - }, - { - "label": "Yuri", - "value": "yuri" - } - ], - "inputType": "Picker" - } - ] - }, - { - "id": "Novelmt.com", - "sourceSite": "https://www.novelmt.com/", - "sourceName": "Novelmt.com", - "filters": [ - { - "key": "sort", - "label": "Sort By", - "values": [ - { - "label": "New", - "value": "newstime" - }, - { - "label": "Popular", - "value": "onclick" - }, - { - "label": "Updates", - "value": "lastdotime" - } - ], - "inputType": "Picker" - }, - { - "key": "status", - "label": "Status", - "values": [ - { - "label": "All", - "value": "all" - }, - { - "label": "Completed", - "value": "Completed" - }, - { - "label": "Ongoing", - "value": "Ongoing" - } - ], - "inputType": "Picker" - }, - { - "key": "genres", - "label": "Genre / Category", - "values": [ - { - "label": "All", - "value": "all" - }, - { - "label": "Action", - "value": "action" - }, - { - "label": "Adult", - "value": "adult" - }, - { - "label": "Adventure", - "value": "adventure" - }, - { - "label": "Billionaire", - "value": "billionaire" - }, - { - "label": "CEO", - "value": "ceo" - }, - { - "label": "Chinese", - "value": "chinese" - }, - { - "label": "Comedy", - "value": "comedy" - }, - { - "label": "Contemporary Romance", - "value": "contemporary-romance" - }, - { - "label": "Drama", - "value": "drama" - }, - { - "label": "Eastern Fantasy", - "value": "eastern-fantasy" - }, - { - "label": "Ecchi", - "value": "ecchi" - }, - { - "label": "Erciyuan", - "value": "erciyuan" - }, - { - "label": "Faloo", - "value": "faloo" - }, - { - "label": "Fan-Fiction", - "value": "fan-fiction" - }, - { - "label": "Fantasy", - "value": "fantasy" - }, - { - "label": "Fantasy Romance", - "value": "fantasy-romance" - }, - { - "label": "Farming", - "value": "farming" - }, - { - "label": "Game", - "value": "game" - }, - { - "label": "Games", - "value": "games" - }, - { - "label": "Gay Romance", - "value": "gay-romance" - }, - { - "label": "Gender Bender", - "value": "gender-bender" - }, - { - "label": "Harem", - "value": "harem" - }, - { - "label": "Historical", - "value": "historical" - }, - { - "label": "Historical Romance", - "value": "historical-romance" - }, - { - "label": "Horror", - "value": "horror" - }, - { - "label": "Isekai", - "value": "isekai" - }, - { - "label": "Japanese", - "value": "japanese" - }, - { - "label": "Josei", - "value": "josei" - }, - { - "label": "Korean", - "value": "korean" - }, - { - "label": "Lolicon", - "value": "lolicon" - }, - { - "label": "Magic", - "value": "magic" - }, - { - "label": "Magical Realism", - "value": "magical-realism" - }, - { - "label": "Martial Arts", - "value": "martial-arts" - }, - { - "label": "Mature", - "value": "mature" - }, - { - "label": "Mecha", - "value": "mecha" - }, - { - "label": "Military", - "value": "military" - }, - { - "label": "Modern Life", - "value": "modern-life" - }, - { - "label": "Modern Romance", - "value": "modern-romance" - }, - { - "label": "Mystery", - "value": "mystery" - }, - { - "label": "Psychological", - "value": "psychological" - }, - { - "label": "Romance", - "value": "romance" - }, - { - "label": "Romantic", - "value": "romantic" - }, - { - "label": "School Life", - "value": "school-life" - }, - { - "label": "Sci-fi", - "value": "sci-fi" - }, - { - "label": "Seinen", - "value": "seinen" - }, - { - "label": "Shoujo", - "value": "shoujo" - }, - { - "label": "Shoujo Ai", - "value": "shoujo-ai" - }, - { - "label": "Shounen", - "value": "shounen" - }, - { - "label": "Shounen Ai", - "value": "shounen-ai" - }, - { - "label": "Slice of Life", - "value": "slice-of-life" - }, - { - "label": "Smut", - "value": "smut" - }, - { - "label": "Sports", - "value": "sports" - }, - { - "label": "Supernatural", - "value": "supernatural" - }, - { - "label": "Tragedy", - "value": "tragedy" - }, - { - "label": "Two-dimensional", - "value": "two-dimensional" - }, - { - "label": "Urban", - "value": "urban" - }, - { - "label": "Urban Life", - "value": "urban-life" - }, - { - "label": "Video Games", - "value": "video-games" - }, - { - "label": "Virtual Reality", - "value": "virtual-reality" - }, - { - "label": "Wuxia", - "value": "wuxia" - }, - { - "label": "Xianxia", - "value": "xianxia" - }, - { - "label": "Xuanhuan", - "value": "xuanhuan" - }, - { - "label": "Yaoi", - "value": "yaoi" - }, - { - "label": "Yuri", - "value": "yuri" - } - ], - "inputType": "Picker" - } - ] - }, - { - "id": "Ltnovel.com", - "sourceSite": "https://www.ltnovel.com/", - "sourceName": "Ltnovel.com", - "filters": [ - { - "key": "sort", - "label": "Sort By", - "values": [ - { - "label": "New", - "value": "newstime" - }, - { - "label": "Popular", - "value": "onclick" - }, - { - "label": "Updates", - "value": "lastdotime" - } - ], - "inputType": "Picker" - }, - { - "key": "status", - "label": "Status", - "values": [ - { - "label": "All", - "value": "all" - }, - { - "label": "Completed", - "value": "Completed" - }, - { - "label": "Ongoing", - "value": "Ongoing" - } - ], - "inputType": "Picker" - }, - { - "key": "genres", - "label": "Genre / Category", - "values": [ - { - "label": "All", - "value": "all" - }, - { - "label": "Action", - "value": "action" - }, - { - "label": "Adult", - "value": "adult" - }, - { - "label": "Adventure", - "value": "adventure" - }, - { - "label": "Comedy", - "value": "comedy" - }, - { - "label": "Contemporary Romance", - "value": "contemporary-romance" - }, - { - "label": "Drama", - "value": "drama" - }, - { - "label": "Eastern Fantasy", - "value": "eastern-fantasy" - }, - { - "label": "Ecchi", - "value": "ecchi" - }, - { - "label": "Fantasy", - "value": "fantasy" - }, - { - "label": "Fantasy Romance", - "value": "fantasy-romance" - }, - { - "label": "Game", - "value": "game" - }, - { - "label": "Gender Bender", - "value": "gender-bender" - }, - { - "label": "Harem", - "value": "harem" - }, - { - "label": "Historical", - "value": "historical" - }, - { - "label": "Horror", - "value": "horror" - }, - { - "label": "Josei", - "value": "josei" - }, - { - "label": "Lolicon", - "value": "lolicon" - }, - { - "label": "Magical Realism", - "value": "magical-realism" - }, - { - "label": "Martial Arts", - "value": "martial-arts" - }, - { - "label": "Mature", - "value": "mature" - }, - { - "label": "Mecha", - "value": "mecha" - }, - { - "label": "Mystery", - "value": "mystery" - }, - { - "label": "Psychological", - "value": "psychological" - }, - { - "label": "Romance", - "value": "romance" - }, - { - "label": "School Life", - "value": "school-life" - }, - { - "label": "Sci-fi", - "value": "sci-fi" - }, - { - "label": "Seinen", - "value": "seinen" - }, - { - "label": "Shoujo", - "value": "shoujo" - }, - { - "label": "Shounen", - "value": "shounen" - }, - { - "label": "Shounen Ai", - "value": "shounen-ai" - }, - { - "label": "Slice of Life", - "value": "slice-of-life" - }, - { - "label": "Smut", - "value": "smut" - }, - { - "label": "Sports", - "value": "sports" - }, - { - "label": "Supernatural", - "value": "supernatural" - }, - { - "label": "Tragedy", - "value": "tragedy" - }, - { - "label": "Video Games", - "value": "video-games" - }, - { - "label": "Wuxia", - "value": "wuxia" - }, - { - "label": "Xianxia", - "value": "xianxia" - }, - { - "label": "Xuanhuan", - "value": "xuanhuan" - }, - { - "label": "Yaoi", - "value": "yaoi" - } - ], - "inputType": "Picker" - } - ] - } -] \ No newline at end of file diff --git a/scripts/multisrc/rulate/generator.ts b/scripts/multisrc/rulate/generator.ts deleted file mode 100644 index 7dd3098..0000000 --- a/scripts/multisrc/rulate/generator.ts +++ /dev/null @@ -1,251 +0,0 @@ -import { ScrpitGeneratorFunction } from "../generate"; -import list from "./sources.json"; - -type sourceData = (typeof list)[number]; - -export const generateAll: ScrpitGeneratorFunction = function () { - return list.map((source) => { - return generator(source); - }); -}; - -const generator = function generator(sourceJson: sourceData) { - const pluginId = sourceJson.id; - const sourceName = sourceJson.sourceName; - const iconFileName = sourceName.split('.')[0].toLowerCase() + '.png'; - const site = sourceJson.sourceSite; - const filters = sourceJson.filters; - const filetersString = JSON.stringify(filters).replace(/(\"inputType\":)\s*\"([^\"]+)\"/g, "$1FilterInputs.$2"); - const pluginScript = ` -import { load as parseHTML } from "cheerio"; -// import dayjs from 'dayjs'; -import { fetchFile, fetchApi } from "@libs/fetch"; -import { Novel, Plugin, Chapter } from "@typings/plugin"; -// import { parseMadaraDate } from "@libs/parseMadaraDate"; -// import { isUrlAbsolute } from '@libs/isAbsoluteUrl'; -// import { showToast } from "@libs/showToast"; -import { FilterInputs } from "@libs/filterInputs"; -import { NovelStatus } from '@libs/novelStatus'; -// import { defaultCover } from "@libs/defaultCover"; - -export const id = "${pluginId}"; -export const name = "${sourceName}"; -export const icon = "multisrc/rulate/icons/${iconFileName}"; -export const version = "1.0.0"; -export const site = "${site}"; - -export const popularNovels: Plugin.popularNovels = async function ( - page, - { filters, showLatestNovels } -) { - let url = site + '/search?t='; - url += '&cat=' + (filters?.cat || '0'); - url += '&s_lang=' + (filters?.s_lang || '0'); - url += '&t_lang=' + (filters?.t_lang || '0'); - url += '&type=' + (filters?.type || '0'); - url += '&sort=' + (showLatestNovels ? '4' : (filters?.sort || '6')); - url += '&atmosphere=' + (filters?.atmosphere || '0'); - url += '&adult=' + (filters?.adult || '0'); - - if (filters?.genres instanceof Array) { - url += filters.genres.map(i => '&genres[]=' + i).join(''); - } - - if (filters?.genres_ex instanceof Array) { - url += filters.genres_ex.map(i => '&genres_ex[]=' + i).join(''); - } - - if (filters?.tags instanceof Array) { - url += filters.tags.map(i => '&tags[]=' + i).join(''); - } - - if (filters?.tags_ex instanceof Array) { - url += filters.tags_ex.map(i => '&tags_ex[]=' + i).join(''); - } - - if (filters?.fandoms instanceof Array) { - url += filters.fandoms.map(i => '&fandoms[]=' + i).join(''); - } - - if (filters?.fandoms_ex instanceof Array) { - url += filters.fandoms_ex.map(i => '&fandoms_ex[]=' + i).join(''); - } - - if (filters?.trash instanceof Array) { - url += filters.trash.map(i => '&' + i + '=1').join(''); - } - - url += '&Book_page=' + page; - - const result = await fetchApi(url); - const body = await result.text(); - const loadedCheerio = parseHTML(body); - - const novels: Novel.Item[] = []; - - loadedCheerio( - 'ul[class="search-results"] > li:not([class="ad_type_catalog"])', - ).each(function () { - novels.push({ - name: loadedCheerio(this).find('p > a').text(), - cover: site + loadedCheerio(this).find('img').attr('src'), - url: site + loadedCheerio(this).find('p > a').attr('href') || '', - }); - }); - - return novels; -}; - - -export const parseNovelAndChapters: Plugin.parseNovelAndChapters = - async function (novelUrl) { - const novel: Novel.instance = { - url: novelUrl, - chapters: [], - }; - let result = await fetchApi(novelUrl); - if (result.url.includes('mature?path=')) { - const formData = new FormData(); - formData.append('path', novelUrl); - formData.append('ok', 'Да'); - - await fetchApi(result.url, { - method: 'POST', - body: formData, - }); - - result = await fetchApi(novelUrl); - } - const body = await result.text(); - const loadedCheerio = parseHTML(body); - - novel.name = loadedCheerio('div[class="container"] > div > div > h1, div.span8:nth-child(1) > h1:nth-child(2)') - .text() - .trim(); - novel.cover = - site + loadedCheerio('div[class="images"] > div img').attr('src'); - novel.summary = loadedCheerio('#Info > div:nth-child(3), .book-description').text(); - novel.author = loadedCheerio('.book-stats-icons_author > span:nth-child(2) > a:nth-child(1)').text() - let genres: string[] = []; - - loadedCheerio('div.span5 > p, .span5 > div:nth-child(2) > p').each(function () { - switch (loadedCheerio(this).find('strong').text()) { - case 'Автор:': - novel.author = loadedCheerio(this).find('em > a').text().trim(); - break; - case 'Выпуск:': - novel.status = - loadedCheerio(this).find('em').text().trim() === 'продолжается' - ? NovelStatus.Ongoing - : NovelStatus.Completed; - break; - case 'Тэги:': - loadedCheerio(this) - .find('em > a') - .each(function () { - genres.push(loadedCheerio(this).text()); - }); - break; - case 'Жанры:': - loadedCheerio(this) - .find('em > a') - .each(function () { - genres.push(loadedCheerio(this).text()); - }); - break; - } - }); - - if (genres.length > 0) { - novel.genres = genres.reverse().join(','); - } - - const chapters: Chapter.Item[] = []; - loadedCheerio('table > tbody > tr.chapter_row').each(function () { - const chapterName = loadedCheerio(this) - .find('td[class="t"] > a') - .text() - .trim(); - const releaseDate = loadedCheerio(this) - .find('td > span') - .attr('title') - ?.trim(); - const chapterUrl = site + loadedCheerio(this) - .find('td[class="t"] > a') - .attr('href'); - - if ( - loadedCheerio(this).find('td > span[class="disabled"]').length < 1 && - releaseDate - ) { - chapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl }); - } - }); - - novel.chapters = chapters; - return novel; - }; - -export const parseChapter: Plugin.parseChapter = async function (chapterUrl) { - let result = await fetchApi(chapterUrl); - if (result.url.includes('mature?path=')) { - const formData = new FormData(); - formData.append('ok', 'Да'); - - await fetchApi(result.url, { - method: 'POST', - body: formData, - }); - - result = await fetchApi(chapterUrl); - } - const body = await result.text(); - const loadedCheerio = parseHTML(body); - - loadedCheerio('.content-text img').each(function () { - if (!loadedCheerio(this).attr('src')?.startsWith('http')) { - const src = loadedCheerio(this).attr('src'); - loadedCheerio(this).attr('src', site + src); - } - }); - - const chapterText = loadedCheerio('.content-text').html(); - return chapterText; -}; - -export const searchNovels: Plugin.searchNovels = async (searchTerm) => { - const novels: Novel.Item[] = []; - const result = await fetchApi( - site + '/search/autocomplete?query=' + searchTerm, - ); - let json = await result.json() as response[]; - - json.forEach((item) => { - const novelName = item.title_one + ' / ' + item.title_two; - const novelCover = site + item.img; - const novelUrl = site + item.url; - - novels.push({ name: novelName, cover: novelCover, url: novelUrl }); - }); - - return novels; -}; - -interface response { - id: number; - title_one: string; - title_two: string; - url: string; - img: string; -}; - -export const fetchImage: Plugin.fetchImage = fetchFile; - -export const filters = ${filetersString};` - - return { - lang: "Russian", - filename: sourceName, - pluginScript, - }; -}; diff --git a/scripts/multisrc/rulate/sources.json b/scripts/multisrc/rulate/sources.json deleted file mode 100644 index 15642d5..0000000 --- a/scripts/multisrc/rulate/sources.json +++ /dev/null @@ -1,22556 +0,0 @@ -[ - { - "id": "tl.rulate", - "sourceSite": "https://tl.rulate.ru", - "sourceName": "Rulate", - "filters": [ - { - "key": "cat", - "label": "Из раздела каталога:", - "values": [ - { - "label": "Неважно", - "value": "0" - }, - { - "label": "Авторские", - "value": "18" - }, - { - "label": "Авторские", - "value": "35" - }, - { - "label": "Авторские фанфики", - "value": "51" - }, - { - "label": "Английские", - "value": "28" - }, - { - "label": "Английские", - "value": "34" - }, - { - "label": "Английские", - "value": "48" - }, - { - "label": "Аниме", - "value": "20" - }, - { - "label": "Аудиокниги", - "value": "25" - }, - { - "label": "Блич", - "value": "42" - }, - { - "label": "Большие игры", - "value": "22" - }, - { - "label": "Ван-Пис", - "value": "41" - }, - { - "label": "Визуальные новеллы", - "value": "8" - }, - { - "label": "Вьетнамские", - "value": "39" - }, - { - "label": "Вьетнамские", - "value": "49" - }, - { - "label": "Игры", - "value": "3" - }, - { - "label": "Китайские", - "value": "5" - }, - { - "label": "Китайские", - "value": "31" - }, - { - "label": "Китайские", - "value": "45" - }, - { - "label": "Книги", - "value": "2" - }, - { - "label": "Книги", - "value": "14" - }, - { - "label": "Комиксы", - "value": "29" - }, - { - "label": "Корейские", - "value": "7" - }, - { - "label": "Корейские", - "value": "33" - }, - { - "label": "Корейские", - "value": "47" - }, - { - "label": "Маленькие игры", - "value": "23" - }, - { - "label": "Манга", - "value": "16" - }, - { - "label": "Манга", - "value": "30" - }, - { - "label": "Марвел", - "value": "43" - }, - { - "label": "Машинный перевод", - "value": "44" - }, - { - "label": "Наруто", - "value": "40" - }, - { - "label": "Новеллы и ранобэ", - "value": "12" - }, - { - "label": "Переводы фанфиков", - "value": "19" - }, - { - "label": "Психология", - "value": "37" - }, - { - "label": "Путешествия", - "value": "36" - }, - { - "label": "Статьи", - "value": "13" - }, - { - "label": "Субтитры", - "value": "15" - }, - { - "label": "Фильмы", - "value": "21" - }, - { - "label": "Японские", - "value": "6" - }, - { - "label": "Японские", - "value": "32" - }, - { - "label": "Японские", - "value": "46" - } - ], - "inputType": "Picker" - }, - { - "key": "s_lang", - "label": "Язык оригинала:", - "values": [ - { - "label": "Неважно", - "value": "0" - }, - { - "label": "Абхазский", - "value": "20" - }, - { - "label": "Аварский", - "value": "21" - }, - { - "label": "Азербайджанский", - "value": "22" - }, - { - "label": "Аймара", - "value": "23" - }, - { - "label": "Акан", - "value": "24" - }, - { - "label": "Албанский", - "value": "25" - }, - { - "label": "Амхарский", - "value": "26" - }, - { - "label": "Английский", - "value": "2" - }, - { - "label": "Арабский", - "value": "27" - }, - { - "label": "Арагонский", - "value": "28" - }, - { - "label": "Арберешский", - "value": "29" - }, - { - "label": "Армянский", - "value": "30" - }, - { - "label": "Ассамский", - "value": "31" - }, - { - "label": "Астурийский", - "value": "32" - }, - { - "label": "Афарский", - "value": "33" - }, - { - "label": "Африкаанс", - "value": "34" - }, - { - "label": "Ацтекский", - "value": "35" - }, - { - "label": "Баварский", - "value": "36" - }, - { - "label": "Бамбарийский", - "value": "37" - }, - { - "label": "Баскский", - "value": "39" - }, - { - "label": "Башкирский", - "value": "40" - }, - { - "label": "Белорусский", - "value": "10" - }, - { - "label": "Бенгальский", - "value": "41" - }, - { - "label": "Бирманский", - "value": "42" - }, - { - "label": "Бислама", - "value": "43" - }, - { - "label": "Бихари", - "value": "44" - }, - { - "label": "Болгарский", - "value": "45" - }, - { - "label": "Боснийский", - "value": "234" - }, - { - "label": "Бретонский", - "value": "47" - }, - { - "label": "Валенсийский", - "value": "48" - }, - { - "label": "Валлийский", - "value": "49" - }, - { - "label": "Валлонский", - "value": "50" - }, - { - "label": "Венгерский", - "value": "51" - }, - { - "label": "Венда", - "value": "52" - }, - { - "label": "Венетский", - "value": "53" - }, - { - "label": "Верхнелужицкий", - "value": "54" - }, - { - "label": "Волоф", - "value": "55" - }, - { - "label": "Вьетнамский", - "value": "57" - }, - { - "label": "Гавайский", - "value": "58" - }, - { - "label": "Гаитянский", - "value": "59" - }, - { - "label": "Галисийский", - "value": "60" - }, - { - "label": "Гереро", - "value": "61" - }, - { - "label": "Голландский", - "value": "62" - }, - { - "label": "Греческий", - "value": "63" - }, - { - "label": "Грузинский", - "value": "64" - }, - { - "label": "Гуарани", - "value": "65" - }, - { - "label": "Гуджарати", - "value": "66" - }, - { - "label": "Датский", - "value": "19" - }, - { - "label": "Дзонг-кэ", - "value": "68" - }, - { - "label": "Древнегреческий", - "value": "69" - }, - { - "label": "Западно-фламандский", - "value": "70" - }, - { - "label": "Зулу", - "value": "71" - }, - { - "label": "Иврит", - "value": "15" - }, - { - "label": "Игбо", - "value": "72" - }, - { - "label": "Идиш", - "value": "73" - }, - { - "label": "Илоко", - "value": "74" - }, - { - "label": "Индонезийский", - "value": "75" - }, - { - "label": "Интерлингва", - "value": "76" - }, - { - "label": "Инуктитут", - "value": "77" - }, - { - "label": "Инупиак", - "value": "78" - }, - { - "label": "Ирландский", - "value": "79" - }, - { - "label": "Исландский", - "value": "80" - }, - { - "label": "Испанский", - "value": "6" - }, - { - "label": "Итальянский", - "value": "5" - }, - { - "label": "Йоруба", - "value": "81" - }, - { - "label": "Кабильский", - "value": "82" - }, - { - "label": "Казахский", - "value": "83" - }, - { - "label": "Калмыцкий", - "value": "235" - }, - { - "label": "Каннада", - "value": "84" - }, - { - "label": "Кантонский юэ", - "value": "85" - }, - { - "label": "Канури", - "value": "86" - }, - { - "label": "Каталанский", - "value": "87" - }, - { - "label": "Кашмири", - "value": "88" - }, - { - "label": "Кечуа", - "value": "90" - }, - { - "label": "Кикуйю", - "value": "91" - }, - { - "label": "Киньяруанда", - "value": "92" - }, - { - "label": "Киргизский", - "value": "93" - }, - { - "label": "Китайский", - "value": "7" - }, - { - "label": "Клингонский", - "value": "94" - }, - { - "label": "Коми", - "value": "95" - }, - { - "label": "Конго", - "value": "96" - }, - { - "label": "Конкани", - "value": "97" - }, - { - "label": "Корейский", - "value": "98" - }, - { - "label": "Корсиканский", - "value": "100" - }, - { - "label": "Котава", - "value": "101" - }, - { - "label": "Кри", - "value": "102" - }, - { - "label": "Курдский", - "value": "105" - }, - { - "label": "Кхмерский", - "value": "107" - }, - { - "label": "Лакский", - "value": "233" - }, - { - "label": "Лаосский", - "value": "109" - }, - { - "label": "Латынь", - "value": "110" - }, - { - "label": "Латышский", - "value": "111" - }, - { - "label": "Лезгинский", - "value": "112" - }, - { - "label": "Лимбургский", - "value": "113" - }, - { - "label": "Лингала", - "value": "114" - }, - { - "label": "Литовский", - "value": "115" - }, - { - "label": "Луба", - "value": "118" - }, - { - "label": "Луганда", - "value": "119" - }, - { - "label": "Люксембургский", - "value": "120" - }, - { - "label": "Македонский", - "value": "121" - }, - { - "label": "Малагасийский", - "value": "122" - }, - { - "label": "Малайский", - "value": "123" - }, - { - "label": "Мальдивский", - "value": "125" - }, - { - "label": "Мальтийский", - "value": "126" - }, - { - "label": "Маори", - "value": "127" - }, - { - "label": "Марийский", - "value": "232" - }, - { - "label": "Маршалльский", - "value": "130" - }, - { - "label": "Молдавский", - "value": "11" - }, - { - "label": "Монгольский", - "value": "133" - }, - { - "label": "Мяо (хмонг)", - "value": "209" - }, - { - "label": "Навахо", - "value": "135" - }, - { - "label": "Неаполитанский", - "value": "139" - }, - { - "label": "Немецкий", - "value": "3" - }, - { - "label": "Непальский", - "value": "140" - }, - { - "label": "Норвежский", - "value": "18" - }, - { - "label": "Осетинский", - "value": "147" - }, - { - "label": "Пакистанский", - "value": "230" - }, - { - "label": "Пенджабский", - "value": "149" - }, - { - "label": "Персидский", - "value": "151" - }, - { - "label": "Польский", - "value": "152" - }, - { - "label": "Португальский", - "value": "153" - }, - { - "label": "Румынский", - "value": "158" - }, - { - "label": "Русский", - "value": "1" - }, - { - "label": "Санскрит", - "value": "163" - }, - { - "label": "Сардинский", - "value": "164" - }, - { - "label": "Сербохорватский", - "value": "166" - }, - { - "label": "Словацкий", - "value": "170" - }, - { - "label": "Словенский", - "value": "171" - }, - { - "label": "Сомали", - "value": "172" - }, - { - "label": "Старотурецкий", - "value": "174" - }, - { - "label": "Суахили", - "value": "175" - }, - { - "label": "Сунданский", - "value": "176" - }, - { - "label": "Тагальский", - "value": "177" - }, - { - "label": "Таджикский", - "value": "178" - }, - { - "label": "Таитянский", - "value": "179" - }, - { - "label": "Тайваньский", - "value": "180" - }, - { - "label": "Тайский", - "value": "181" - }, - { - "label": "Тамильский", - "value": "182" - }, - { - "label": "Татарский", - "value": "12" - }, - { - "label": "Телугу", - "value": "184" - }, - { - "label": "Тибетский", - "value": "185" - }, - { - "label": "Тигринья", - "value": "186" - }, - { - "label": "Ток-писин", - "value": "187" - }, - { - "label": "Токи пона", - "value": "188" - }, - { - "label": "Тонганский", - "value": "189" - }, - { - "label": "Тсвана", - "value": "191" - }, - { - "label": "Тсонга", - "value": "192" - }, - { - "label": "Турецкий", - "value": "193" - }, - { - "label": "Туркменский", - "value": "194" - }, - { - "label": "Удмуртский", - "value": "196" - }, - { - "label": "Узбекский", - "value": "197" - }, - { - "label": "Уйгурский", - "value": "198" - }, - { - "label": "Украинский", - "value": "9" - }, - { - "label": "Фиджийский", - "value": "201" - }, - { - "label": "Филиппинский", - "value": "229" - }, - { - "label": "Финский", - "value": "17" - }, - { - "label": "Французский", - "value": "4" - }, - { - "label": "Фризский", - "value": "203" - }, - { - "label": "Фулах", - "value": "204" - }, - { - "label": "Хауса", - "value": "206" - }, - { - "label": "Хинди", - "value": "207" - }, - { - "label": "Хири-моту", - "value": "208" - }, - { - "label": "Чеченский", - "value": "213" - }, - { - "label": "Чешский", - "value": "13" - }, - { - "label": "Чувашский", - "value": "217" - }, - { - "label": "Шведский", - "value": "16" - }, - { - "label": "Швейцарский немецкий", - "value": "218" - }, - { - "label": "Шона", - "value": "219" - }, - { - "label": "Шотландский", - "value": "67" - }, - { - "label": "Эве", - "value": "221" - }, - { - "label": "Эскимосский", - "value": "223" - }, - { - "label": "Эсперанто", - "value": "14" - }, - { - "label": "Эстонский", - "value": "224" - }, - { - "label": "Южно-корейский", - "value": "231" - }, - { - "label": "Юкатекский", - "value": "225" - }, - { - "label": "Яванский", - "value": "227" - }, - { - "label": "Японский", - "value": "8" - } - ], - "inputType": "Picker" - }, - { - "key": "t_lang", - "label": "Язык перевода:", - "values": [ - { - "label": "Неважно", - "value": "0" - }, - { - "label": "Абхазский", - "value": "20" - }, - { - "label": "Аварский", - "value": "21" - }, - { - "label": "Азербайджанский", - "value": "22" - }, - { - "label": "Аймара", - "value": "23" - }, - { - "label": "Акан", - "value": "24" - }, - { - "label": "Албанский", - "value": "25" - }, - { - "label": "Амхарский", - "value": "26" - }, - { - "label": "Английский", - "value": "2" - }, - { - "label": "Арабский", - "value": "27" - }, - { - "label": "Арагонский", - "value": "28" - }, - { - "label": "Арберешский", - "value": "29" - }, - { - "label": "Армянский", - "value": "30" - }, - { - "label": "Ассамский", - "value": "31" - }, - { - "label": "Астурийский", - "value": "32" - }, - { - "label": "Афарский", - "value": "33" - }, - { - "label": "Африкаанс", - "value": "34" - }, - { - "label": "Ацтекский", - "value": "35" - }, - { - "label": "Баварский", - "value": "36" - }, - { - "label": "Бамбарийский", - "value": "37" - }, - { - "label": "Баскский", - "value": "39" - }, - { - "label": "Башкирский", - "value": "40" - }, - { - "label": "Белорусский", - "value": "10" - }, - { - "label": "Бенгальский", - "value": "41" - }, - { - "label": "Бирманский", - "value": "42" - }, - { - "label": "Бислама", - "value": "43" - }, - { - "label": "Бихари", - "value": "44" - }, - { - "label": "Болгарский", - "value": "45" - }, - { - "label": "Боснийский", - "value": "234" - }, - { - "label": "Бретонский", - "value": "47" - }, - { - "label": "Валенсийский", - "value": "48" - }, - { - "label": "Валлийский", - "value": "49" - }, - { - "label": "Валлонский", - "value": "50" - }, - { - "label": "Венгерский", - "value": "51" - }, - { - "label": "Венда", - "value": "52" - }, - { - "label": "Венетский", - "value": "53" - }, - { - "label": "Верхнелужицкий", - "value": "54" - }, - { - "label": "Волоф", - "value": "55" - }, - { - "label": "Вьетнамский", - "value": "57" - }, - { - "label": "Гавайский", - "value": "58" - }, - { - "label": "Гаитянский", - "value": "59" - }, - { - "label": "Галисийский", - "value": "60" - }, - { - "label": "Гереро", - "value": "61" - }, - { - "label": "Голландский", - "value": "62" - }, - { - "label": "Греческий", - "value": "63" - }, - { - "label": "Грузинский", - "value": "64" - }, - { - "label": "Гуарани", - "value": "65" - }, - { - "label": "Гуджарати", - "value": "66" - }, - { - "label": "Датский", - "value": "19" - }, - { - "label": "Дзонг-кэ", - "value": "68" - }, - { - "label": "Древнегреческий", - "value": "69" - }, - { - "label": "Западно-фламандский", - "value": "70" - }, - { - "label": "Зулу", - "value": "71" - }, - { - "label": "Иврит", - "value": "15" - }, - { - "label": "Игбо", - "value": "72" - }, - { - "label": "Идиш", - "value": "73" - }, - { - "label": "Илоко", - "value": "74" - }, - { - "label": "Индонезийский", - "value": "75" - }, - { - "label": "Интерлингва", - "value": "76" - }, - { - "label": "Инуктитут", - "value": "77" - }, - { - "label": "Инупиак", - "value": "78" - }, - { - "label": "Ирландский", - "value": "79" - }, - { - "label": "Исландский", - "value": "80" - }, - { - "label": "Испанский", - "value": "6" - }, - { - "label": "Итальянский", - "value": "5" - }, - { - "label": "Йоруба", - "value": "81" - }, - { - "label": "Кабильский", - "value": "82" - }, - { - "label": "Казахский", - "value": "83" - }, - { - "label": "Калмыцкий", - "value": "235" - }, - { - "label": "Каннада", - "value": "84" - }, - { - "label": "Кантонский юэ", - "value": "85" - }, - { - "label": "Канури", - "value": "86" - }, - { - "label": "Каталанский", - "value": "87" - }, - { - "label": "Кашмири", - "value": "88" - }, - { - "label": "Кечуа", - "value": "90" - }, - { - "label": "Кикуйю", - "value": "91" - }, - { - "label": "Киньяруанда", - "value": "92" - }, - { - "label": "Киргизский", - "value": "93" - }, - { - "label": "Китайский", - "value": "7" - }, - { - "label": "Клингонский", - "value": "94" - }, - { - "label": "Коми", - "value": "95" - }, - { - "label": "Конго", - "value": "96" - }, - { - "label": "Конкани", - "value": "97" - }, - { - "label": "Корейский", - "value": "98" - }, - { - "label": "Корсиканский", - "value": "100" - }, - { - "label": "Котава", - "value": "101" - }, - { - "label": "Кри", - "value": "102" - }, - { - "label": "Курдский", - "value": "105" - }, - { - "label": "Кхмерский", - "value": "107" - }, - { - "label": "Лакский", - "value": "233" - }, - { - "label": "Лаосский", - "value": "109" - }, - { - "label": "Латынь", - "value": "110" - }, - { - "label": "Латышский", - "value": "111" - }, - { - "label": "Лезгинский", - "value": "112" - }, - { - "label": "Лимбургский", - "value": "113" - }, - { - "label": "Лингала", - "value": "114" - }, - { - "label": "Литовский", - "value": "115" - }, - { - "label": "Луба", - "value": "118" - }, - { - "label": "Луганда", - "value": "119" - }, - { - "label": "Люксембургский", - "value": "120" - }, - { - "label": "Македонский", - "value": "121" - }, - { - "label": "Малагасийский", - "value": "122" - }, - { - "label": "Малайский", - "value": "123" - }, - { - "label": "Мальдивский", - "value": "125" - }, - { - "label": "Мальтийский", - "value": "126" - }, - { - "label": "Маори", - "value": "127" - }, - { - "label": "Марийский", - "value": "232" - }, - { - "label": "Маршалльский", - "value": "130" - }, - { - "label": "Молдавский", - "value": "11" - }, - { - "label": "Монгольский", - "value": "133" - }, - { - "label": "Мяо (хмонг)", - "value": "209" - }, - { - "label": "Навахо", - "value": "135" - }, - { - "label": "Неаполитанский", - "value": "139" - }, - { - "label": "Немецкий", - "value": "3" - }, - { - "label": "Непальский", - "value": "140" - }, - { - "label": "Норвежский", - "value": "18" - }, - { - "label": "Осетинский", - "value": "147" - }, - { - "label": "Пакистанский", - "value": "230" - }, - { - "label": "Пенджабский", - "value": "149" - }, - { - "label": "Персидский", - "value": "151" - }, - { - "label": "Польский", - "value": "152" - }, - { - "label": "Португальский", - "value": "153" - }, - { - "label": "Румынский", - "value": "158" - }, - { - "label": "Русский", - "value": "1" - }, - { - "label": "Санскрит", - "value": "163" - }, - { - "label": "Сардинский", - "value": "164" - }, - { - "label": "Сербохорватский", - "value": "166" - }, - { - "label": "Словацкий", - "value": "170" - }, - { - "label": "Словенский", - "value": "171" - }, - { - "label": "Сомали", - "value": "172" - }, - { - "label": "Старотурецкий", - "value": "174" - }, - { - "label": "Суахили", - "value": "175" - }, - { - "label": "Сунданский", - "value": "176" - }, - { - "label": "Тагальский", - "value": "177" - }, - { - "label": "Таджикский", - "value": "178" - }, - { - "label": "Таитянский", - "value": "179" - }, - { - "label": "Тайваньский", - "value": "180" - }, - { - "label": "Тайский", - "value": "181" - }, - { - "label": "Тамильский", - "value": "182" - }, - { - "label": "Татарский", - "value": "12" - }, - { - "label": "Телугу", - "value": "184" - }, - { - "label": "Тибетский", - "value": "185" - }, - { - "label": "Тигринья", - "value": "186" - }, - { - "label": "Ток-писин", - "value": "187" - }, - { - "label": "Токи пона", - "value": "188" - }, - { - "label": "Тонганский", - "value": "189" - }, - { - "label": "Тсвана", - "value": "191" - }, - { - "label": "Тсонга", - "value": "192" - }, - { - "label": "Турецкий", - "value": "193" - }, - { - "label": "Туркменский", - "value": "194" - }, - { - "label": "Удмуртский", - "value": "196" - }, - { - "label": "Узбекский", - "value": "197" - }, - { - "label": "Уйгурский", - "value": "198" - }, - { - "label": "Украинский", - "value": "9" - }, - { - "label": "Фиджийский", - "value": "201" - }, - { - "label": "Филиппинский", - "value": "229" - }, - { - "label": "Финский", - "value": "17" - }, - { - "label": "Французский", - "value": "4" - }, - { - "label": "Фризский", - "value": "203" - }, - { - "label": "Фулах", - "value": "204" - }, - { - "label": "Хауса", - "value": "206" - }, - { - "label": "Хинди", - "value": "207" - }, - { - "label": "Хири-моту", - "value": "208" - }, - { - "label": "Чеченский", - "value": "213" - }, - { - "label": "Чешский", - "value": "13" - }, - { - "label": "Чувашский", - "value": "217" - }, - { - "label": "Шведский", - "value": "16" - }, - { - "label": "Швейцарский немецкий", - "value": "218" - }, - { - "label": "Шона", - "value": "219" - }, - { - "label": "Шотландский", - "value": "67" - }, - { - "label": "Эве", - "value": "221" - }, - { - "label": "Эскимосский", - "value": "223" - }, - { - "label": "Эсперанто", - "value": "14" - }, - { - "label": "Эстонский", - "value": "224" - }, - { - "label": "Южно-корейский", - "value": "231" - }, - { - "label": "Юкатекский", - "value": "225" - }, - { - "label": "Яванский", - "value": "227" - }, - { - "label": "Японский", - "value": "8" - } - ], - "inputType": "Picker" - }, - { - "key": "type", - "label": "Тип:", - "values": [ - { - "label": "Неважно", - "value": "0" - }, - { - "label": "Только авторские", - "value": "2" - }, - { - "label": "Только переводы", - "value": "1" - } - ], - "inputType": "Picker" - }, - { - "key": "trash", - "label": "Другое:", - "values": [ - { - "label": "Без фэндомов", - "value": "fandoms_ex_all" - }, - { - "label": "Готовые на 100%", - "value": "ready" - }, - { - "label": "Доступные для перевода", - "value": "tr" - }, - { - "label": "Доступные для скачивания", - "value": "gen" - }, - { - "label": "Завершённые проекты", - "value": "wealth" - }, - { - "label": "Распродажа", - "value": "discount" - }, - { - "label": "Только онгоинги", - "value": "ongoings" - }, - { - "label": "Убрать машинный", - "value": "remove_machinelate" - } - ], - "inputType": "Checkbox" - }, - { - "key": "sort", - "label": "Сортировка:", - "values": [ - { - "label": "По рейтингу", - "value": "6" - }, - { - "label": "По дате последней активности", - "value": "4" - }, - { - "label": "По дате создания", - "value": "3" - }, - { - "label": "По кол-ву бесплатных глав", - "value": "11" - }, - { - "label": "По кол-ву в закладках", - "value": "13" - }, - { - "label": "По кол-ву в избранном", - "value": "14" - }, - { - "label": "По кол-ву лайков", - "value": "8" - }, - { - "label": "По кол-ву переведённых глав", - "value": "7" - }, - { - "label": "По кол-ву рецензий", - "value": "12" - }, - { - "label": "По кол-ву страниц", - "value": "10" - }, - { - "label": "По названию на языке оригинала", - "value": "1" - }, - { - "label": "По названию на языке перевода", - "value": "2" - }, - { - "label": "По просмотрам", - "value": "5" - }, - { - "label": "По степени готовности", - "value": "0" - }, - { - "label": "Случайно", - "value": "9" - } - ], - "inputType": "Picker" - }, - { - "key": "genres", - "label": "Жанры:", - "values": [ - { - "label": "18+", - "value": "52" - }, - { - "label": "Арт", - "value": "1" - }, - { - "label": "Боевик", - "value": "2" - }, - { - "label": "Боевые искусства", - "value": "3" - }, - { - "label": "Гаремник", - "value": "5" - }, - { - "label": "Героическое фэнтези", - "value": "7" - }, - { - "label": "Детектив", - "value": "8" - }, - { - "label": "Дзёсэй", - "value": "9" - }, - { - "label": "Додзинси", - "value": "10" - }, - { - "label": "Драма", - "value": "11" - }, - { - "label": "История", - "value": "13" - }, - { - "label": "Киберпанк", - "value": "46" - }, - { - "label": "Кодомо", - "value": "14" - }, - { - "label": "Комедия", - "value": "15" - }, - { - "label": "Литрпг", - "value": "48" - }, - { - "label": "Махо-сёдзё", - "value": "16" - }, - { - "label": "Мелодрама", - "value": "49" - }, - { - "label": "Меха", - "value": "17" - }, - { - "label": "Мистика", - "value": "18" - }, - { - "label": "Научная фантастика", - "value": "19" - }, - { - "label": "Повседневность", - "value": "20" - }, - { - "label": "Постапокалиптика", - "value": "21" - }, - { - "label": "Приключения", - "value": "22" - }, - { - "label": "Психология", - "value": "23" - }, - { - "label": "Романтика", - "value": "24" - }, - { - "label": "Самурайский боевик", - "value": "25" - }, - { - "label": "Сверхъестественное", - "value": "26" - }, - { - "label": "Сёдзё", - "value": "27" - }, - { - "label": "Сёнэн", - "value": "29" - }, - { - "label": "Смат", - "value": "45" - }, - { - "label": "Спорт", - "value": "31" - }, - { - "label": "Сэйнэн", - "value": "32" - }, - { - "label": "Сюаньхуа", - "value": "44" - }, - { - "label": "Сюаньхуань", - "value": "47" - }, - { - "label": "Сянься (XianXia)", - "value": "42" - }, - { - "label": "Трагедия", - "value": "33" - }, - { - "label": "Триллер", - "value": "34" - }, - { - "label": "Ужасы", - "value": "35" - }, - { - "label": "Уся (wuxia)", - "value": "41" - }, - { - "label": "Фантастика", - "value": "36" - }, - { - "label": "Фанфик", - "value": "50" - }, - { - "label": "Фэнтези", - "value": "37" - }, - { - "label": "Школа", - "value": "38" - }, - { - "label": "Этти", - "value": "39" - }, - { - "label": "Bl", - "value": "43" - }, - { - "label": "Gl", - "value": "40" - } - ], - "inputType": "Checkbox" - }, - { - "key": "tags", - "label": "Тэги:", - "values": [ - { - "label": "12+", - "value": "3316" - }, - { - "label": "16+", - "value": "83" - }, - { - "label": "Абсурд", - "value": "7973" - }, - { - "label": "Авантюристы", - "value": "222" - }, - { - "label": "Автомат", - "value": "5272" - }, - { - "label": "Авторский мир", - "value": "1062" - }, - { - "label": "Агрессивные персонажи", - "value": "3249" - }, - { - "label": "Ад", - "value": "2623" - }, - { - "label": "Ад и рай", - "value": "817" - }, - { - "label": "Адам дженсен", - "value": "1649" - }, - { - "label": "Адаптация произведения", - "value": "192" - }, - { - "label": "Адвокат", - "value": "6340" - }, - { - "label": "Адекватные главные герои", - "value": "1953" - }, - { - "label": "Азартные игры", - "value": "5301" - }, - { - "label": "Азгард", - "value": "3494" - }, - { - "label": "Азула", - "value": "5550" - }, - { - "label": "Аид", - "value": "7641" - }, - { - "label": "Айдолы", - "value": "4081" - }, - { - "label": "Академия", - "value": "316" - }, - { - "label": "Акамэ", - "value": "5059" - }, - { - "label": "Аквакинез", - "value": "5952" - }, - { - "label": "Акира", - "value": "2639" - }, - { - "label": "Акнология", - "value": "4634" - }, - { - "label": "Актерское мастерство", - "value": "4798" - }, - { - "label": "Актёры", - "value": "7506" - }, - { - "label": "Активные герои", - "value": "6376" - }, - { - "label": "Акутагава рюноске", - "value": "4113" - }, - { - "label": "Аладдин", - "value": "6489" - }, - { - "label": "Алая ведьма", - "value": "4767" - }, - { - "label": "Алиса", - "value": "4761" - }, - { - "label": "Алкоголь", - "value": "5508" - }, - { - "label": "Аллегория", - "value": "271" - }, - { - "label": "Алукард", - "value": "4914" - }, - { - "label": "Алхимики", - "value": "1164" - }, - { - "label": "Алхимия", - "value": "1473" - }, - { - "label": "Алчность", - "value": "6897" - }, - { - "label": "Альбус дамблдор", - "value": "5784" - }, - { - "label": "Альтернативное развитие событий", - "value": "5330" - }, - { - "label": "Альянсы", - "value": "328" - }, - { - "label": "Амбициозный главный герой", - "value": "3751" - }, - { - "label": "Америка", - "value": "4082" - }, - { - "label": "Амнезия", - "value": "2207" - }, - { - "label": "Аморальный герой", - "value": "18" - }, - { - "label": "Анбу", - "value": "8129" - }, - { - "label": "Ангелы", - "value": "857" - }, - { - "label": "Ангелы и демоны", - "value": "1327" - }, - { - "label": "Ангст", - "value": "4638" - }, - { - "label": "Андроиды", - "value": "1993" - }, - { - "label": "Анимализм", - "value": "5249" - }, - { - "label": "Аниме", - "value": "1294" - }, - { - "label": "Анко митараши", - "value": "5768" - }, - { - "label": "Антагонист", - "value": "2144" - }, - { - "label": "Антигерой", - "value": "7725" - }, - { - "label": "Антиквариат", - "value": "3552" - }, - { - "label": "Антимаг", - "value": "1348" - }, - { - "label": "Антиутопия", - "value": "662" - }, - { - "label": "Апокалипсис", - "value": "1498" - }, - { - "label": "Аристократия", - "value": "371" - }, - { - "label": "Аристократы", - "value": "7338" - }, - { - "label": "Армия", - "value": "1723" - }, - { - "label": "Артас", - "value": "6700" - }, - { - "label": "Артефакты", - "value": "2296" - }, - { - "label": "Археология", - "value": "6523" - }, - { - "label": "Асгард", - "value": "3635" - }, - { - "label": "Ассасин", - "value": "1415" - }, - { - "label": "Асуна", - "value": "5044" - }, - { - "label": "Аугментации", - "value": "7751" - }, - { - "label": "Ацуши накаджима", - "value": "4109" - }, - { - "label": "Аянокоджи киетака", - "value": "6862" - }, - { - "label": "Бандиты", - "value": "2188" - }, - { - "label": "Басейн", - "value": "6847" - }, - { - "label": "Баскетбол", - "value": "7933" - }, - { - "label": "Бастарды", - "value": "76" - }, - { - "label": "Бедность", - "value": "1207" - }, - { - "label": "Без культивации", - "value": "668" - }, - { - "label": "Без любовной линий", - "value": "2225" - }, - { - "label": "Без перерождений", - "value": "262" - }, - { - "label": "Без попаданца", - "value": "8065" - }, - { - "label": "Без системы", - "value": "747" - }, - { - "label": "Без юмора", - "value": "763" - }, - { - "label": "Бездна", - "value": "1026" - }, - { - "label": "Безжалостное домашнее животное", - "value": "1245" - }, - { - "label": "Безжалостные персонажи", - "value": "2986" - }, - { - "label": "Беззаботные персонажи", - "value": "3123" - }, - { - "label": "Безответная любовь", - "value": "7815" - }, - { - "label": "Безработный", - "value": "2202" - }, - { - "label": "Безумие", - "value": "37" - }, - { - "label": "Безумные персонажи", - "value": "2049" - }, - { - "label": "Бейсбол", - "value": "7623" - }, - { - "label": "Беременность", - "value": "2122" - }, - { - "label": "Бесконечный поток", - "value": "7556" - }, - { - "label": "Беспечные персонажи", - "value": "742" - }, - { - "label": "Бесплатно", - "value": "8403" - }, - { - "label": "Бессмертные персонажи", - "value": "566" - }, - { - "label": "Бесстрашные персонажи", - "value": "6921" - }, - { - "label": "Бесстыдные персонажи", - "value": "1257" - }, - { - "label": "Бесстыдный главный герой", - "value": "8190" - }, - { - "label": "Библиотека", - "value": "4210" - }, - { - "label": "Библия", - "value": "488" - }, - { - "label": "Бизнес", - "value": "704" - }, - { - "label": "Биология", - "value": "2220" - }, - { - "label": "Биомехи", - "value": "1968" - }, - { - "label": "Биседзе", - "value": "777" - }, - { - "label": "Битва за веру", - "value": "721" - }, - { - "label": "Битва за трон", - "value": "7211" - }, - { - "label": "Битва королевств", - "value": "1151" - }, - { - "label": "Битва рас", - "value": "6989" - }, - { - "label": "Битвы", - "value": "1740" - }, - { - "label": "Благородные персонажи", - "value": "2201" - }, - { - "label": "Близнецы", - "value": "2931" - }, - { - "label": "Богатство", - "value": "6522" - }, - { - "label": "Богатые персонажи", - "value": "520" - }, - { - "label": "Боги", - "value": "173" - }, - { - "label": "Богини", - "value": "30" - }, - { - "label": "Богиня", - "value": "8324" - }, - { - "label": "Богоубийца", - "value": "1253" - }, - { - "label": "Богохульство", - "value": "95" - }, - { - "label": "Боевая академия", - "value": "2108" - }, - { - "label": "Большая грудь", - "value": "4717" - }, - { - "label": "Борос", - "value": "6533" - }, - { - "label": "Борьба", - "value": "1925" - }, - { - "label": "Борьба за власть", - "value": "8072" - }, - { - "label": "Босс и подчиненный", - "value": "7157" - }, - { - "label": "Бояръ", - "value": "2307" - }, - { - "label": "Брак", - "value": "1558" - }, - { - "label": "Брак по расчету", - "value": "1389" - }, - { - "label": "Брат и сестра", - "value": "615" - }, - { - "label": "Братский комплекс", - "value": "2321" - }, - { - "label": "Броманс", - "value": "1103" - }, - { - "label": "Брошенные дети", - "value": "2846" - }, - { - "label": "Буддизм", - "value": "1871" - }, - { - "label": "Будущее", - "value": "1820" - }, - { - "label": "Бывший муж", - "value": "8080" - }, - { - "label": "Быстрое развитие", - "value": "1443" - }, - { - "label": "Бэтгерл", - "value": "2584" - }, - { - "label": "Бэтмен", - "value": "4668" - }, - { - "label": "В первый раз", - "value": "6212" - }, - { - "label": "В этот же мир", - "value": "49" - }, - { - "label": "Ваканда", - "value": "8331" - }, - { - "label": "Валькирии", - "value": "4047" - }, - { - "label": "Вампиры", - "value": "2206" - }, - { - "label": "Веб камера", - "value": "5664" - }, - { - "label": "Веб новелла", - "value": "2349" - }, - { - "label": "Ведьмак", - "value": "843" - }, - { - "label": "Ведьмы", - "value": "643" - }, - { - "label": "Везучие персонажи", - "value": "1879" - }, - { - "label": "Веном", - "value": "3994" - }, - { - "label": "Вестерн", - "value": "2131" - }, - { - "label": "Вестерос", - "value": "8171" - }, - { - "label": "Взросление", - "value": "624" - }, - { - "label": "Взрослый главный герой", - "value": "2416" - }, - { - "label": "Видео игры", - "value": "2630" - }, - { - "label": "Викинги", - "value": "267" - }, - { - "label": "Вино", - "value": "6972" - }, - { - "label": "Вирт", - "value": "6213" - }, - { - "label": "Виртуальная реальность", - "value": "325" - }, - { - "label": "Вирусы", - "value": "3327" - }, - { - "label": "Владыка демонов", - "value": "555" - }, - { - "label": "Власть", - "value": "756" - }, - { - "label": "Влюбленность", - "value": "6132" - }, - { - "label": "Внешний вид отличается от личности", - "value": "1938" - }, - { - "label": "Внучка", - "value": "8399" - }, - { - "label": "Военные", - "value": "1096" - }, - { - "label": "Возрождение", - "value": "1160" - }, - { - "label": "Воины", - "value": "287" - }, - { - "label": "Война", - "value": "443" - }, - { - "label": "Войны", - "value": "2431" - }, - { - "label": "Воландеморт", - "value": "4278" - }, - { - "label": "Волейбол", - "value": "6415" - }, - { - "label": "Волки", - "value": "1166" - }, - { - "label": "Волшебники", - "value": "122" - }, - { - "label": "Волшебные существа", - "value": "1689" - }, - { - "label": "Волшебство", - "value": "719" - }, - { - "label": "Вор", - "value": "1399" - }, - { - "label": "Воровка", - "value": "6948" - }, - { - "label": "Ворон", - "value": "848" - }, - { - "label": "Воскрешение", - "value": "6915" - }, - { - "label": "Воспоминания из другого мира", - "value": "1366" - }, - { - "label": "Воспоминания из прошлого", - "value": "1372" - }, - { - "label": "Воссоединие семьи", - "value": "8130" - }, - { - "label": "Восхождение", - "value": "380" - }, - { - "label": "Враги становятся любовниками", - "value": "978" - }, - { - "label": "Врата", - "value": "40" - }, - { - "label": "Врата в другой мир", - "value": "1957" - }, - { - "label": "Врач", - "value": "1243" - }, - { - "label": "Временная петля", - "value": "2852" - }, - { - "label": "Врмморпг", - "value": "2043" - }, - { - "label": "Все дозволено", - "value": "96" - }, - { - "label": "Всемогущий главный герой", - "value": "1414" - }, - { - "label": "Второй шанс", - "value": "2372" - }, - { - "label": "Вуайеризм", - "value": "2498" - }, - { - "label": "Выживание", - "value": "501" - }, - { - "label": "Вымышленные существа", - "value": "3466" - }, - { - "label": "Вынужденный брак", - "value": "7705" - }, - { - "label": "Высокие технологии", - "value": "653" - }, - { - "label": "Высокомерные персонажи", - "value": "3250" - }, - { - "label": "Галустян", - "value": "5199" - }, - { - "label": "Гангстеры", - "value": "7704" - }, - { - "label": "Гарем", - "value": "440" - }, - { - "label": "Гарри поттер", - "value": "226" - }, - { - "label": "Геймеры", - "value": "2130" - }, - { - "label": "Генетические модификации", - "value": "1750" - }, - { - "label": "Гениальный главный герой", - "value": "1500" - }, - { - "label": "Гений", - "value": "1650" - }, - { - "label": "Гермиона грейнджер", - "value": "4280" - }, - { - "label": "Герои", - "value": "185" - }, - { - "label": "Гигаполис", - "value": "8393" - }, - { - "label": "Гильгамеш", - "value": "6031" - }, - { - "label": "Гильдии", - "value": "900" - }, - { - "label": "Гильдия авантюристов", - "value": "1858" - }, - { - "label": "Гинтама", - "value": "4544" - }, - { - "label": "Гипноз", - "value": "358" - }, - { - "label": "Главная героиня влюбляется первой", - "value": "973" - }, - { - "label": "Главный герой бог", - "value": "164" - }, - { - "label": "Главный герой влюбляется первым", - "value": "3629" - }, - { - "label": "Главный герой выживальщик", - "value": "120" - }, - { - "label": "Главный герой гонг", - "value": "7877" - }, - { - "label": "Главный герой девушка", - "value": "257" - }, - { - "label": "Главный герой демон", - "value": "136" - }, - { - "label": "Главный герой женщина", - "value": "7329" - }, - { - "label": "Главный герой жестокий", - "value": "1553" - }, - { - "label": "Главный герой извращенец", - "value": "94" - }, - { - "label": "Главный герой имба", - "value": "2421" - }, - { - "label": "Главный герой киборг", - "value": "7780" - }, - { - "label": "Главный герой монстр", - "value": "869" - }, - { - "label": "Главный герой мужчина", - "value": "1997" - }, - { - "label": "Главный герой на стороне сил зла", - "value": "1514" - }, - { - "label": "Главный герой не адекватный", - "value": "5" - }, - { - "label": "Главный герой не психопат", - "value": "7804" - }, - { - "label": "Главный герой не человек", - "value": "2172" - }, - { - "label": "Главный герой не эмоционален", - "value": "1150" - }, - { - "label": "Главный герой подросток", - "value": "2215" - }, - { - "label": "Главный герой позитивный", - "value": "7787" - }, - { - "label": "Главный герой психопат", - "value": "7803" - }, - { - "label": "Главный герой ребенок", - "value": "2347" - }, - { - "label": "Главный герой русский", - "value": "2417" - }, - { - "label": "Главный герой сильный с самого начала", - "value": "88" - }, - { - "label": "Главный герой скрывает свою силу", - "value": "1059" - }, - { - "label": "Главный герой эгоист", - "value": "8326" - }, - { - "label": "Гномы", - "value": "1870" - }, - { - "label": "Гоблины", - "value": "2029" - }, - { - "label": "Годзилла", - "value": "6990" - }, - { - "label": "Големы", - "value": "1690" - }, - { - "label": "Голливуд", - "value": "7754" - }, - { - "label": "Головоломка", - "value": "1697" - }, - { - "label": "Горничные", - "value": "8091" - }, - { - "label": "Гробница", - "value": "388" - }, - { - "label": "Дазай осаму", - "value": "4112" - }, - { - "label": "Даньмэй", - "value": "3411" - }, - { - "label": "Даосизм", - "value": "258" - }, - { - "label": "Дарк соулс", - "value": "6057" - }, - { - "label": "Дарт вейдер", - "value": "6826" - }, - { - "label": "Дафна гринграсс", - "value": "5192" - }, - { - "label": "Дворяне", - "value": "7204" - }, - { - "label": "Девушки", - "value": "7668" - }, - { - "label": "Девушки монстры", - "value": "2231" - }, - { - "label": "Дедушка и внучка", - "value": "8400" - }, - { - "label": "Дейви джонс", - "value": "8061" - }, - { - "label": "Действие", - "value": "1425" - }, - { - "label": "Демон лорд", - "value": "153" - }, - { - "label": "Демонология", - "value": "2024" - }, - { - "label": "Демоны", - "value": "1406" - }, - { - "label": "Дети", - "value": "580" - }, - { - "label": "Джарвис", - "value": "933" - }, - { - "label": "Джедай", - "value": "4442" - }, - { - "label": "Джин", - "value": "4024" - }, - { - "label": "Джокер", - "value": "3351" - }, - { - "label": "Джон сноу", - "value": "7412" - }, - { - "label": "Джоффри баратеон", - "value": "3936" - }, - { - "label": "Дзесэй", - "value": "678" - }, - { - "label": "Дин винчестер", - "value": "6953" - }, - { - "label": "Династии", - "value": "2982" - }, - { - "label": "Динозавры", - "value": "3666" - }, - { - "label": "Директор", - "value": "1417" - }, - { - "label": "Для девушек", - "value": "1441" - }, - { - "label": "Дневник", - "value": "298" - }, - { - "label": "Добби", - "value": "6762" - }, - { - "label": "Добрый мир", - "value": "1685" - }, - { - "label": "Договоры с богами", - "value": "2152" - }, - { - "label": "Договоры с демонами", - "value": "1922" - }, - { - "label": "Доктор", - "value": "1991" - }, - { - "label": "Доктор стрэндж", - "value": "7634" - }, - { - "label": "Доминирование", - "value": "2054" - }, - { - "label": "Дота", - "value": "6965" - }, - { - "label": "Доудзюцу", - "value": "7133" - }, - { - "label": "Дочь", - "value": "3291" - }, - { - "label": "Драко малфой", - "value": "46" - }, - { - "label": "Драконы", - "value": "282" - }, - { - "label": "Драконы оборотни", - "value": "8082" - }, - { - "label": "Древние времена", - "value": "7781" - }, - { - "label": "Древний египет", - "value": "7614" - }, - { - "label": "Древний китай", - "value": "473" - }, - { - "label": "Древний мир", - "value": "4" - }, - { - "label": "Другая вселенная", - "value": "39" - }, - { - "label": "Другие планеты", - "value": "2371" - }, - { - "label": "Другой мир", - "value": "2248" - }, - { - "label": "Дружба", - "value": "1903" - }, - { - "label": "Друзья детства", - "value": "1153" - }, - { - "label": "Духи", - "value": "114" - }, - { - "label": "Духовные силы", - "value": "1955" - }, - { - "label": "Души", - "value": "1212" - }, - { - "label": "Дьявол", - "value": "1094" - }, - { - "label": "Дьявольские фрукты", - "value": "1564" - }, - { - "label": "Дэдпул", - "value": "4399" - }, - { - "label": "Евнух", - "value": "6293" - }, - { - "label": "Европейская атмосфера", - "value": "5837" - }, - { - "label": "Египет", - "value": "528" - }, - { - "label": "Еда", - "value": "2056" - }, - { - "label": "Единороги", - "value": "437" - }, - { - "label": "Екаи", - "value": "655" - }, - { - "label": "Жалкий главный герой", - "value": "97" - }, - { - "label": "Жена", - "value": "5729" - }, - { - "label": "Женское доминирование", - "value": "4622" - }, - { - "label": "Женщина в теле мужчины", - "value": "2748" - }, - { - "label": "Женщина кошка", - "value": "7513" - }, - { - "label": "Жестокие персонажи", - "value": "3153" - }, - { - "label": "Жестокий мир", - "value": "1532" - }, - { - "label": "Жестокость", - "value": "7880" - }, - { - "label": "Животные", - "value": "7488" - }, - { - "label": "Животные компаньоны", - "value": "2061" - }, - { - "label": "Жизнь и смерть", - "value": "2014" - }, - { - "label": "Жнец", - "value": "6288" - }, - { - "label": "Жойен рид", - "value": "3926" - }, - { - "label": "Заботливый главный герой", - "value": "338" - }, - { - "label": "Закалка тела", - "value": "148" - }, - { - "label": "Заклинания", - "value": "558" - }, - { - "label": "Заключенные", - "value": "3052" - }, - { - "label": "Занпакто", - "value": "1102" - }, - { - "label": "Запретная любовь", - "value": "8033" - }, - { - "label": "Запутанный сюжет", - "value": "1041" - }, - { - "label": "Захват мира", - "value": "315" - }, - { - "label": "Зачарованные", - "value": "4169" - }, - { - "label": "Звери", - "value": "1638" - }, - { - "label": "Зверодевочки", - "value": "2006" - }, - { - "label": "Зверолюди", - "value": "1018" - }, - { - "label": "Земля", - "value": "82" - }, - { - "label": "Злая организация", - "value": "7768" - }, - { - "label": "Зло", - "value": "1512" - }, - { - "label": "Злодей", - "value": "1060" - }, - { - "label": "Злодейка", - "value": "2376" - }, - { - "label": "Злой главный герой", - "value": "616" - }, - { - "label": "Злые боги", - "value": "7109" - }, - { - "label": "Злые персонажи", - "value": "3243" - }, - { - "label": "Змей", - "value": "5721" - }, - { - "label": "Знаменитости", - "value": "1341" - }, - { - "label": "Знание медицины", - "value": "1411" - }, - { - "label": "Золушка", - "value": "2980" - }, - { - "label": "Зомби", - "value": "1743" - }, - { - "label": "Зомби апокалипсис", - "value": "912" - }, - { - "label": "Зона 51", - "value": "3051" - }, - { - "label": "Зооморфы", - "value": "375" - }, - { - "label": "Зорро", - "value": "6736" - }, - { - "label": "Зрелые женщины", - "value": "1458" - }, - { - "label": "Игра", - "value": "663" - }, - { - "label": "Игра на выживание", - "value": "2182" - }, - { - "label": "Игровая система", - "value": "384" - }, - { - "label": "Игровые элементы", - "value": "720" - }, - { - "label": "Извращения", - "value": "651" - }, - { - "label": "Измена", - "value": "1874" - }, - { - "label": "Изменение характера", - "value": "1113" - }, - { - "label": "Изменения внешности", - "value": "259" - }, - { - "label": "Изменения личности", - "value": "1080" - }, - { - "label": "Изобретения", - "value": "126" - }, - { - "label": "Изуку мидория", - "value": "6967" - }, - { - "label": "Император", - "value": "867" - }, - { - "label": "Империи", - "value": "712" - }, - { - "label": "Империя", - "value": "1716" - }, - { - "label": "Инвалидность", - "value": "2073" - }, - { - "label": "Инквизитор", - "value": "143" - }, - { - "label": "Инкуб", - "value": "3264" - }, - { - "label": "Инопланетное вторжение", - "value": "209" - }, - { - "label": "Инопланетяне", - "value": "866" - }, - { - "label": "Интерактив с читателями", - "value": "472" - }, - { - "label": "Интересный сюжет", - "value": "7374" - }, - { - "label": "Интернет", - "value": "739" - }, - { - "label": "Интимные сцены", - "value": "3450" - }, - { - "label": "Интрига", - "value": "317" - }, - { - "label": "Интриги и заговоры", - "value": "1009" - }, - { - "label": "Иные миры", - "value": "35" - }, - { - "label": "Исекай", - "value": "2979" - }, - { - "label": "Искусственный интеллект", - "value": "1900" - }, - { - "label": "Исследование", - "value": "1626" - }, - { - "label": "Исторический роман", - "value": "573" - }, - { - "label": "Итачи учиха", - "value": "4556" - }, - { - "label": "Ичиго", - "value": "7254" - }, - { - "label": "Йода", - "value": "6829" - }, - { - "label": "Йоруичи", - "value": "6755" - }, - { - "label": "Калипсо", - "value": "8062" - }, - { - "label": "Каннибализм", - "value": "2249" - }, - { - "label": "Капитан америка", - "value": "6301" - }, - { - "label": "Каракура", - "value": "7473" - }, - { - "label": "Карточная игра", - "value": "1557" - }, - { - "label": "Кастиэль", - "value": "6954" - }, - { - "label": "Кафе", - "value": "3934" - }, - { - "label": "Кацуки бакуго", - "value": "7696" - }, - { - "label": "Квесты", - "value": "1707" - }, - { - "label": "Киберспорт", - "value": "1984" - }, - { - "label": "Кино", - "value": "7126" - }, - { - "label": "Китай", - "value": "3762" - }, - { - "label": "Кицунэ", - "value": "241" - }, - { - "label": "Кланы", - "value": "834" - }, - { - "label": "Клоны", - "value": "1624" - }, - { - "label": "Книги", - "value": "1068" - }, - { - "label": "Книжный червь", - "value": "521" - }, - { - "label": "Колдовство", - "value": "2681" - }, - { - "label": "колледж", - "value": "5058" - }, - { - "label": "Коллекционер", - "value": "2588" - }, - { - "label": "Кольцо", - "value": "1628" - }, - { - "label": "Коммунисты", - "value": "1042" - }, - { - "label": "Коноха", - "value": "2827" - }, - { - "label": "Контракт", - "value": "4304" - }, - { - "label": "Контроль разума", - "value": "485" - }, - { - "label": "Конфеты", - "value": "341" - }, - { - "label": "Корейцы", - "value": "6535" - }, - { - "label": "Корея", - "value": "2443" - }, - { - "label": "Королевская власть", - "value": "55" - }, - { - "label": "Королевская семья", - "value": "276" - }, - { - "label": "Королевство", - "value": "1695" - }, - { - "label": "Короткий рассказ", - "value": "239" - }, - { - "label": "Коррупция", - "value": "831" - }, - { - "label": "Космическая опера", - "value": "2245" - }, - { - "label": "Космические рейнджеры", - "value": "5860" - }, - { - "label": "Космос", - "value": "329" - }, - { - "label": "Кот", - "value": "5171" - }, - { - "label": "Кража навыков", - "value": "1159" - }, - { - "label": "Красивая главная героиня", - "value": "186" - }, - { - "label": "Красивые женщины", - "value": "66" - }, - { - "label": "Красивые персонажи", - "value": "5787" - }, - { - "label": "Красивый главный герой", - "value": "895" - }, - { - "label": "Крафт", - "value": "1599" - }, - { - "label": "Кроссовер", - "value": "75" - }, - { - "label": "Ктулху", - "value": "920" - }, - { - "label": "Кузнец", - "value": "853" - }, - { - "label": "Кукла", - "value": "3085" - }, - { - "label": "Кулинария", - "value": "2230" - }, - { - "label": "Культивация", - "value": "1901" - }, - { - "label": "Культивирование", - "value": "1860" - }, - { - "label": "Курама", - "value": "5709" - }, - { - "label": "Курилин", - "value": "6134" - }, - { - "label": "Кушина узумаки", - "value": "5222" - }, - { - "label": "Лавкрафт", - "value": "6063" - }, - { - "label": "Лара крофт", - "value": "6435" - }, - { - "label": "Легенда о зельде", - "value": "5707" - }, - { - "label": "Ленивый главный герой", - "value": "1516" - }, - { - "label": "Леон золдик", - "value": "7469" - }, - { - "label": "Лес", - "value": "6645" - }, - { - "label": "Лечебная магия", - "value": "562" - }, - { - "label": "Локи", - "value": "1725" - }, - { - "label": "Лоли", - "value": "1576" - }, - { - "label": "Лопата", - "value": "4989" - }, - { - "label": "Лорд", - "value": "8404" - }, - { - "label": "Лориен", - "value": "7397" - }, - { - "label": "Лошади", - "value": "6110" - }, - { - "label": "Лунатизм", - "value": "3520" - }, - { - "label": "Луффи", - "value": "274" - }, - { - "label": "Лучник", - "value": "1038" - }, - { - "label": "Любовный интерес влюбляется первым", - "value": "7753" - }, - { - "label": "Любовный треугольник", - "value": "2109" - }, - { - "label": "Любовь", - "value": "2297" - }, - { - "label": "Любовь с первого взгляда", - "value": "7748" - }, - { - "label": "Любящие родители", - "value": "2699" - }, - { - "label": "Люди", - "value": "3572" - }, - { - "label": "Люцифер", - "value": "5883" - }, - { - "label": "Маг", - "value": "780" - }, - { - "label": "Магазин", - "value": "4762" - }, - { - "label": "Маги", - "value": "58" - }, - { - "label": "Магическая академия", - "value": "6788" - }, - { - "label": "Магические звери", - "value": "684" - }, - { - "label": "Магические предметы", - "value": "1648" - }, - { - "label": "Магический мир", - "value": "578" - }, - { - "label": "Магия", - "value": "150" - }, - { - "label": "Магия воды", - "value": "6450" - }, - { - "label": "Магия воздуха", - "value": "7627" - }, - { - "label": "Магия земли", - "value": "7626" - }, - { - "label": "Магия и технология", - "value": "107" - }, - { - "label": "Магия крови", - "value": "7976" - }, - { - "label": "Магия льда", - "value": "1379" - }, - { - "label": "Магия огня", - "value": "7625" - }, - { - "label": "Магия призыва", - "value": "885" - }, - { - "label": "Магия природы", - "value": "6226" - }, - { - "label": "Магия стихий", - "value": "7673" - }, - { - "label": "Магия тьмы", - "value": "3596" - }, - { - "label": "Мадара", - "value": "2929" - }, - { - "label": "Мазохизм", - "value": "1961" - }, - { - "label": "Мама", - "value": "12" - }, - { - "label": "Мама и дочь", - "value": "7894" - }, - { - "label": "Мама и сын", - "value": "7895" - }, - { - "label": "Манга", - "value": "2464" - }, - { - "label": "Манипуляция временем", - "value": "932" - }, - { - "label": "Маньяк", - "value": "2026" - }, - { - "label": "Маргери тирелл", - "value": "3935" - }, - { - "label": "Марионетки", - "value": "3175" - }, - { - "label": "Марс", - "value": "4013" - }, - { - "label": "Марти стью", - "value": "594" - }, - { - "label": "Мастер на все руки", - "value": "3189" - }, - { - "label": "Матриархат", - "value": "7197" - }, - { - "label": "Мать и сестры", - "value": "7946" - }, - { - "label": "Мафия", - "value": "353" - }, - { - "label": "Мачеха", - "value": "4664" - }, - { - "label": "Мегаполис", - "value": "3322" - }, - { - "label": "Медицина", - "value": "441" - }, - { - "label": "Медленная романтика", - "value": "8383" - }, - { - "label": "Медленное развитие истории", - "value": "7462" - }, - { - "label": "Мелиодас", - "value": "7224" - }, - { - "label": "Мелодрама", - "value": "1507" - }, - { - "label": "Менеджмент", - "value": "368" - }, - { - "label": "Мерлин", - "value": "3977" - }, - { - "label": "Месть", - "value": "1218" - }, - { - "label": "Меч", - "value": "48" - }, - { - "label": "Мечники", - "value": "969" - }, - { - "label": "Мечта", - "value": "527" - }, - { - "label": "Мизуки", - "value": "4269" - }, - { - "label": "Микото", - "value": "3862" - }, - { - "label": "Милая главная героиня", - "value": "134" - }, - { - "label": "Милф", - "value": "1987" - }, - { - "label": "Милый главный герой", - "value": "2678" - }, - { - "label": "Мимик", - "value": "5706" - }, - { - "label": "Мина ашидо", - "value": "7695" - }, - { - "label": "Минато намикадзе", - "value": "5223" - }, - { - "label": "Мир будущего", - "value": "1770" - }, - { - "label": "Мир земли", - "value": "8394" - }, - { - "label": "Мир меча и магии", - "value": "1271" - }, - { - "label": "Мистер пропер", - "value": "565" - }, - { - "label": "Мифические существа", - "value": "1878" - }, - { - "label": "Мифы и легенды", - "value": "4463" - }, - { - "label": "Младшая сестра", - "value": "1523" - }, - { - "label": "Мморпг", - "value": "620" - }, - { - "label": "Много главных героев", - "value": "1191" - }, - { - "label": "Много крови", - "value": "5318" - }, - { - "label": "Много персонажей", - "value": "1539" - }, - { - "label": "Множество королевств", - "value": "32" - }, - { - "label": "Модерн", - "value": "5457" - }, - { - "label": "Мокутон", - "value": "4438" - }, - { - "label": "Молоко", - "value": "5469" - }, - { - "label": "Монархия", - "value": "3590" - }, - { - "label": "Монстры", - "value": "307" - }, - { - "label": "Море", - "value": "922" - }, - { - "label": "Моритика ринносукэ", - "value": "1142" - }, - { - "label": "Мортал комбат", - "value": "5861" - }, - { - "label": "Мошенник", - "value": "959" - }, - { - "label": "Мрачный мир", - "value": "1" - }, - { - "label": "Мужчина в женском теле", - "value": "8405" - }, - { - "label": "Музыка", - "value": "1183" - }, - { - "label": "Мультивселенная", - "value": "7410" - }, - { - "label": "Мурим", - "value": "7342" - }, - { - "label": "Мутанты", - "value": "2392" - }, - { - "label": "Мутация", - "value": "29" - }, - { - "label": "Мясо", - "value": "1503" - }, - { - "label": "На реальных событиях", - "value": "26" - }, - { - "label": "Навыки", - "value": "415" - }, - { - "label": "Нагато узумаки", - "value": "5221" - }, - { - "label": "Наемники", - "value": "1668" - }, - { - "label": "Назарик", - "value": "5369" - }, - { - "label": "Наивный главный герой", - "value": "159" - }, - { - "label": "Наложница", - "value": "4867" - }, - { - "label": "Наноботы", - "value": "2332" - }, - { - "label": "Наруто", - "value": "7177" - }, - { - "label": "Наруто и хината", - "value": "5766" - }, - { - "label": "Насилие и жестокость", - "value": "1440" - }, - { - "label": "Наука", - "value": "2150" - }, - { - "label": "Национализм", - "value": "5556" - }, - { - "label": "Нацу", - "value": "5826" - }, - { - "label": "Нацуки субару", - "value": "6656" - }, - { - "label": "Начальная школа", - "value": "3920" - }, - { - "label": "Наши дни", - "value": "1814" - }, - { - "label": "Не всесильный главный герой", - "value": "42" - }, - { - "label": "Не по канону", - "value": "1611" - }, - { - "label": "Неверность", - "value": "5735" - }, - { - "label": "Невеста", - "value": "6011" - }, - { - "label": "Неджи хьюга", - "value": "3099" - }, - { - "label": "Недооценённый главный герой", - "value": "43" - }, - { - "label": "Нежить", - "value": "1949" - }, - { - "label": "Некромаг", - "value": "7441" - }, - { - "label": "Некромант", - "value": "1914" - }, - { - "label": "Некромантия", - "value": "754" - }, - { - "label": "Ненормативная лексика", - "value": "160" - }, - { - "label": "Необычные герои", - "value": "67" - }, - { - "label": "Нет людей", - "value": "7486" - }, - { - "label": "Нетораре", - "value": "403" - }, - { - "label": "Нетори", - "value": "5393" - }, - { - "label": "Нефилимы", - "value": "7764" - }, - { - "label": "Нецензурная лексика", - "value": "4912" - }, - { - "label": "Нечисть", - "value": "4559" - }, - { - "label": "Ник фьюри", - "value": "6304" - }, - { - "label": "Ниндзюцу", - "value": "2354" - }, - { - "label": "Ниндзя", - "value": "1330" - }, - { - "label": "Новелла", - "value": "2105" - }, - { - "label": "Нэко", - "value": "147" - }, - { - "label": "Оби ван кеноби", - "value": "6830" - }, - { - "label": "Обито учиха", - "value": "2814" - }, - { - "label": "Оборотни", - "value": "53" - }, - { - "label": "Обратный гарем", - "value": "3303" - }, - { - "label": "Овощ", - "value": "6098" - }, - { - "label": "Огнестрельное оружие", - "value": "3155" - }, - { - "label": "Одержимость", - "value": "708" - }, - { - "label": "Один в поле воин", - "value": "6498" - }, - { - "label": "Онлайн игра", - "value": "1565" - }, - { - "label": "Ооками теппей", - "value": "849" - }, - { - "label": "Оригинальные персонажи", - "value": "7741" - }, - { - "label": "Орки", - "value": "1597" - }, - { - "label": "Оружие", - "value": "125" - }, - { - "label": "Основано на видео игре", - "value": "602" - }, - { - "label": "Особые способности", - "value": "2904" - }, - { - "label": "От бедности к богатству", - "value": "901" - }, - { - "label": "От слабого до сильного", - "value": "118" - }, - { - "label": "Отель", - "value": "2879" - }, - { - "label": "Отец", - "value": "3290" - }, - { - "label": "Отношения", - "value": "398" - }, - { - "label": "Отношения человек/нечеловек", - "value": "7406" - }, - { - "label": "Офис", - "value": "3460" - }, - { - "label": "Охотники", - "value": "2263" - }, - { - "label": "Оцуцуки", - "value": "5101" - }, - { - "label": "Ошейник", - "value": "2362" - }, - { - "label": "Ояш", - "value": "8048" - }, - { - "label": "Падчерица", - "value": "7023" - }, - { - "label": "Падший ангел", - "value": "184" - }, - { - "label": "Палач", - "value": "852" - }, - { - "label": "Палочка", - "value": "2682" - }, - { - "label": "Пандорум", - "value": "4360" - }, - { - "label": "Папа и дочь", - "value": "7647" - }, - { - "label": "Паразит", - "value": "1213" - }, - { - "label": "Параллельный мир", - "value": "2092" - }, - { - "label": "Парень", - "value": "619" - }, - { - "label": "Паркур", - "value": "3391" - }, - { - "label": "Пародия", - "value": "898" - }, - { - "label": "Пасхалки", - "value": "455" - }, - { - "label": "Паук", - "value": "2209" - }, - { - "label": "Пекарь", - "value": "5073" - }, - { - "label": "Первая книга", - "value": "269" - }, - { - "label": "Первая любовь", - "value": "640" - }, - { - "label": "Первый раз", - "value": "1465" - }, - { - "label": "Переводы", - "value": "24" - }, - { - "label": "Перевоплощение", - "value": "1596" - }, - { - "label": "Перевоплощение в игровом мире", - "value": "92" - }, - { - "label": "Перемещение в другой мир", - "value": "1288" - }, - { - "label": "Перемещение во времени", - "value": "146" - }, - { - "label": "Перерождение", - "value": "894" - }, - { - "label": "Перерождение в демона", - "value": "1111" - }, - { - "label": "Перерождение в дракона", - "value": "6867" - }, - { - "label": "Перерождение в злодейку", - "value": "5619" - }, - { - "label": "Перерождение в злодея", - "value": "749" - }, - { - "label": "Перерождение в ином мире", - "value": "109" - }, - { - "label": "Перерождение в монстра", - "value": "917" - }, - { - "label": "Перерождений", - "value": "335" - }, - { - "label": "Переселение", - "value": "813" - }, - { - "label": "Переселение души", - "value": "1864" - }, - { - "label": "Перси джексон", - "value": "6329" - }, - { - "label": "Пилот", - "value": "5521" - }, - { - "label": "Пилюли", - "value": "1531" - }, - { - "label": "Пират", - "value": "1579" - }, - { - "label": "Пирог", - "value": "80" - }, - { - "label": "Писатель", - "value": "734" - }, - { - "label": "Пистолеты", - "value": "4916" - }, - { - "label": "Письмо", - "value": "840" - }, - { - "label": "Питомцы", - "value": "3122" - }, - { - "label": "Планомерное развитие событий", - "value": "62" - }, - { - "label": "Племянник", - "value": "8303" - }, - { - "label": "Пленница", - "value": "4897" - }, - { - "label": "Плети", - "value": "4839" - }, - { - "label": "Пляж", - "value": "4243" - }, - { - "label": "Повар", - "value": "658" - }, - { - "label": "Повествование от первого лица", - "value": "1054" - }, - { - "label": "Повествование от разных лиц", - "value": "600" - }, - { - "label": "Повествование от третьего лица", - "value": "2116" - }, - { - "label": "Подавитель", - "value": "497" - }, - { - "label": "Подземелье", - "value": "798" - }, - { - "label": "Подростки", - "value": "636" - }, - { - "label": "Подруга", - "value": "5804" - }, - { - "label": "Подчинение", - "value": "8343" - }, - { - "label": "Подчинение и унижение", - "value": "4500" - }, - { - "label": "Покемоны", - "value": "2840" - }, - { - "label": "Полиамория", - "value": "1300" - }, - { - "label": "Полигамия", - "value": "1336" - }, - { - "label": "Политика", - "value": "1313" - }, - { - "label": "Полицейский", - "value": "1907" - }, - { - "label": "Полубог", - "value": "7170" - }, - { - "label": "Полукровка", - "value": "999" - }, - { - "label": "Полулюди", - "value": "2273" - }, - { - "label": "Поношенные трусики", - "value": "1204" - }, - { - "label": "Попаданец", - "value": "2396" - }, - { - "label": "Попаданец в другой мир", - "value": "685" - }, - { - "label": "Попаданец в игру", - "value": "6466" - }, - { - "label": "Попадание в книгу", - "value": "6957" - }, - { - "label": "Постапокалипсис", - "value": "1079" - }, - { - "label": "Похищение", - "value": "7452" - }, - { - "label": "Поэзия", - "value": "1120" - }, - { - "label": "Правитель", - "value": "2261" - }, - { - "label": "Превращения в животных", - "value": "3410" - }, - { - "label": "Преданный любовный интерес", - "value": "2055" - }, - { - "label": "Предательство", - "value": "70" - }, - { - "label": "Президент", - "value": "4334" - }, - { - "label": "Преступник", - "value": "4049" - }, - { - "label": "Преступный мир", - "value": "965" - }, - { - "label": "Призрак", - "value": "511" - }, - { - "label": "Призыв", - "value": "332" - }, - { - "label": "Призыв в другой мир", - "value": "781" - }, - { - "label": "Призыв существ", - "value": "412" - }, - { - "label": "Приложение на телефоне", - "value": "5345" - }, - { - "label": "Принудительный брак", - "value": "2954" - }, - { - "label": "Принуждение", - "value": "1442" - }, - { - "label": "Принц", - "value": "362" - }, - { - "label": "Принцесса", - "value": "2403" - }, - { - "label": "Приручение мостров", - "value": "2338" - }, - { - "label": "Прислуга", - "value": "5185" - }, - { - "label": "Пришельцы", - "value": "273" - }, - { - "label": "Проза", - "value": "2012" - }, - { - "label": "Прокачка", - "value": "1070" - }, - { - "label": "Проклятия", - "value": "1347" - }, - { - "label": "Проработанный мир", - "value": "1711" - }, - { - "label": "Пророчество", - "value": "7762" - }, - { - "label": "Против наркотиков", - "value": "8406" - }, - { - "label": "Псайкеры", - "value": "3659" - }, - { - "label": "Псионика", - "value": "5216" - }, - { - "label": "Психбольница", - "value": "6969" - }, - { - "label": "Психические расстройства", - "value": "2445" - }, - { - "label": "Психологические травмы", - "value": "3418" - }, - { - "label": "Публичный дом", - "value": "7860" - }, - { - "label": "Путешествие в другой мир", - "value": "10" - }, - { - "label": "Пух", - "value": "4286" - }, - { - "label": "Пушечное мясо", - "value": "7234" - }, - { - "label": "Пытки", - "value": "1756" - }, - { - "label": "Пьяный мастер", - "value": "1655" - }, - { - "label": "Пэнси паркинсон", - "value": "7411" - }, - { - "label": "Раб", - "value": "977" - }, - { - "label": "Рабы", - "value": "1240" - }, - { - "label": "Разведение животных", - "value": "3990" - }, - { - "label": "Развитие", - "value": "208" - }, - { - "label": "Развитие персонажа", - "value": "1780" - }, - { - "label": "Развитие поселения", - "value": "7203" - }, - { - "label": "Развитие технологий", - "value": "1875" - }, - { - "label": "Раздвоение личности", - "value": "2062" - }, - { - "label": "Разные расы", - "value": "1188" - }, - { - "label": "Разорванная помолвка", - "value": "2057" - }, - { - "label": "Разработчик", - "value": "2333" - }, - { - "label": "Ранги", - "value": "1568" - }, - { - "label": "Ранобэ", - "value": "1764" - }, - { - "label": "Расизм", - "value": "3554" - }, - { - "label": "Растение", - "value": "407" - }, - { - "label": "Реализм", - "value": "1180" - }, - { - "label": "Ребенок", - "value": "2881" - }, - { - "label": "Ревность", - "value": "293" - }, - { - "label": "Революция", - "value": "3996" - }, - { - "label": "Реинкарнация", - "value": "1302" - }, - { - "label": "Реинкарнация в другом мире", - "value": "2180" - }, - { - "label": "Реинкарнация в игровой мир", - "value": "304" - }, - { - "label": "Рейджер", - "value": "5147" - }, - { - "label": "Религия", - "value": "2184" - }, - { - "label": "Рем", - "value": "6655" - }, - { - "label": "Ремесленник", - "value": "1483" - }, - { - "label": "Ремонт", - "value": "5703" - }, - { - "label": "Репликаторы", - "value": "3495" - }, - { - "label": "Ресторан", - "value": "7519" - }, - { - "label": "Риас гремори", - "value": "6950" - }, - { - "label": "Рим", - "value": "612" - }, - { - "label": "Риннеган", - "value": "4230" - }, - { - "label": "Ритуал", - "value": "1233" - }, - { - "label": "Робот", - "value": "4011" - }, - { - "label": "Роботы", - "value": "467" - }, - { - "label": "Рок ли", - "value": "7002" - }, - { - "label": "Рокси", - "value": "7380" - }, - { - "label": "Рон уизли", - "value": "4279" - }, - { - "label": "Ророноа зоро", - "value": "1590" - }, - { - "label": "Росомаха", - "value": "1035" - }, - { - "label": "Российская империя", - "value": "2146" - }, - { - "label": "Россия", - "value": "4246" - }, - { - "label": "Рудеус", - "value": "7379" - }, - { - "label": "Руны", - "value": "2393" - }, - { - "label": "Русалки", - "value": "3127" - }, - { - "label": "Русь", - "value": "2016" - }, - { - "label": "Рыцари", - "value": "1902" - }, - { - "label": "Рэо хатаке", - "value": "2823" - }, - { - "label": "Сабли", - "value": "6136" - }, - { - "label": "Сайян", - "value": "6802" - }, - { - "label": "Сакура", - "value": "2515" - }, - { - "label": "Самец", - "value": "1592" - }, - { - "label": "Самураи", - "value": "576" - }, - { - "label": "Санса старк", - "value": "3925" - }, - { - "label": "Сарказм", - "value": "4658" - }, - { - "label": "Саске", - "value": "7237" - }, - { - "label": "Сатира", - "value": "215" - }, - { - "label": "Сборник", - "value": "7367" - }, - { - "label": "Свадьба", - "value": "1524" - }, - { - "label": "Сверхсила", - "value": "1055" - }, - { - "label": "Свинцовые книги", - "value": "5322" - }, - { - "label": "Связывание", - "value": "4506" - }, - { - "label": "Священик", - "value": "61" - }, - { - "label": "Северус снейп", - "value": "5783" - }, - { - "label": "Сёдзе", - "value": "2219" - }, - { - "label": "Секты", - "value": "1234" - }, - { - "label": "Сельское хозяйство", - "value": "787" - }, - { - "label": "Семейный конфликт", - "value": "935" - }, - { - "label": "Семья", - "value": "728" - }, - { - "label": "Сенджу", - "value": "6069" - }, - { - "label": "Серийный убийца", - "value": "261" - }, - { - "label": "Сестра", - "value": "2342" - }, - { - "label": "Сила глаза", - "value": "1019" - }, - { - "label": "Сильная героиня", - "value": "7292" - }, - { - "label": "Сильная главная героиня", - "value": "1994" - }, - { - "label": "Сильный главный герой", - "value": "570" - }, - { - "label": "Сильфиетта", - "value": "7381" - }, - { - "label": "Симбиот", - "value": "2648" - }, - { - "label": "Сириус блэк", - "value": "7655" - }, - { - "label": "Сирота", - "value": "297" - }, - { - "label": "Система", - "value": "251" - }, - { - "label": "Система уровней", - "value": "2174" - }, - { - "label": "Ситх", - "value": "1618" - }, - { - "label": "Сказка", - "value": "3570" - }, - { - "label": "Скайрим", - "value": "4032" - }, - { - "label": "Скайуокер", - "value": "6828" - }, - { - "label": "Сквиб", - "value": "4101" - }, - { - "label": "Скелет", - "value": "1315" - }, - { - "label": "Скрытые способности", - "value": "3417" - }, - { - "label": "Скульптор", - "value": "1178" - }, - { - "label": "Слабая главная героиня", - "value": "5805" - }, - { - "label": "Слабый главный герой", - "value": "731" - }, - { - "label": "Славяне", - "value": "2168" - }, - { - "label": "Слизерин", - "value": "6979" - }, - { - "label": "Слизь", - "value": "1095" - }, - { - "label": "Сломанная игрушка", - "value": "8396" - }, - { - "label": "Служанка", - "value": "3486" - }, - { - "label": "Смартфон", - "value": "457" - }, - { - "label": "Смена сущности", - "value": "8391" - }, - { - "label": "Смерть", - "value": "1779" - }, - { - "label": "Смерть основного персонажа", - "value": "1530" - }, - { - "label": "Собаки", - "value": "6109" - }, - { - "label": "Соблазн", - "value": "7994" - }, - { - "label": "Соблазнение", - "value": "2290" - }, - { - "label": "Современность", - "value": "568" - }, - { - "label": "Современные знания", - "value": "988" - }, - { - "label": "Сожительство", - "value": "3026" - }, - { - "label": "Создание армии", - "value": "1992" - }, - { - "label": "Создание королевства", - "value": "1497" - }, - { - "label": "Создание пилюль", - "value": "816" - }, - { - "label": "Создатель", - "value": "1045" - }, - { - "label": "Сокровища", - "value": "6521" - }, - { - "label": "Сокрытие истинной личности", - "value": "2894" - }, - { - "label": "Сома и эрина", - "value": "5737" - }, - { - "label": "Соперничество", - "value": "7699" - }, - { - "label": "Соседи", - "value": "4075" - }, - { - "label": "Сотрудник", - "value": "6339" - }, - { - "label": "Социология", - "value": "7618" - }, - { - "label": "Спокойная главная героиня", - "value": "236" - }, - { - "label": "Спокойный главный герой", - "value": "1656" - }, - { - "label": "Спор", - "value": "3484" - }, - { - "label": "Спортивное тело", - "value": "8317" - }, - { - "label": "Способность кражи", - "value": "7784" - }, - { - "label": "Сражения", - "value": "23" - }, - { - "label": "Средневековье", - "value": "1022" - }, - { - "label": "Сталкер", - "value": "1932" - }, - { - "label": "Становление государства", - "value": "111" - }, - { - "label": "Старшая школа", - "value": "1658" - }, - { - "label": "Стёб", - "value": "454" - }, - { - "label": "Стекло", - "value": "7453" - }, - { - "label": "Стеснительный персонаж", - "value": "152" - }, - { - "label": "Стимпанк", - "value": "1894" - }, - { - "label": "Стихи", - "value": "1309" - }, - { - "label": "Стратегия", - "value": "569" - }, - { - "label": "Строительство", - "value": "921" - }, - { - "label": "Студент", - "value": "1464" - }, - { - "label": "Студентка", - "value": "7518" - }, - { - "label": "Суккубы", - "value": "2662" - }, - { - "label": "Супер зрение", - "value": "6574" - }, - { - "label": "Супер удача", - "value": "489" - }, - { - "label": "Супергерои", - "value": "1481" - }, - { - "label": "Суперзлодеи", - "value": "2125" - }, - { - "label": "Супермен", - "value": "6997" - }, - { - "label": "Суперсилы", - "value": "2276" - }, - { - "label": "Существа", - "value": "6033" - }, - { - "label": "Сферы", - "value": "1077" - }, - { - "label": "Схемы и заговоры", - "value": "7116" - }, - { - "label": "Сценарий", - "value": "7489" - }, - { - "label": "Счастливый конец", - "value": "3293" - }, - { - "label": "Сын", - "value": "3297" - }, - { - "label": "Сэм винчестер", - "value": "7461" - }, - { - "label": "Сюаньхуа", - "value": "2560" - }, - { - "label": "Сюжетные повороты", - "value": "7202" - }, - { - "label": "Таблетки для развития", - "value": "589" - }, - { - "label": "Таинственное прошлое", - "value": "769" - }, - { - "label": "Тайная личность", - "value": "8096" - }, - { - "label": "Тайная любовь", - "value": "113" - }, - { - "label": "Тайны", - "value": "7481" - }, - { - "label": "Тайные отношения", - "value": "7450" - }, - { - "label": "Тайцы", - "value": "6413" - }, - { - "label": "Танки", - "value": "1787" - }, - { - "label": "Творчество", - "value": "20" - }, - { - "label": "Тейлор эберт", - "value": "3526" - }, - { - "label": "Телекинез", - "value": "2203" - }, - { - "label": "Телепортация", - "value": "914" - }, - { - "label": "Телохранитель", - "value": "723" - }, - { - "label": "Темари", - "value": "4810" - }, - { - "label": "Темная магия", - "value": "4788" - }, - { - "label": "Темное фэнтези", - "value": "1675" - }, - { - "label": "Темные эльфы", - "value": "7198" - }, - { - "label": "Тенсейган", - "value": "4367" - }, - { - "label": "Тетя", - "value": "4194" - }, - { - "label": "Техномагия", - "value": "508" - }, - { - "label": "Тиран", - "value": "1174" - }, - { - "label": "Титаны", - "value": "3308" - }, - { - "label": "Тодороки шото", - "value": "5105" - }, - { - "label": "Токио", - "value": "5791" - }, - { - "label": "Том реддл", - "value": "6652" - }, - { - "label": "Тони старк", - "value": "1338" - }, - { - "label": "Тор", - "value": "1800" - }, - { - "label": "Тор и локи", - "value": "2645" - }, - { - "label": "Торговля", - "value": "1637" - }, - { - "label": "Травничество", - "value": "221" - }, - { - "label": "Трагическое прошлое", - "value": "644" - }, - { - "label": "Трактир", - "value": "1918" - }, - { - "label": "Трансмиграция", - "value": "1071" - }, - { - "label": "Трансформация", - "value": "156" - }, - { - "label": "Трансформеры", - "value": "4616" - }, - { - "label": "Тревор филипс", - "value": "5427" - }, - { - "label": "Тройняшки", - "value": "7169" - }, - { - "label": "Троли", - "value": "4250" - }, - { - "label": "Трудолюбивый главный герой", - "value": "248" - }, - { - "label": "Тупой главный герой", - "value": "3710" - }, - { - "label": "Тьма", - "value": "1919" - }, - { - "label": "Тюрьма", - "value": "5597" - }, - { - "label": "Тяжёлое детство", - "value": "2253" - }, - { - "label": "Убийства", - "value": "378" - }, - { - "label": "Убийцы", - "value": "1766" - }, - { - "label": "Убийцы драконов", - "value": "1484" - }, - { - "label": "Увечья", - "value": "3266" - }, - { - "label": "Удача", - "value": "6575" - }, - { - "label": "Узумаки", - "value": "7579" - }, - { - "label": "Укротитель", - "value": "367" - }, - { - "label": "Умения", - "value": "531" - }, - { - "label": "Умная главная героиня", - "value": "1381" - }, - { - "label": "Умные персонажи", - "value": "2756" - }, - { - "label": "Умный главный герой", - "value": "2093" - }, - { - "label": "Университет", - "value": "2102" - }, - { - "label": "Унижение", - "value": "8342" - }, - { - "label": "Уничтожение мира", - "value": "81" - }, - { - "label": "Управление временем", - "value": "5648" - }, - { - "label": "Уровни", - "value": "8" - }, - { - "label": "Усиление", - "value": "3549" - }, - { - "label": "Усопп", - "value": "6737" - }, - { - "label": "Устроенный брак", - "value": "2223" - }, - { - "label": "Усыновление", - "value": "395" - }, - { - "label": "Утопия", - "value": "4677" - }, - { - "label": "Уход за детьми", - "value": "7609" - }, - { - "label": "Учеба в университете", - "value": "2797" - }, - { - "label": "Учебное заведение", - "value": "1817" - }, - { - "label": "Ученые", - "value": "1843" - }, - { - "label": "Учитель", - "value": "845" - }, - { - "label": "Учиха", - "value": "5348" - }, - { - "label": "Фамильяры", - "value": "1471" - }, - { - "label": "Фанатичная любовь", - "value": "6721" - }, - { - "label": "Фанаты", - "value": "7739" - }, - { - "label": "Фантастический мир", - "value": "2414" - }, - { - "label": "Фармацевт", - "value": "1706" - }, - { - "label": "Фашисты", - "value": "3118" - }, - { - "label": "Феи", - "value": "7185" - }, - { - "label": "Фелляция", - "value": "5880" - }, - { - "label": "Феминизм", - "value": "6527" - }, - { - "label": "Феникс", - "value": "2413" - }, - { - "label": "Фенрир", - "value": "2740" - }, - { - "label": "Феодализм", - "value": "280" - }, - { - "label": "Ферма", - "value": "285" - }, - { - "label": "Фехтовальщик", - "value": "4685" - }, - { - "label": "Филиппины", - "value": "128" - }, - { - "label": "Философия", - "value": "1859" - }, - { - "label": "Флафф", - "value": "5048" - }, - { - "label": "Флер делакур", - "value": "5191" - }, - { - "label": "Флэш", - "value": "4667" - }, - { - "label": "Фокусник", - "value": "7602" - }, - { - "label": "Фольклор", - "value": "4086" - }, - { - "label": "Фугаку", - "value": "6161" - }, - { - "label": "Фурри", - "value": "6631" - }, - { - "label": "Футбол", - "value": "1121" - }, - { - "label": "Фэнтезийный мир", - "value": "1556" - }, - { - "label": "Хакер", - "value": "475" - }, - { - "label": "Халк", - "value": "1196" - }, - { - "label": "Хан нуньен синг", - "value": "4817" - }, - { - "label": "Ханма юджиро", - "value": "4369" - }, - { - "label": "Хаос", - "value": "3117" - }, - { - "label": "Харизматичный главный герой", - "value": "2350" - }, - { - "label": "Хатаке какаши", - "value": "2820" - }, - { - "label": "Хиддлстон", - "value": "5903" - }, - { - "label": "Химавари", - "value": "2583" - }, - { - "label": "Хината", - "value": "2513" - }, - { - "label": "Хитрый главный герой", - "value": "2036" - }, - { - "label": "Хоббит", - "value": "6698" - }, - { - "label": "Хогвартс", - "value": "5954" - }, - { - "label": "Холодная главная героиня", - "value": "6507" - }, - { - "label": "Холодное оружие", - "value": "4889" - }, - { - "label": "Холодный главный герой", - "value": "2686" - }, - { - "label": "Храм", - "value": "2135" - }, - { - "label": "Христианство", - "value": "877" - }, - { - "label": "Художественная литература", - "value": "2380" - }, - { - "label": "Художница", - "value": "518" - }, - { - "label": "Хулиганы", - "value": "854" - }, - { - "label": "Цветок", - "value": "902" - }, - { - "label": "Цезарь", - "value": "1705" - }, - { - "label": "Целители", - "value": "4523" - }, - { - "label": "Церковь", - "value": "1980" - }, - { - "label": "Цундере", - "value": "1078" - }, - { - "label": "Чакра", - "value": "1393" - }, - { - "label": "Чат-система", - "value": "8407" - }, - { - "label": "Черный юмор", - "value": "2868" - }, - { - "label": "Честная главная героиня", - "value": "5855" - }, - { - "label": "Честный главный герой", - "value": "129" - }, - { - "label": "Читы", - "value": "451" - }, - { - "label": "Шантаж", - "value": "7175" - }, - { - "label": "Шаринган", - "value": "5165" - }, - { - "label": "Шинигами", - "value": "4661" - }, - { - "label": "Шиноби", - "value": "1227" - }, - { - "label": "Школьная жизнь", - "value": "284" - }, - { - "label": "Школьники", - "value": "218" - }, - { - "label": "Школьницы", - "value": "5946" - }, - { - "label": "Шлюха", - "value": "5822" - }, - { - "label": "Шоу-бизнес", - "value": "7119" - }, - { - "label": "Шпионы", - "value": "4262" - }, - { - "label": "Эволюция", - "value": "2040" - }, - { - "label": "Экзорцизм", - "value": "676" - }, - { - "label": "Экономика", - "value": "121" - }, - { - "label": "Экспансия", - "value": "110" - }, - { - "label": "Эксперименты над людьми", - "value": "7408" - }, - { - "label": "Элементальная магия", - "value": "1264" - }, - { - "label": "Эльфы", - "value": "1362" - }, - { - "label": "Эротика", - "value": "2053" - }, - { - "label": "Юмор", - "value": "7360" - }, - { - "label": "Яды", - "value": "201" - }, - { - "label": "Якудза", - "value": "4599" - }, - { - "label": "Яндере", - "value": "7111" - }, - { - "label": "Rpg", - "value": "90" - }, - { - "label": "Star wars", - "value": "1985" - }, - { - "label": "Time skip", - "value": "824" - }, - { - "label": "Warrior of light", - "value": "5289" - } - ], - "inputType": "Checkbox" - }, - { - "key": "fandoms", - "label": "Фэндом:", - "values": [ - { - "label": "19 Дней - Один день / 19 Days - One Day", - "value": "838" - }, - { - "label": "47-й / Хитмэн: Агент 47 / Наёмный убийца / Hitman", - "value": "589" - }, - { - "label": "Абсолютный дуэт / Absolute Duo", - "value": "1029" - }, - { - "label": "Аватар (Короля; об Аанге; об Корре) / Avatar", - "value": "1889" - }, - { - "label": "Аватар: Легенда о Корре / Avatar legend of Korra", - "value": "351" - }, - { - "label": "Аватар: Легенда об Аанге / Avatar: The Legend of Aang / Avatar: The Last Airbender", - "value": "303" - }, - { - "label": "Аватар(Фильм, 2009) / Avatar", - "value": "19" - }, - { - "label": "Ад Данте(Данте Алигьери) / Dante's Inferno(Dante Alighieri)", - "value": "1502" - }, - { - "label": "Азур Лейн / Azur Lane", - "value": "1009" - }, - { - "label": "Айон / Aion", - "value": "1005" - }, - { - "label": "Аладдин / Aladdin", - "value": "502" - }, - { - "label": "Алиса в Стране чудес / Alice in Wonderland", - "value": "616" - }, - { - "label": "Альдноа.Зеро / Aldnoah.Zero", - "value": "1799" - }, - { - "label": "Амагами СС / Amagami SS", - "value": "900" - }, - { - "label": "Амано Мегуми полна любви! / Amano Megumi wa Sukidarake!", - "value": "991" - }, - { - "label": "Американские боги / American Gods", - "value": "1843" - }, - { - "label": "Американский папаша! / American Dad", - "value": "348" - }, - { - "label": "Ангельские ритмы! / Angel Beats!", - "value": "880" - }, - { - "label": "Анлимитед: Хёбу Кёске / Zettai Karen Children: The Unlimited - Hyoubu Kyousuke", - "value": "74" - }, - { - "label": "Апостол карточек / The Apostle of Cards", - "value": "1504" - }, - { - "label": "Арифурэта: сильнейший ремесленник в мире / Arifureta: From Commonplace to World's Strongest", - "value": "62" - }, - { - "label": "Аркан: О Паровых Заводах и Магии Обскуры / Arcanum: Of Steamworks and Magick Obscura", - "value": "1495" - }, - { - "label": "Аркейн / Arcane: League of Legends", - "value": "1154" - }, - { - "label": "Аркнайтс(Games) / Arknights", - "value": "1210" - }, - { - "label": "Армелло(Games) / Armello", - "value": "1846" - }, - { - "label": "Астра, затерянная в космосе / Kanata no Astra", - "value": "1851" - }, - { - "label": "Атака титанов / Атака на титанов / Attack on Titan", - "value": "106" - }, - { - "label": "Атлантида: Затерянный мир / Atlantis: The Lost Empire", - "value": "985" - }, - { - "label": "Бакуган Отчаянные бойцы / Bakugan Battle Brawlers", - "value": "1069" - }, - { - "label": "Банановая рыба / Banana Fish", - "value": "1685" - }, - { - "label": "Баскетбол Куроко / Kuroko no basuke", - "value": "582" - }, - { - "label": "Баффи - Истребительница вампиров / Buffy the Vampire Slayer", - "value": "115" - }, - { - "label": "Башня Бога / Tower of God", - "value": "58" - }, - { - "label": "Бездарная Нана / Munou na Nana", - "value": "954" - }, - { - "label": "Бездомный бог / Норагами / Noragami", - "value": "1014" - }, - { - "label": "Безумные Мотивы / Looney Tunes", - "value": "1140" - }, - { - "label": "Безумный азарт / Kakegurui", - "value": "334" - }, - { - "label": "Бейблэйд / Beyblade", - "value": "921" - }, - { - "label": "Бен - 10 / Ben 10", - "value": "475" - }, - { - "label": "Берсерк / Berserk", - "value": "479" - }, - { - "label": "Бесконечное лето / Everlasting Summer", - "value": "966" - }, - { - "label": "Бесконечный ужас / Terror Infinity", - "value": "381" - }, - { - "label": "Бесподобный Воинственный Бог / Peerless Martial God", - "value": "419" - }, - { - "label": "Бессмертный Деревенщина(Games) / Immortal Redneck", - "value": "1524" - }, - { - "label": "Бесстыжие / Shameless", - "value": "1759" - }, - { - "label": "Био шок(Games) / BioShock", - "value": "1095" - }, - { - "label": "Блейд / Blade", - "value": "1479" - }, - { - "label": "Блич / Bleach", - "value": "7" - }, - { - "label": "Бог войны / God Of War", - "value": "352" - }, - { - "label": "Бог из машины / Deus Ex", - "value": "612" - }, - { - "label": "Боги поступают плохо / Игры богов / Gods Behaving Badly", - "value": "301" - }, - { - "label": "Боевая академия города Астериск / Gakusen Toshi Asterisk", - "value": "884" - }, - { - "label": "Боевой континент / Combat Continent / Douluo Dalu", - "value": "739" - }, - { - "label": "Боевой молот 40-го тысячелетия / WH40K / Warhammer 40,000", - "value": "341" - }, - { - "label": "Боевой молот Фэнтезийная битва / Warhammer Fantasy Battles", - "value": "1742" - }, - { - "label": "Боевые машины(Games) / BattleTech", - "value": "1667" - }, - { - "label": "Боец Баки / Baki the Grappler", - "value": "821" - }, - { - "label": "Божественность II: Эго Дракона(Games) / Divinity II: Ego Draconis", - "value": "1538" - }, - { - "label": "Божественные Врата / Divine Gate", - "value": "1490" - }, - { - "label": "Большая автомобильная кража 5 / GTA V / Grand Theft Auto V", - "value": "1139" - }, - { - "label": "Большая автомобильная кража: Сан-Андреас / GTA: SA / Grand Theft Auto: San Andreas", - "value": "820" - }, - { - "label": "Большая разница / Far Cry", - "value": "939" - }, - { - "label": "Большой куш / Ван Пис / One Piece", - "value": "25" - }, - { - "label": "Боруто: Следующие поколения Наруто / Boruto: Naruto Next Generations", - "value": "602" - }, - { - "label": "Брак по договоренности с принцессой красных скорпионов / Arranged marriage to the princess of the Red Scorpions", - "value": "1386" - }, - { - "label": "Бэтмен за гранью: Наследие / Batman Beyond: Legacy", - "value": "1380" - }, - { - "label": "В другом мире со смартфоном / Isekai wa Smartphone to Tomo ni", - "value": "947" - }, - { - "label": "В объятиях шлюхи / JK Bitch ni Shiboraretai", - "value": "1283" - }, - { - "label": "В ожидании бедности, я собираюсь стать кузнецом / Expecting to Fall into Ruin, I Aim to Become a Blacksmith", - "value": "1475" - }, - { - "label": "В Повелителе как Довакин / In Overlord as a Dovahkiin", - "value": "1816" - }, - { - "label": "Вакфу / Wakfu", - "value": "814" - }, - { - "label": "ВАЛЛ-И / Wally", - "value": "801" - }, - { - "label": "Вампир: Маскарад - Родословные / Vampire: The Masquerade Bloodline", - "value": "1212" - }, - { - "label": "Вампирелла / Vampirella", - "value": "1214" - }, - { - "label": "Варфрейм / Warframe", - "value": "967" - }, - { - "label": "Ведьмак / The Witcher", - "value": "278" - }, - { - "label": "Великий из бродячих псов / Bungou Stray Dogs", - "value": "75" - }, - { - "label": "Великолепный парк Амаги / Amagi Brilliant Park", - "value": "813" - }, - { - "label": "Вельзепуз / Вельзевул / Beelzebub", - "value": "765" - }, - { - "label": "Веном / Venom", - "value": "978" - }, - { - "label": "Веселая ферма / Fun Farm", - "value": "1124" - }, - { - "label": "Вечная история / The Neverending Story", - "value": "547" - }, - { - "label": "Вечные(Фильм, 2021) / Eternal", - "value": "1234" - }, - { - "label": "Виви: Песнь флюоритового глаза / Vivy: Fluorite Eye's Song", - "value": "1819" - }, - { - "label": "Викинги / Vikings", - "value": "369" - }, - { - "label": "Владелец ранчо со слизью(Games) / Ранчо слизи / Slime Rancher", - "value": "1529" - }, - { - "label": "Властелин колец / Lord of the Ring", - "value": "254" - }, - { - "label": "Власть книжного червя / Honzuki no Gekokujou", - "value": "1399" - }, - { - "label": "Внук Мудрец / Kenjo no Mago", - "value": "1260" - }, - { - "label": "Внук Нурарихёна / Nurarihyon no Mago", - "value": "66" - }, - { - "label": "Во всеоружии / Overgeared", - "value": "1021" - }, - { - "label": "Во тьме(Games) / The Darkness", - "value": "938" - }, - { - "label": "Военная хроника маленькой девочки / Сага о злой Тане / The Saga of Tanya the Evil / \tGekijouban Youjo Senki", - "value": "1726" - }, - { - "label": "Возвращение в детские годы / Gaki ni Modotte Yarinaoshi!!!", - "value": "1031" - }, - { - "label": "Возрождение Серийного Убийцы / Rebirth Of A Serial Killer", - "value": "1358" - }, - { - "label": "Воинственный Бог Асура / Martial God Asura", - "value": "771" - }, - { - "label": "Война будущего / The Tomorrow War", - "value": "1174" - }, - { - "label": "Война Любовь Снег / War Love Snow", - "value": "1417" - }, - { - "label": "Волейбол! / Haikyuu!!", - "value": "697" - }, - { - "label": "Волчонок / Teen Wolf", - "value": "795" - }, - { - "label": "Волшебная Девушка Спецоперация Аска / Magical Girl Spec-Ops Asuka", - "value": "1470" - }, - { - "label": "Волшебник-воин Орфен / Majutsushi Orphen Hagure Tabi: Kimluck-hen", - "value": "1128" - }, - { - "label": "Волшебники / The Magicians", - "value": "1314" - }, - { - "label": "Волшебный учитель Нэгима! / Negima!: Magister Negi Mag", - "value": "1777" - }, - { - "label": "Воля второго цикла мироздания. / Will of the second cycle of the Worldifice.", - "value": "1036" - }, - { - "label": "Воспитание хозяина / Yours to Claim", - "value": "839" - }, - { - "label": "Восставший против неба / Against the Gods", - "value": "957" - }, - { - "label": "Восстание стражей / Хранители снов / Rise of the Guardians", - "value": "1488" - }, - { - "label": "Восхождение в Голливуде / I'm in Hollywood", - "value": "1237" - }, - { - "label": "Восхождение героя щита / The Rising of the Shield Hero", - "value": "103" - }, - { - "label": "Врата Штейна / Steins: Gate", - "value": "1044" - }, - { - "label": "Врата: там бьются наши воины / Gate: Jieitai Kanochi nite, Kaku Tatakaeri", - "value": "727" - }, - { - "label": "Время / In Time", - "value": "542" - }, - { - "label": "Всегда вялый Танака-кун / Tanaka-kun wa Itsumo Kedaruge", - "value": "1082" - }, - { - "label": "Всего лишь восьмой сын? Я с этим не смирюсь! / Hachinan tte, Sore wa Nai Deshou! / Eighth son, I don’t think so!", - "value": "1473" - }, - { - "label": "Вселенная Марвел / Marvel Universe / Marvel Comics", - "value": "6" - }, - { - "label": "Вселенная монстров / Monsterverse / Monster Verse", - "value": "905" - }, - { - "label": "Вселенная Стивена / Steven universe", - "value": "573" - }, - { - "label": "Вселенная Стрелы / Arrowverse", - "value": "488" - }, - { - "label": "Вселенная Тип Луны(Игровая компания) / Universe Type Moon", - "value": "1221" - }, - { - "label": "Вселенная DC / DC Universe / DC Comics", - "value": "36" - }, - { - "label": "Выпадение радиоактивных осадков / Fallout", - "value": "55" - }, - { - "label": "Выращивание онлайн / Cultivation Online", - "value": "1252" - }, - { - "label": "Галактическая секс-звезда / Galaxy Sex Star", - "value": "1539" - }, - { - "label": "Гало(Games) / Halo", - "value": "1338" - }, - { - "label": "Ганц / Gantz", - "value": "256" - }, - { - "label": "Гарем рабов в лабиринте другого мира / Slave Harem in the Labyrinth of the Other World", - "value": "1853" - }, - { - "label": "Гарри Поттер / Harry Potter", - "value": "1" - }, - { - "label": "Гвен-паук / Spider-Gwen", - "value": "920" - }, - { - "label": "Генерал маньяк с его сумасшедшей системой / The Maniacal General with his Crazy System", - "value": "1356" - }, - { - "label": "Генерал, вы вправе уйти. / General, You May Leave Now", - "value": "1385" - }, - { - "label": "Геншин Импакт / Genshin Impact", - "value": "689" - }, - { - "label": "Геркулес / Hercules", - "value": "721" - }, - { - "label": "Герои и замки / Heroes & Castles", - "value": "940" - }, - { - "label": "Герои меча и магии / Heroes of Might and Magic", - "value": "1002" - }, - { - "label": "Герои(телесериал) / Heroes", - "value": "864" - }, - { - "label": "Гильгамеш / Gilgamesh", - "value": "1143" - }, - { - "label": "Гинтама / Gintama", - "value": "129" - }, - { - "label": "Глубина(Фильм, 2002) / Below", - "value": "1186" - }, - { - "label": "Гнев Асуры / Asura's wrath", - "value": "100" - }, - { - "label": "Годзилла / Godzilla", - "value": "922" - }, - { - "label": "Голодные игры / The Hunger Games", - "value": "859" - }, - { - "label": "Горец / Highlander", - "value": "1761" - }, - { - "label": "Горожане(Games) / Townsmen", - "value": "1599" - }, - { - "label": "Госпожа Кагуя: в любви как на войне / Kaguya sama: Love is war", - "value": "533" - }, - { - "label": "Готика / Gothic", - "value": "418" - }, - { - "label": "Готов ли ты влюбиться в извращенку до тех пор, пока она милая? / Hentai demo Suki ni Natte Kuremasu ka", - "value": "1383" - }, - { - "label": "Гоэтия / Гоетия / Yοητεία / Ars Goetia", - "value": "772" - }, - { - "label": "Гравити Фолз / Gravity Falls", - "value": "491" - }, - { - "label": "Граница пустоты / Kara no Kyoukai", - "value": "1101" - }, - { - "label": "Гриффины / Family Guy", - "value": "349" - }, - { - "label": "Гром над небом / Thunder over the sky", - "value": "793" - }, - { - "label": "Гуррен-Лаганн / Tengen Toppa Gurren Lagann", - "value": "719" - }, - { - "label": "Да будет благословенен этот прекрасный мир! / Konosuba / Kono Subarashii Sekai ni Shukufuku wo!", - "value": "82" - }, - { - "label": "Да Здравствует Призыв! / Long Live Summons!", - "value": "948" - }, - { - "label": "Да, я паук, и что с того? / So I'm a Spider, So What? / Kumo Desu ga, Nani ka?", - "value": "910" - }, - { - "label": "Данганронпа / Danganronpa", - "value": "972" - }, - { - "label": "Две звезды Онмёджи / Sousei no Onmyouji", - "value": "1108" - }, - { - "label": "Дворянство / Благородство / Noblesse", - "value": "636" - }, - { - "label": "Девочка-волшебница Мадока Магика / Mahou Shoujo Madoka Magica", - "value": "1412" - }, - { - "label": "Девочка, которая видит это / Mieruko-chan", - "value": "1645" - }, - { - "label": "Декстер(телесериал) / Dexter", - "value": "1543" - }, - { - "label": "Демон Бездны всех царств / Abyss Demon of All Realms", - "value": "1419" - }, - { - "label": "Демоны старшей школы / High School DxD", - "value": "8" - }, - { - "label": "День независимости(Фильм, 1996) / Independence Day", - "value": "850" - }, - { - "label": "Детектив Конан / Detective Conan", - "value": "1554" - }, - { - "label": "Дети индиго из другого мира / Mondaiji-tachi ga isekai kara kuru sô desu yo", - "value": "1484" - }, - { - "label": "Джаггед Альянс 2: Агония Власти(Games) / Jagged Alliance 2", - "value": "1668" - }, - { - "label": "Джессика Джонс / Marvel's Jessica Jones", - "value": "1817" - }, - { - "label": "Джон Уик / John Wick", - "value": "388" - }, - { - "label": "Дисней / The Walt Disney Company", - "value": "503" - }, - { - "label": "Для тебя, Бессмертный / Fumetsu no Anata e / To Your Eternity", - "value": "1802" - }, - { - "label": "Дневник Будущего / Mirai Nikki", - "value": "368" - }, - { - "label": "Дневники вампира / The Vampire Diaries", - "value": "160" - }, - { - "label": "Доблесть рыцаря-неудачника / Chivalry of a Failed Knight", - "value": "1462" - }, - { - "label": "Добро пожаловать в ад, Ирума / Welcome to Demon School! Iruma-kun", - "value": "261" - }, - { - "label": "Добро пожаловать в класс превосходства / Classroom of the Elite", - "value": "122" - }, - { - "label": "Добро пожаловать! В лес похотливых эльфов! / Youkoso! Sukebe Elf no Mori e", - "value": "1034" - }, - { - "label": "Добывать ремесло / Майнкрафт / Minecraft", - "value": "102" - }, - { - "label": "Доктор Кто / Doctor Who", - "value": "277" - }, - { - "label": "Доктор Стоун / Dr. Stone", - "value": "720" - }, - { - "label": "Доля секунды: скорость / Split - second: velocity", - "value": "890" - }, - { - "label": "Дом кролика / Кофейня "Кроличий домик" / Gochuumon wa Usagi Desu ka?", - "value": "642" - }, - { - "label": "Домашний очаг / Hearthstone: Heroes of Warcraft / Hearthstone", - "value": "934" - }, - { - "label": "Домекано / Domestic Na Kanojo", - "value": "632" - }, - { - "label": "Дорогой звёзд / Звёздное преобразование / Stellar Transformation / Xing Chen Bian", - "value": "1155" - }, - { - "label": "Доспехи Бога 2: Операция Кондор / Armour of God II: Operation Condor", - "value": "1829" - }, - { - "label": "Дота 2 / Dota 2", - "value": "1105" - }, - { - "label": "Дофус / Dofus", - "value": "817" - }, - { - "label": "Дракенгард / Drakengard / Drag-On Dragoon", - "value": "919" - }, - { - "label": "Дракон-горничная госпожи Кобаяси / Kobayashi-san Chi no Maid Dragon", - "value": "673" - }, - { - "label": "Дракон-сама из семьи Касумигаока / Dragon-sama of the Kasumigaoka Family", - "value": "1458" - }, - { - "label": "Драконий жемчуг Зет / Dragon Ball Z", - "value": "307" - }, - { - "label": "Дракониум Онлайн / Draconic Online", - "value": "1360" - }, - { - "label": "Дракула / Dracula", - "value": "709" - }, - { - "label": "Древнегреческая мифология / Ancient Greek mythology", - "value": "1159" - }, - { - "label": "Дре́вние / Первородные / The Originals", - "value": "863" - }, - { - "label": "Древние свитки / The Elder Scrolls", - "value": "428" - }, - { - "label": "Древние свитки: Скайрим / TES: Skyrim", - "value": "337" - }, - { - "label": "Другой мир / Underworld", - "value": "480" - }, - { - "label": "Друид с Сеульской станции / Seoul Station Druid", - "value": "1178" - }, - { - "label": "Дьявол / Диабло / Diablo", - "value": "1787" - }, - { - "label": "Дьявол может плакать / Devil May Cry / DMC", - "value": "339" - }, - { - "label": "Дьявол Юраги-су / The Devil of Yuragi-sou", - "value": "431" - }, - { - "label": "Дьявол II(Games) / Диабло II / Diablo II", - "value": "1055" - }, - { - "label": "Дэдпул / Deadpool", - "value": "810" - }, - { - "label": "Дэнни-призрак / Danny Phantom", - "value": "109" - }, - { - "label": "Евангелион / Neon Genesis Evangelion", - "value": "583" - }, - { - "label": "Единство семи магов / Тринити: Семь Магов / Trinity Seven", - "value": "442" - }, - { - "label": "Еженедельный прыжок сёнэн / Weekly Shōnen Jump", - "value": "1629" - }, - { - "label": "Ёрмунганд / Jormungand", - "value": "77" - }, - { - "label": "Жажда скорости / Need For Speed", - "value": "1493" - }, - { - "label": "Железный человек / Iron Man", - "value": "710" - }, - { - "label": "Жемчуг дракона / Dragon Ball", - "value": "309" - }, - { - "label": "Женщина-Халк(телесериал) / She-Hulk: Attorney at Law", - "value": "1593" - }, - { - "label": "Жизнь девушки в игровом мире / A Girl’s Life In A Gaming World", - "value": "1406" - }, - { - "label": "Жизнь после / Days Gone", - "value": "1279" - }, - { - "label": "За гранью / Beyond the Boundary", - "value": "357" - }, - { - "label": "Загипнотизировать Семью / Kyonyuu Kazoku Saimin", - "value": "1032" - }, - { - "label": "Закон Уэки / The Law of Ueki", - "value": "790" - }, - { - "label": "Закулисье / Backrooms", - "value": "1827" - }, - { - "label": "Зачарованные / Charmed", - "value": "113" - }, - { - "label": "Защитники / Defenders", - "value": "1832" - }, - { - "label": "Защитница Химари / Omamori Himari", - "value": "279" - }, - { - "label": "Звёздная принцесса и силы зла\t / Стар против сил зла / Star vs. The Forces of Evil", - "value": "782" - }, - { - "label": "Звёздное дитя / Oshi no Ko", - "value": "1903" - }, - { - "label": "Звёздное ремесло / StarCraft", - "value": "386" - }, - { - "label": "Звездные Войны / Star Wars", - "value": "40" - }, - { - "label": "Звёздные войны: Войны клонов - Все типы носителей(мультсериал, 2008) / Star Wars: The Clone Wars", - "value": "1182" - }, - { - "label": "Звёздные врата / Stargate", - "value": "770" - }, - { - "label": "Звёздные врата: Атлантида / Stargate: Atlantis", - "value": "1097" - }, - { - "label": "Звездный путь / Стартрек / Star Trek", - "value": "849" - }, - { - "label": "Зверополис / Zootopia", - "value": "1449" - }, - { - "label": "Зеленая Жизнь / Green Life", - "value": "1196" - }, - { - "label": "Зеленый фонарь / The Green Lantern", - "value": "1222" - }, - { - "label": "Зетмен / Zetman", - "value": "1191" - }, - { - "label": "Игра в кальмара(телесериал) / Squid game", - "value": "1065" - }, - { - "label": "Игра престолов / Game of Thrones", - "value": "22" - }, - { - "label": "Игрок / The Gamer", - "value": "126" - }, - { - "label": "Идеальная судьба / The Perfect Destiny", - "value": "781" - }, - { - "label": "Идолмастер / The Idolmaster", - "value": "807" - }, - { - "label": "Иерихон Клайва Баркера / Иерихон / Clive Barker’s Jericho /Jericho", - "value": "320" - }, - { - "label": "Извивающийся дракон / Coiling Dragon", - "value": "692" - }, - { - "label": "Изгнаные королевства РПГ / Exiled Kingdoms RPG", - "value": "1375" - }, - { - "label": "Импульс Валькирии: Сирена / Варукири Дораиву: Сирена / Valkyrie Drive: Mermaid", - "value": "1736" - }, - { - "label": "Индекс волшебства / A Certain Magical Index", - "value": "68" - }, - { - "label": "Инуяша - Пес-демон / InuYasha", - "value": "481" - }, - { - "label": "Искусственный отбор / Triage X", - "value": "1037" - }, - { - "label": "Истинный мир боевых искусств / Zhenwu Shijie / True Martial World", - "value": "867" - }, - { - "label": "История монстров / Monogatari", - "value": "911" - }, - { - "label": "История о второстепенном персонаже который стал игроком в другой игре. / The story is about a minor character who became a player in another game.", - "value": "868" - }, - { - "label": "Кабанери железной крепости / Koutetsujou no Kabaneri", - "value": "1494" - }, - { - "label": "Каждый раз, когда я сплю, моя душа покидает мое тело / Every Day I Sleep, My Soul Goes Out of My Body", - "value": "1048" - }, - { - "label": "Как воспитать героиню из обычной девушки / Saenai Heroine no Sodatekata", - "value": "1637" - }, - { - "label": "Как игрок глупой FPS попал в иной мир / Как дурачок из стрелялки в другой мир попал / Manuke na FPS Player ga Isekai e Ochita Baai", - "value": "746" - }, - { - "label": "Как приручить дракона / How to Train Your Dragon", - "value": "687" - }, - { - "label": "Капитан Америка / Captain America", - "value": "1425" - }, - { - "label": "Капитан Марвел(Фильм, 2019) / Captain Marvel", - "value": "1594" - }, - { - "label": "Каратель / The Punisher", - "value": "387" - }, - { - "label": "Касл / Castle", - "value": "389" - }, - { - "label": "Касльвания / Castlevania", - "value": "1215" - }, - { - "label": "Катаклизм: Тёмные дни впереди / DDA / Cataclysm: Dark Days Ahead", - "value": "680" - }, - { - "label": "Квайзер со Стигматом / Адепт Святого Знака / The Qwaser of Stigmata", - "value": "72" - }, - { - "label": "Квартет из альтернативного мира / Isekai Quartet", - "value": "1801" - }, - { - "label": "Квест Девушки-монстра / Monster Girl Questt", - "value": "928" - }, - { - "label": "Квест титана(Games) / Титанический квест / Titan Quest", - "value": "1483" - }, - { - "label": "Кенши(Games) / Kenshi", - "value": "1230" - }, - { - "label": "Киберпанк 2077 / Cyberpunk 2077", - "value": "416" - }, - { - "label": "Ким Пять-с-плюсом / Kim Possible", - "value": "436" - }, - { - "label": "Киру ра Киру / Круши Кромсай / Убей или умри / Kill la Kill", - "value": "763" - }, - { - "label": "Класс убийц / Assassination classroom", - "value": "610" - }, - { - "label": "Клеймор / Claymore", - "value": "110" - }, - { - "label": "Клинок зла / Evil Blade / Übel Blatt", - "value": "722" - }, - { - "label": "Клинок королевы / Queen’s Blade", - "value": "757" - }, - { - "label": "Клинок Маню: Тайна сисечного свитка / Manyuu Hiken-chou", - "value": "501" - }, - { - "label": "Клинок рассекающий демонов / Demon Slayer: Kimetsu no Yaiba", - "value": "21" - }, - { - "label": "Клуб Винкс / Winx Club", - "value": "397" - }, - { - "label": "Книга джунглей / The Jungle Book", - "value": "1688" - }, - { - "label": "Князь тьмы с задней парты / Demon King Daimao / Ichiban Ushiro no Daimaou", - "value": "1207" - }, - { - "label": "Код Гиас / Code Geass", - "value": "340" - }, - { - "label": "Код Квалидеи / Qualidea Code", - "value": "76" - }, - { - "label": "Кольцо Элдена / Elden Ring", - "value": "1408" - }, - { - "label": "Комната / The Room", - "value": "889" - }, - { - "label": "Конь и клинок: Боевой отряд(Games) / Mount and Blade:Warband", - "value": "1477" - }, - { - "label": "Королевства Сердец / Kingdom Hearts", - "value": "407" - }, - { - "label": "Короли крестоносцев / Crusader kings", - "value": "572" - }, - { - "label": "Король бойцов / The King of Fighters", - "value": "1378" - }, - { - "label": "Король лев / The Lion king", - "value": "1705" - }, - { - "label": "Король Шаманов / Shaman King", - "value": "744" - }, - { - "label": "Корона греха / Guilty Crown", - "value": "1007" - }, - { - "label": "Корпорация лоботомии / Lobotomy corporation", - "value": "852" - }, - { - "label": "Космические рейнджеры(Games) / Space Rangers", - "value": "1508" - }, - { - "label": "Кошечка из Сакурасо / Sakurasou no Pet na Kanojo", - "value": "605" - }, - { - "label": "Красавица и чудовище / Beauty and the Beast", - "value": "1765" - }, - { - "label": "Красная угроза 3 / Command & Conquer: Red Alert 3", - "value": "742" - }, - { - "label": "Красный, Белый, Черный, Желтый / RWBY", - "value": "131" - }, - { - "label": "Кредо убийцы / Assassin's Creed", - "value": "690" - }, - { - "label": "Кризис / Crysis", - "value": "1734" - }, - { - "label": "Крушитель / The Breaker", - "value": "1080" - }, - { - "label": "Кунг-фу панда / Kung Fu Panda", - "value": "831" - }, - { - "label": "Кэйон! / K-On!", - "value": "1785" - }, - { - "label": "Кэнган Асура / Kengan Asura", - "value": "726" - }, - { - "label": "Лаборатория Декстера / Dexter Lab", - "value": "639" - }, - { - "label": "Лавкрафт / Говард Филлипс Лавкрафт / Howard Phillips Lovecraft", - "value": "1259" - }, - { - "label": "Легенда о восьми псах востока / Hakkenden: Touhou Hakken Ibun", - "value": "1699" - }, - { - "label": "Легенда о Зельде / The Legend of Zelda", - "value": "870" - }, - { - "label": "Легенда о Короле Драконов / Legend of the Dragon King", - "value": "623" - }, - { - "label": "Легенда о Легендарных Героях / Densetsu no Yuusha no Densetsu", - "value": "193" - }, - { - "label": "Легион Супергероев / The Legion of Super-Heroes", - "value": "450" - }, - { - "label": "Леди Баг и Супер-Кот / Miraculous Ladybug", - "value": "327" - }, - { - "label": "Летняя сага / Summertime Saga", - "value": "1441" - }, - { - "label": "Лига Легенд / League of Legends", - "value": "65" - }, - { - "label": "Линия фронта для девочек / Girls' Frontline", - "value": "1686" - }, - { - "label": "Литературный клуб Доки Доки / Литературный клуб / Doki Doki literature club!", - "value": "819" - }, - { - "label": "Лорд героев(Games) / Lord of Heroes", - "value": "1771" - }, - { - "label": "Лорд человечества / Lord of the People", - "value": "1896" - }, - { - "label": "Лориенская Сага / Lorien Legacies", - "value": "521" - }, - { - "label": "Любимая жена господина генерального директора / Mr.CEO's Beloved Wife", - "value": "1389" - }, - { - "label": "Любовные неприятности / To love ru", - "value": "353" - }, - { - "label": "Любовь, Деньги, Рок-н-Ролл / Love, Money, Rock'n'Roll", - "value": "1890" - }, - { - "label": "Люди в чёрном(Фильм) / Men in Black", - "value": "1193" - }, - { - "label": "Люди Икс / X-Men", - "value": "371" - }, - { - "label": "Лютер Строуд Сага / The Luther Strode Saga", - "value": "1700" - }, - { - "label": "Люцифер(телесериал) / Lucifer", - "value": "681" - }, - { - "label": "Маг на полную ставку / Quanzhi Fashi", - "value": "291" - }, - { - "label": "Маг смерти не желающий четвертой реинкарнации / The Death Mage Who Doesn’t Want a Fourth Time", - "value": "1775" - }, - { - "label": "Маг-целитель: Новый старт / Kaifuku Jutsushi no Yarinaoshi", - "value": "1311" - }, - { - "label": "Маги: Волшебный лабиринт / Magi: The Labyrinth of Magic", - "value": "1581" - }, - { - "label": "Магистр дьявольского культа / The Grandmaster of Demonic Cultivation", - "value": "608" - }, - { - "label": "Магическая академия Атараксия: Гибрид х Сердце / Hybrid x Heart Magias Academy Ataraxia", - "value": "1898" - }, - { - "label": "Магическая битва / Magic Battle / Jujutsu Kaisen", - "value": "671" - }, - { - "label": "Маленькие кошмары 2 / Little Nightmares 2", - "value": "601" - }, - { - "label": "Малефисента / Maleficent", - "value": "775" - }, - { - "label": "Мальчик с оленьими рогами / Сладкоежка / Sweet tooth", - "value": "1772" - }, - { - "label": "Маска / The mask", - "value": "847" - }, - { - "label": "Мастер Урадана / The Master of Uradan", - "value": "1395" - }, - { - "label": "Мастера меча онлайн / Sword Art Online / SAO", - "value": "324" - }, - { - "label": "Межвидовые Рецензенты / Interspecies Reviewers", - "value": "1555" - }, - { - "label": "Менеджер среднего звена Тонэгава / Chuukan Kanriroku Tonegawa", - "value": "1084" - }, - { - "label": "Мерлин / Merlin", - "value": "486" - }, - { - "label": "Мертвы к Рассвету / Dead by Daylight", - "value": "899" - }, - { - "label": "Мертвый или живой / Dead or Alive", - "value": "1563" - }, - { - "label": "Мертвый остров / Dead Island", - "value": "124" - }, - { - "label": "Месть Масамуне-куна! / Masamune-kun no Revenge", - "value": "571" - }, - { - "label": "Метавселенная Рудазова / Rudazov's Metauniverse", - "value": "1211" - }, - { - "label": "Метро 2033(Games) / Metro 2033", - "value": "1584" - }, - { - "label": "Милый во Франксе / Любимый во Франксе / Darling in the Franxx", - "value": "942" - }, - { - "label": "Мир боевых искусств / 武极天下 / Wuji Tianxia / Martial World", - "value": "620" - }, - { - "label": "Мир зомби / Zombie World", - "value": "1880" - }, - { - "label": "Мир Льда и Пламени / The World of Ice & Fire", - "value": "415" - }, - { - "label": "Мир приключений Джеки Чана(мультсериал, 2000) / ackie Chan Adventures", - "value": "1544" - }, - { - "label": "Мир танков / WoT Blitz / World of Tanks Blitz", - "value": "525" - }, - { - "label": "Мир Тьмы / World of Darkness", - "value": "145" - }, - { - "label": "Мир Эрастай / The World of Erasthay", - "value": "1836" - }, - { - "label": "Мир Warcraft / World of Warcraft", - "value": "89" - }, - { - "label": "Мировая война Z / Война миров Z / World War Z", - "value": "1217" - }, - { - "label": "Моана / Moana", - "value": "686" - }, - { - "label": "Моб психо 100 / Mob Psycho 100", - "value": "866" - }, - { - "label": "Мобильные легенды: Бах-Бах(Games) / Mobile Legends: Bang Bang", - "value": "1497" - }, - { - "label": "Могучие рейнджеры / Power Rangers", - "value": "1486" - }, - { - "label": "Может, я встречу тебя в подземелье? / DanMachi", - "value": "9" - }, - { - "label": "Мой жених сбежал / My Groom Ran Away", - "value": "1047" - }, - { - "label": "Мой маленький пони / My Little Pony", - "value": "655" - }, - { - "label": "Мой маленький пони: Дружба — это чудо / My Little Pony: Friendship is Magic", - "value": "658" - }, - { - "label": "Мой шумный дом(мультсериал, 2016) / The Loud House", - "value": "1467" - }, - { - "label": "Монстер Хай / Monster High", - "value": "1012" - }, - { - "label": "Моя возлюбленная чпокается со всеми / Kanojo wa Dare to demo Sex Sur", - "value": "1274" - }, - { - "label": "Моя геройская академия / Boku no Hero Academia", - "value": "69" - }, - { - "label": "Моя девушка - зомби / My Girlfriend is a Zombie", - "value": "754" - }, - { - "label": "Моя жена - красивый генеральный директор / My Wife is a Beautiful CEO", - "value": "1025" - }, - { - "label": "Моя жена — президент студенческого совета! / My Wife is the Student Council President / Okusama ga Seitokaichou", - "value": "241" - }, - { - "label": "Моя Марвел Академия / My marvel academia", - "value": "696" - }, - { - "label": "Моя первая модница / Hajimete no Gal", - "value": "1835" - }, - { - "label": "Моя Супер-Бывшая / My Super Ex-Girlfriend", - "value": "1828" - }, - { - "label": "Мрачный рассвет / Grim Dawn", - "value": "1113" - }, - { - "label": "Мстители / The Avengers", - "value": "1747" - }, - { - "label": "Мстители. Эра Альтрона / The Avengers. Age of Ultron", - "value": "784" - }, - { - "label": "Мулан / Mulan", - "value": "706" - }, - { - "label": "Мы не можем учится / Bokutachi wa Benkyou ga Dekinai", - "value": "912" - }, - { - "label": "Мэй Гунцин / Mei Gongqing", - "value": "753" - }, - { - "label": "Наблюдать / Overwatch", - "value": "607" - }, - { - "label": "Надпись / Inscription", - "value": "1718" - }, - { - "label": "Нам Ён / Nam Yeon", - "value": "1188" - }, - { - "label": "Наруто / Naruto", - "value": "3" - }, - { - "label": "Начало после конца / The Beginning After The End", - "value": "888" - }, - { - "label": "Не голодай / Don't Starve", - "value": "274" - }, - { - "label": "Не издевайся надо мной, Нагаторо / Ijiranaide / Nagatoro-san Don't Toy with Me, Miss Nagatoro", - "value": "1041" - }, - { - "label": "Не люблю боль, так что вкачаю все в защиту / Itai no wa Iya nano de Bougyoryoku ni Kyokufuri Shitai to Omoimasu", - "value": "517" - }, - { - "label": "Не моя вина, что я непопулярна! / Watashi ga Motenai no wa Dou Kangaetemo Omaera ga Warui", - "value": "1381" - }, - { - "label": "Небесный замок Лапута / Tenkuu no Shiro Laputa", - "value": "1109" - }, - { - "label": "Невероятные приключения ДжоДжо / JoJo's Bizarre Adventure", - "value": "20" - }, - { - "label": "Негодник, которому не снилась девочка-зайка / Rascal Does Not Dream of Bunny Girl Senpai", - "value": "1897" - }, - { - "label": "Негодяй спасает мужскую роль / The Villain Saves the Male Lead", - "value": "1224" - }, - { - "label": "Неизвестен / Persona", - "value": "205" - }, - { - "label": "Некий магический индекс / To Aru Majutsu no Index", - "value": "562" - }, - { - "label": "Некий научный акселератор / Toaru Kagaku no Accelerator", - "value": "1487" - }, - { - "label": "Ненасытный Берсерк / Boushoku no Berserk: Ore dake Level to Iu Gainen wo Toppa suru the Comic", - "value": "1195" - }, - { - "label": "Необъятные небеса / Infinite Stratos / IS", - "value": "280" - }, - { - "label": "Необъятный океан / Grand Blue", - "value": "531" - }, - { - "label": "Непревзойденная / Master Piece The Animation", - "value": "712" - }, - { - "label": "Непризнанный школой владыка демонов / Maou Gakuin no Futekigousha", - "value": "1476" - }, - { - "label": "Непутевый ученик в школе магии / Mahouka Koukou No Rettousei", - "value": "982" - }, - { - "label": "Непутевый ученик в школе магии / The Irregular at Magic High School", - "value": "630" - }, - { - "label": "Несокрушимая механическая кукла / Machine-Doll wa Kizutsukanai", - "value": "1030" - }, - { - "label": "Несправедливость / Injustice", - "value": "1026" - }, - { - "label": "Нет игры - нет жизни / Без игры жизни нет / No Game No Life", - "value": "718" - }, - { - "label": "Неуязвимый / Invincible", - "value": "702" - }, - { - "label": "НиоХ(Games) / NioH", - "value": "1465" - }, - { - "label": "Новый завет Владыки тьмы / Shinmai Maou no Testament", - "value": "1432" - }, - { - "label": "Ну и ну! Земляничные яйца / I My Me! Strawberry Eggs", - "value": "1485" - }, - { - "label": "Нулевой Уровень Целомудрия / Teisou Kannen Zero", - "value": "1209" - }, - { - "label": "О моём перерождении в меч / Tensei Shitara Ken deshita", - "value": "53" - }, - { - "label": "О моём перерождении в слизь / Tensei shitara Slime Datta Ken", - "value": "64" - }, - { - "label": "О моя Богиня / Aa! Megami-sama! / Ah! My Goddess", - "value": "915" - }, - { - "label": "Обесчещенный(Games) / Dishonored", - "value": "1073" - }, - { - "label": "Обитель зла / Resident Evil", - "value": "86" - }, - { - "label": "Огненная эмблема / Fire Emblem", - "value": "1615" - }, - { - "label": "Огненная эмблема: Пробуждение / Fire Emblem: Awakening", - "value": "1616" - }, - { - "label": "Огненная эмблема: Три Дома / Fire Emblem:Three Houses", - "value": "1716" - }, - { - "label": "Одинокий рокер! / Bocchi the Rock!", - "value": "1904" - }, - { - "label": "Одному лишь Богу ведомый мир / World God Only Knows", - "value": "1248" - }, - { - "label": "Она становится гламурной после расторжения помолвки / She gets glamorous after the engagement is annulled", - "value": "1404" - }, - { - "label": "Орк-рубака / Orc Grunt", - "value": "779" - }, - { - "label": "Освободите эту ведьму / Release that witch", - "value": "994" - }, - { - "label": "Острые козырьки(телесериал) / Peaky Blinders", - "value": "1177" - }, - { - "label": "От заката до рассвета! / From Dusk till Dawn!", - "value": "1416" - }, - { - "label": "Отброс из семьи графа / Trash of counts family", - "value": "853" - }, - { - "label": "Отряд самоубийц / The Suicide Squad", - "value": "1844" - }, - { - "label": "Отчаянные домохозяйки / Desperate Housewives", - "value": "1011" - }, - { - "label": "Отчет о буйстве духов / YuYu Hakusho", - "value": "1008" - }, - { - "label": "Охота демонического короля на свою жену / Xie Wang Zhui Qi", - "value": "1737" - }, - { - "label": "Охотник х Охотник / Hunter x Hunter", - "value": "101" - }, - { - "label": "Охотницы на демонов / Taimanin Asagi", - "value": "1463" - }, - { - "label": "Очень приятно Бог! / Kamisama Hajimemashita", - "value": "1585" - }, - { - "label": "Очень Странные Дела(телесериал) / Stranger Things", - "value": "1834" - }, - { - "label": "ПАЗЛ / PUZZLE", - "value": "1762" - }, - { - "label": "Палач Рока / DOOM", - "value": "132" - }, - { - "label": "Параграф 78(Фильм) / Paragraph 78", - "value": "923" - }, - { - "label": "Паразит: Учение о жизни / Parasyte: The Maxim", - "value": "1176" - }, - { - "label": "Пастырь(Фильм, 2011) / Priest", - "value": "1173" - }, - { - "label": "Пацаны / The Boys", - "value": "133" - }, - { - "label": "Первый детский сад во вселенной / The First Kindergarten in the Universe", - "value": "1049" - }, - { - "label": "Перевозчик / Le Transporteur", - "value": "365" - }, - { - "label": "Передающийся через кровь / Bloodborne", - "value": "229" - }, - { - "label": "Пережить / Outlast", - "value": "645" - }, - { - "label": "Перерождение / Rebirth", - "value": "550" - }, - { - "label": "Перерождение бессмертного горожанина-культиватора / Rebirth – City Cultivation / Rebirth of the Urban Immortal Cultivator", - "value": "843" - }, - { - "label": "Перерождение в монстра / Re:Monster", - "value": "85" - }, - { - "label": "Перестрой мир / Sekai O Sai Kochiku / Rebuild World", - "value": "961" - }, - { - "label": "Период полураспада(Valve) / Half-Life", - "value": "895" - }, - { - "label": "Перси Джексон / Percy Jackson", - "value": "308" - }, - { - "label": "Персона 5 / Persona 5", - "value": "1614" - }, - { - "label": "Печать ветра / Kaze no Stigma", - "value": "845" - }, - { - "label": "Пик боевых искусств / Martial Peak", - "value": "414" - }, - { - "label": "Пираты Карибского моря / Pirates of the Caribbean", - "value": "932" - }, - { - "label": "Пираты черной лагуны / Black Lagoon", - "value": "621" - }, - { - "label": "Пламенная бригада пожарных / Fire Force / Enen no Shouboutai", - "value": "841" - }, - { - "label": "Пламя бесчисленых невзгод / I' m really not demon god's lackey", - "value": "1452" - }, - { - "label": "Планетарная аннигиляция / Planetary Annihilation", - "value": "487" - }, - { - "label": "Плоскостной пейзаж: Мучение / Planescape: Torment", - "value": "1768" - }, - { - "label": "По велению адской сестры / The Testament of Sister New Devil", - "value": "18" - }, - { - "label": "Поборники тьмы / Darksiders", - "value": "1028" - }, - { - "label": "Повар небесной гостиницы / Чем кормят в ином мире / Kakuriyo no Yadomeshi", - "value": "998" - }, - { - "label": "Повар-боец Сома / В поисках божественного рецепта / Shokugeki no Souma", - "value": "191" - }, - { - "label": "Повелитель тьмы на подработке! / Hataraku Maou-sama!", - "value": "674" - }, - { - "label": "Повелитель тьмы: Другая история мира / How Not to Summon a Demon Lord / Isekai Maou to Shoukan Shoujo no Dorei Majutsu", - "value": "699" - }, - { - "label": "Повелитель(Куганэ Маруяма) / Overlord", - "value": "27" - }, - { - "label": "Повелитель(Games) / Overlord", - "value": "1623" - }, - { - "label": "Повесть о Конце Света / Record of Ragnarok", - "value": "332" - }, - { - "label": "Повесть о лунной принцессе / Tsukihime: Lunar Legend", - "value": "750" - }, - { - "label": "Повесть о Небесных островах / Фэнтези Гранблю / Granblue Fantasy", - "value": "808" - }, - { - "label": "Повседневная жизнь бессмертного короля / The Daily Life of the Immortal King / Xian Wang de Richang Shenghuo", - "value": "1466" - }, - { - "label": "Повседневная жизнь с девушкой-монстром / Monster Musume", - "value": "760" - }, - { - "label": "Пограничье(Games) / Borderlands", - "value": "992" - }, - { - "label": "Под лунами Драконьих глаз / Beneath the Dragoneye Moons", - "value": "1735" - }, - { - "label": "Подземелья и драконы / Dungeons & Dragons", - "value": "81" - }, - { - "label": "Подземная история / Андертейл / Undertale", - "value": "390" - }, - { - "label": "Поднявшийся(Games) / Risen", - "value": "1273" - }, - { - "label": "Поднятие уровня в одиночку / Solo Leveling", - "value": "127" - }, - { - "label": "Подручный Луизы-Нулизы / Zero no Tsukaima", - "value": "580" - }, - { - "label": "Пожиратель богов / God Eater", - "value": "1321" - }, - { - "label": "Поймай себя ! Моя дорогая жена / Catch You ! My Dear Wife", - "value": "1317" - }, - { - "label": "Покемон / Pokemon", - "value": "43" - }, - { - "label": "Политическая Хроника Молодой Девушки / A Young Woman's Political Record", - "value": "1306" - }, - { - "label": "Полностью пленённые / Totally Captivated", - "value": "1086" - }, - { - "label": "Полый Рыцарь(Games) / Hollow Knight", - "value": "1198" - }, - { - "label": "Пользователи Силы / Forceusers", - "value": "1162" - }, - { - "label": "Поля битвы Неизвестного игрока / ПАБГ / Player Unknown's Battlegrounds / PUBG", - "value": "622" - }, - { - "label": "Попытка приручить злого повелителя / Trying to Tame an Evil Overlord", - "value": "983" - }, - { - "label": "Поработитель Ада / Helltaker", - "value": "776" - }, - { - "label": "Порновселенная / Porn Universe", - "value": "1776" - }, - { - "label": "Портал(Valve) / Portal", - "value": "800" - }, - { - "label": "Последние из нас / Last Of Us", - "value": "1717" - }, - { - "label": "Последний Серафим / Owari no Seraph", - "value": "551" - }, - { - "label": "Последняя из рода Блау(Тайга Ри) / The last of the Blau family", - "value": "1507" - }, - { - "label": "Последняя фантазия / ファイナルファンタジ / Final Fantasy", - "value": "769" - }, - { - "label": "Преподобное безумие / Reverend Insanity", - "value": "1280" - }, - { - "label": "Преподобный Гу / Gu Zhen Ren / Daoist Gu", - "value": "1464" - }, - { - "label": "Призрачный бегун / Ghostrunner", - "value": "613" - }, - { - "label": "Призрачный гонщик / Ghost Rider", - "value": "823" - }, - { - "label": "Принц Драконов Хаоса / The Chaos Dragon Prince", - "value": "1397" - }, - { - "label": "Принц Персии / Prince of Persia", - "value": "1535" - }, - { - "label": "Принцесса монстров / Princess Resurrection", - "value": "1304" - }, - { - "label": "Принцесса Цу / Не проиграю! / Maken Ki", - "value": "675" - }, - { - "label": "Проект „Восток“ / Touhou Project", - "value": "809" - }, - { - "label": "Проект Кей / K Project", - "value": "73" - }, - { - "label": "Проклятие: Автоматизация / NieR:Automata", - "value": "1496" - }, - { - "label": "Противостояние святого / Renegade Immortal", - "value": "926" - }, - { - "label": "Прототип / Prototype", - "value": "54" - }, - { - "label": "Пуленепробиваемый / Bang-Tan / BTS", - "value": "520" - }, - { - "label": "Путешествие на Запад / Journey to the West", - "value": "1833" - }, - { - "label": "Пять невест / Go-Toubun no Hanayome", - "value": "713" - }, - { - "label": "Пять ночей у Фредди / Five nights at freddy's", - "value": "930" - }, - { - "label": "Рагнарёк Онлайн / Ragnarok Online", - "value": "953" - }, - { - "label": "Радуга 6: Осада / Rainbow Six: Siege", - "value": "421" - }, - { - "label": "Развращение Дочери / Daraku Reijou Hakoiri Ojou-sama Netorare Choukyou Kiroku", - "value": "1284" - }, - { - "label": "Рай Грисайи / Эдем в серых тонах / Grisaia no Rakuen", - "value": "584" - }, - { - "label": "Рандеву с жизнью / Date A live", - "value": "851" - }, - { - "label": "Ранма ½ / Ranma ½", - "value": "1192" - }, - { - "label": "Рапунцель: Запутанная история / Tangled", - "value": "773" - }, - { - "label": "Расколотая битвой синева небес / Battle Through the Heavens", - "value": "927" - }, - { - "label": "Рассказ служанки / The Handmaid's Tale", - "value": "1135" - }, - { - "label": "Расхитительница гробниц / Tomb Raider", - "value": "988" - }, - { - "label": "Резатель / Лангриссер / Langrisser", - "value": "792" - }, - { - "label": "Реинкарнация безработного / Mushoku Tensei", - "value": "569" - }, - { - "label": "Реинкарнация Богини / Megami Tensei", - "value": "1161" - }, - { - "label": "Репликант НиеР / NieR Replicant / NieR Gestalt", - "value": "1299" - }, - { - "label": "Рецеттия: Повесть о магазине предметов / Recettear: An Item Shop's Tale", - "value": "858" - }, - { - "label": "Ривердэйл / Riverdale", - "value": "637" - }, - { - "label": "Рик и Морти / Rick and Morty", - "value": "315" - }, - { - "label": "Розарий и Вампир / Rosario+Vampire", - "value": "83" - }, - { - "label": "Розовая пора моей школьной жизни сплошной обман / Yahari Ore no Seishun Love Come wa Machigatteiru", - "value": "856" - }, - { - "label": "Рок шоу! / Show By Rock!!", - "value": "344" - }, - { - "label": "Русалочка / The Little Mermaid", - "value": "892" - }, - { - "label": "Рыцарь и маг / Knight's & Magic", - "value": "1491" - }, - { - "label": "Сага о Винланде / Vinland Saga", - "value": "1200" - }, - { - "label": "Садистская смесь / Blend S", - "value": "1120" - }, - { - "label": "Сайт волшебниц / Mahou Shoujo Site", - "value": "909" - }, - { - "label": "Сверхъестественное(телесериал) / Supernatural", - "value": "916" - }, - { - "label": "Связь принцесс: повторное погружение / Princess Connect! Re:Dive", - "value": "1481" - }, - { - "label": "Святые / Saints Row", - "value": "1390" - }, - { - "label": "Сейлор Мун / Sailor Moon", - "value": "114" - }, - { - "label": "Секире: Тени Умирают Дважды / Sekiro: Shadows Die Twice", - "value": "1076" - }, - { - "label": "Семь смертных грехов / Nanatsu no Taizai", - "value": "61" - }, - { - "label": "Семья шпиона / Spy x Family", - "value": "1646" - }, - { - "label": "Сердца Пандоры / Pandora Hearts", - "value": "497" - }, - { - "label": "Серия Метроидов / Metroid Series", - "value": "1612" - }, - { - "label": "Серый человек / Ди: Гурэйман / D.Gray-man", - "value": "367" - }, - { - "label": "Си Тянь Гуань / Si Tian Guan", - "value": "1189" - }, - { - "label": "Сильнейший в истории ученик Кэнити / Shijou Saikyou no Deshi Kenichi", - "value": "242" - }, - { - "label": "Сильнейший в истории ученик Кэнъити / KenIchi: The Mightiest Disciple", - "value": "745" - }, - { - "label": "Сильнейший магнат / The Strongest Tycoon", - "value": "1340" - }, - { - "label": "Сильнейший мудрец низшей эмблемы / Shikkakumon no Saikyou Kenja", - "value": "1472" - }, - { - "label": "Симпсоны / The Simpsons", - "value": "1461" - }, - { - "label": "Симс / The Sims", - "value": "654" - }, - { - "label": "Симфония морской стали / Aoki Hagane no Arpeggio", - "value": "958" - }, - { - "label": "Сингулярность(Games) / Singularity", - "value": "1793" - }, - { - "label": "Синий Архив / Blue Archive", - "value": "1411" - }, - { - "label": "Синий экзорцист / Blue Exorcist", - "value": "312" - }, - { - "label": "Синяя Тюрьма: Блю Лок / Blue Lock", - "value": "1792" - }, - { - "label": "Система Богов и Демонов / God and Devil World", - "value": "1648" - }, - { - "label": "Система Спаси-Себя-Сам / The Scum Villain's Self-Saving System: Ren Zha Fanpai Zijiu Xitong", - "value": "1505" - }, - { - "label": "Система: Восьмой уровень(Д. Серебряков) / System: Eighth level", - "value": "1175" - }, - { - "label": "Сисястая Принцесса под гипнозом / Kyonyuu Princess Saimin", - "value": "1618" - }, - { - "label": "Сказание о Демонах и Богах / Tales of Demons and Gods", - "value": "59" - }, - { - "label": "Сказание о Тёмном Рыцаре ~ Призван, чтобы одолеть Героя ~ / Tale of Dark Knight~Summoned to Defeat The Hero~", - "value": "1647" - }, - { - "label": "Сказки хранителей(Games) / Guardian tales", - "value": "1068" - }, - { - "label": "Скрытая Похотливая Натура Моих Русских Сестренок и Мачехи / Muttsuri do Sukebe ro Gibo Shimai", - "value": "1282" - }, - { - "label": "Скуби-Ду / Scooby-Doo", - "value": "638" - }, - { - "label": "Скучный мир, где не существует самой идеи похабных шуток / Shimoneta to Iu Gainen ga Sonzai Shinai Taikutsu na Sekai", - "value": "830" - }, - { - "label": "Сладкая жизнь / Happy Sugar Life", - "value": "1099" - }, - { - "label": "Сладкий флирт / Amour Sucré / Sweet Crush", - "value": "495" - }, - { - "label": "Сладости и Сигареты / Candy & Cigarettes", - "value": "778" - }, - { - "label": "Следопыт Гнев Праведников / Pathfinder Wrath Of The Righteous", - "value": "1077" - }, - { - "label": "Следопыт: Творец королей / Pathfinder: Kingmaker", - "value": "1770" - }, - { - "label": "Смертельная битва / Мортал Комбат / Mortal Kombat", - "value": "806" - }, - { - "label": "Смертельный укус", - "value": "1902" - }, - { - "label": "Созданный в бездне / Made in Abyss", - "value": "952" - }, - { - "label": "Сок джунглей", - "value": "1901" - }, - { - "label": "Сокрушитель: Новые волны / The Breaker: New Waves", - "value": "1500" - }, - { - "label": "Соник еж / Sonic the hedgehog", - "value": "1052" - }, - { - "label": "Сорвиголова / Daredevil", - "value": "1690" - }, - { - "label": "Сотня / Hundred", - "value": "885" - }, - { - "label": "Спаун / Spawn", - "value": "1254" - }, - { - "label": "Спецагент Арчер / Archer", - "value": "624" - }, - { - "label": "Специалист по апгрейду из другого мира / Endless Sea of Clouds ESC", - "value": "1499" - }, - { - "label": "Спираль / Удзумаки / Uzumaki", - "value": "1164" - }, - { - "label": "СТАЛКЕР / STALKER / S.T.A.L.K.E.R", - "value": "677" - }, - { - "label": "Стальная тревога / Full Metal Panic! The Second Raid", - "value": "1489" - }, - { - "label": "Стальной алхимик / Fullmetal Alchemist", - "value": "1123" - }, - { - "label": "Стальной Гигант / The Iron Giant", - "value": "1241" - }, - { - "label": "Становление богом / Bai Lian Cheng Shen", - "value": "1315" - }, - { - "label": "Старгерл / Stargirl", - "value": "1137" - }, - { - "label": "Стелларис / Stellaris", - "value": "1098" - }, - { - "label": "Сторожевые Псы / Watch Dogs", - "value": "1886" - }, - { - "label": "Стражи Галактики / Guardians of the Galaxy", - "value": "1426" - }, - { - "label": "Страна Самоцветов / Houseki no Kuni", - "value": "1305" - }, - { - "label": "Страна чудес смертников / Зона-парк смертников / Deadman Wonderland", - "value": "857" - }, - { - "label": "Страношары / Кантриболз / Countryballs", - "value": "1895" - }, - { - "label": "Студии 20-й век / 20th Century Studios", - "value": "1715" - }, - { - "label": "Судьба / Fate", - "value": "1740" - }, - { - "label": "Судьба: Апокриф / Fate: Apocrypha", - "value": "231" - }, - { - "label": "Судьба: Великий Орден / Fate: Grand Order", - "value": "60" - }, - { - "label": "Судьба: Девочка волшебница Илия / Fate: Kaleid Liner Prisma", - "value": "789" - }, - { - "label": "Судьба: Истоки / Fate: Zero", - "value": "230" - }, - { - "label": "Судьба: Ночь схватки / Fate: Stay Night", - "value": "536" - }, - { - "label": "Сумерки / Twilight", - "value": "471" - }, - { - "label": "Супер ген бога / Super God Gene", - "value": "316" - }, - { - "label": "Супер Марио / Super Mario", - "value": "1661" - }, - { - "label": "Супергёрл(телесериал, 2015) / Supergirl", - "value": "1088" - }, - { - "label": "Супермедицинский ниндзя / Super medical ninja", - "value": "1391" - }, - { - "label": "Суперсемейка / The Incredibles", - "value": "306" - }, - { - "label": "Сэкирэй / Sekirei", - "value": "111" - }, - { - "label": "Тада не может влюбиться! / Tada-kun wa koi wo shinai!", - "value": "1905" - }, - { - "label": "Тайны Смолвиля / Smallville", - "value": "449" - }, - { - "label": "Танец клинка Элементалиста / Seireitsukai no Blade Dance", - "value": "1498" - }, - { - "label": "Твоя апрельская ложь / Your lie in april", - "value": "532" - }, - { - "label": "Те, кто охотятся на эльфов / エルフを狩るモノたち / Those Who Hunt Elves", - "value": "1168" - }, - { - "label": "Темнейшее подземелье / Darkest dungeon", - "value": "1405" - }, - { - "label": "Темные Души / Dark Souls", - "value": "200" - }, - { - "label": "Темный Ангел / Dark Angel", - "value": "1010" - }, - { - "label": "Тёмный Дворецкий / Kuroshitsuj / Dark Butler", - "value": "411" - }, - { - "label": "Темный дворецкий / Kuroshitsuji", - "value": "1043" - }, - { - "label": "Темный призыватель Апокалипсиса / The Dark Summoner of the Apocalypse", - "value": "1407" - }, - { - "label": "Тень ежа / Ёж Шэдоу / Shadow the hedgehog", - "value": "796" - }, - { - "label": "Терминатор / The Terminator", - "value": "759" - }, - { - "label": "Террарий / Terraria", - "value": "805" - }, - { - "label": "Тетрадь смерти / Death Note", - "value": "78" - }, - { - "label": "Тибериумные войны / Tiberium Wars", - "value": "1893" - }, - { - "label": "Титаник / Titanic", - "value": "1842" - }, - { - "label": "Тихий Холм / Сайлент Хилл / Silent Hill", - "value": "848" - }, - { - "label": "Тихоокеанский рубеж / Pacific Rim", - "value": "832" - }, - { - "label": "Тогайну но Чи ~Потерял кровь~(Games) / Togainu no Chi ~Lost Blood~", - "value": "1540" - }, - { - "label": "Токийские вороны / Tokyo Ravens", - "value": "836" - }, - { - "label": "Токийские мстители / Tokyo Revengers", - "value": "1064" - }, - { - "label": "Токийский Гуль / Tokyo Ghoul", - "value": "271" - }, - { - "label": "Тор / Thor", - "value": "764" - }, - { - "label": "Торико / Toriko", - "value": "342" - }, - { - "label": "Точка зрения Всеведущего читателя / Omniscient Reader’s Viewpoint", - "value": "1872" - }, - { - "label": "Трансформеры / Transformers", - "value": "117" - }, - { - "label": "Трес Наварра / Tres Navarre", - "value": "1197" - }, - { - "label": "Три Икса / xXx", - "value": "364" - }, - { - "label": "Трон: Восстание / Tron: Uprising", - "value": "1887" - }, - { - "label": "Тропико / Tropico", - "value": "694" - }, - { - "label": "Ты единственная, кто любит Великого Меня / Ore wo Suki nano wa Omae dake ka yo", - "value": "1818" - }, - { - "label": "Ты же любишь мамочку, удары которой бьют по площади двойным уроном? / Tsuujou Kougeki ga Zentai Kougeki de Ni-kai Kougeki no Okaasan wa Suki Desu ka?", - "value": "333" - }, - { - "label": "Тэнти - лишний! / Tenchi Muyo", - "value": "1316" - }, - { - "label": "У Коми-сан проблемы с общением / 古見さんは、コミュ症です / Komi Can't Communicate", - "value": "591" - }, - { - "label": "У меня мало друзей / Boku wa Tomodachi ga Sukunai", - "value": "1506" - }, - { - "label": "Убийца Акаме / Akame ga Kill", - "value": "30" - }, - { - "label": "Убийца Брайан / Carl Robert Brown", - "value": "1092" - }, - { - "label": "Убийца гоблинов / Goblin slayer", - "value": "803" - }, - { - "label": "Удар крови / Very AU strike the blood", - "value": "1255" - }, - { - "label": "Уж не зомби ли это? / Kore wa Zombie Desu ka?", - "value": "725" - }, - { - "label": "Уличный боец(Games) / Суторито Фаита / Street Fighter", - "value": "1203" - }, - { - "label": "Ультрафиолет / Ultraviolet", - "value": "1831" - }, - { - "label": "Усио и Тора / Ushio and Tora", - "value": "1501" - }, - { - "label": "Утраченное небесами / Sora no Otoshimoto / Lost Property of the Sky", - "value": "627" - }, - { - "label": "Ученик Мудреца / Kenja no Deshi wo Nanoru Kenja", - "value": "1474" - }, - { - "label": "Ученик чародея / The Sorcerer's Apprentice", - "value": "862" - }, - { - "label": "Ученики(Games) / Disciples", - "value": "1478" - }, - { - "label": "Учитель Хокаге / Hokage Master", - "value": "1319" - }, - { - "label": "Учитель-мафиози Реборн! / Katekyo Hitman Reborn!", - "value": "134" - }, - { - "label": "Ушастые Друзья / Kemono Friends", - "value": "578" - }, - { - "label": "Фальшивая любовь / Nisekoi", - "value": "1103" - }, - { - "label": "Фантастическая четвёрка / Fantastic Four", - "value": "625" - }, - { - "label": "Фантастические твари и где они обитают / Fantastic Beasts and Where to Find Them", - "value": "246" - }, - { - "label": "Финес и Ферб / Phineas and Ferb", - "value": "898" - }, - { - "label": "Флотская коллекция / Kantai Collection", - "value": "1194" - }, - { - "label": "Флэш / The Flash", - "value": "1136" - }, - { - "label": "Фонд SCP / SCP / SCP Foundation", - "value": "822" - }, - { - "label": "Форма голоса / A Silent Voice", - "value": "1100" - }, - { - "label": "Форсаж / The Fast and the Furious", - "value": "363" - }, - { - "label": "Фронт кровавой блокады / Кровавый круг - линия фронта / Kekkai Sensen / Blood Blockade Battlefront", - "value": "794" - }, - { - "label": "Футадом мир / Futadom world", - "value": "984" - }, - { - "label": "Халк / Hulk", - "value": "973" - }, - { - "label": "Хвост Феи / Fairy Tail", - "value": "13" - }, - { - "label": "Хеллбой / Hellboy", - "value": "1171" - }, - { - "label": "Хеллсинг: Война с нечистью / Hellsing", - "value": "116" - }, - { - "label": "Хикару и го / Hikaru no Go", - "value": "1121" - }, - { - "label": "Хищник / Predator", - "value": "747" - }, - { - "label": "Хоббит(Дж. Р. Р. Толкина) / The Hobbit(John R.R. Tolkien)", - "value": "1127" - }, - { - "label": "Ходячие мертвецы / The Walking Dead", - "value": "704" - }, - { - "label": "Холодное сердце / Frozen", - "value": "633" - }, - { - "label": "Хонкай удар / Honkai impact", - "value": "1332" - }, - { - "label": "Хранители Пандоры / The guardians of Pandora", - "value": "1187" - }, - { - "label": "Хранитель вечности / UQ Holder", - "value": "1469" - }, - { - "label": "Хроники Акаши / Rokudenashi Majutsu Koushi to Akashic Records", - "value": "1166" - }, - { - "label": "Хроники Ксенобладания / Дзэнобурэйдо / Xenoblade Chronicles", - "value": "1110" - }, - { - "label": "Хроники Миров(Е. Лукин) / Chronicles of the Worlds(E. Lukin)", - "value": "346" - }, - { - "label": "Хроники расхитителей гробниц / Даому Биджи / Grave Robbery Note / Dao Mu Bi Ji / Daomu Biji", - "value": "724" - }, - { - "label": "Хроники Ренегата / The Renegade Chronicles", - "value": "1225" - }, - { - "label": "Царь Горы / The Gog of the Highschool", - "value": "1285" - }, - { - "label": "Чародейки / W.I.T.C.H.", - "value": "118" - }, - { - "label": "Человек — бензопила / Chainsaw Man", - "value": "797" - }, - { - "label": "Человек — летучая мышь / Бэтмен / Bat-man / Batman", - "value": "440" - }, - { - "label": "Человек одного удара / Ванпанчмен / One Punch-Man", - "value": "70" - }, - { - "label": "Человек-паук / Spider-Man", - "value": "326" - }, - { - "label": "Чемпион! / Campione!", - "value": "534" - }, - { - "label": "Червь(Джон Маккрей) / Worm(John C. McCrae(Wildbow))", - "value": "700" - }, - { - "label": "Черная Пантера(Фильм, 2018) / Black Panther", - "value": "1605" - }, - { - "label": "Черновик(С.Лукьяненко) / Draft", - "value": "1023" - }, - { - "label": "Чернокнижник в Мире Магов / Варлок / Warlock", - "value": "635" - }, - { - "label": "Чёрные души / Black Souls", - "value": "1439" - }, - { - "label": "Чёрный зверь / Чёрный Пёс / Kuroinu", - "value": "755" - }, - { - "label": "Чёрный зверь: Развращение Благородных Воительниц / Black Beast: Corruption of the Noble Warriors", - "value": "1733" - }, - { - "label": "Чёрный клевер / Black Clover", - "value": "11" - }, - { - "label": "Что такое настоящий мир? / What is real peace?", - "value": "1336" - }, - { - "label": "Чудачества любви не помеха! / Chuunibyou Demo Koi ga Shitai!", - "value": "1719" - }, - { - "label": "Чужой / Чужие / Aliens", - "value": "1791" - }, - { - "label": "Чужой / Alien", - "value": "748" - }, - { - "label": "Чума инкорпорейтед / Plague Inc", - "value": "125" - }, - { - "label": "Шазам! / Shazam!", - "value": "1560" - }, - { - "label": "Шальной последний босс появился! / A Wild Last Boss Appeared!", - "value": "968" - }, - { - "label": "Шальные девчонки / Girl the Wild's", - "value": "965" - }, - { - "label": "Шан Чи и легенда десяти колец / Shang-Chi and the Legend of the Ten Rings", - "value": "1424" - }, - { - "label": "Шарлотта / Charlotte", - "value": "71" - }, - { - "label": "Шерлок (ВВС) / Sherlock", - "value": "492" - }, - { - "label": "Шестерни войны / Gears of War", - "value": "1346" - }, - { - "label": "Школа мертвецов / Highschool of the Dead", - "value": "98" - }, - { - "label": "Школа строгого режима / Prison School", - "value": "676" - }, - { - "label": "Школьные воины / Сила тысячи / Ikki Tosen", - "value": "818" - }, - { - "label": "Шрек(мультфильм) / Шрэк / Shrek", - "value": "1586" - }, - { - "label": "Шухер, у нас новый студент / Transfer Student The Storm Bringer", - "value": "628" - }, - { - "label": "Эволюционировать(Games) / Evolve", - "value": "1789" - }, - { - "label": "Эволюция. Естественный Отбор / Game Evolution", - "value": "287" - }, - { - "label": "Эльсворд: Эль-ий Йоин / Elsword", - "value": "199" - }, - { - "label": "Эльфийская песнь / Elfen Lied", - "value": "1899" - }, - { - "label": "Эпоха Драконов / Dragon Age", - "value": "253" - }, - { - "label": "Эр Ген Я запечатаю небеса / ISSTH / Er Gen I shall seal the heavens", - "value": "1170" - }, - { - "label": "Эрагон(Кристофер Паолини) / Eragon", - "value": "417" - }, - { - "label": "Эроманга-сэнсэй / Ero-manga Sensei", - "value": "1094" - }, - { - "label": "Эстетика заблудшего героя / Hagure Yuusha no Aesthetica", - "value": "1310" - }, - { - "label": "Эта гяру будет встречаться с отаку через 100 дней. / 100-nichigo ni Otaku-kun to Tsukiau Gal", - "value": "1246" - }, - { - "label": "Эта фарфоровая кукла влюбилась / Sono Bisque Doll wa Koi wo Suru My Dress-Up Darling", - "value": "1335" - }, - { - "label": "Это не Гарри Поттер / This is not Harry Potter", - "value": "1219" - }, - { - "label": "Этот герой неуязвим, но очень осторожен / This Hero Is Invincible but Too Cautious", - "value": "1276" - }, - { - "label": "Эффект массы / Mass Effect", - "value": "213" - }, - { - "label": "Эхо пули / Bullet Echo", - "value": "1523" - }, - { - "label": "Югио: Дуэльные монстры / Yu-Gi-Oh", - "value": "1814" - }, - { - "label": "Югио! Вреинс / Yu-Gi-Oh! VRAINS", - "value": "1888" - }, - { - "label": "Юна из гостиницы Юраги / Yuuna of Yuragi Manor", - "value": "493" - }, - { - "label": "Юная Лига Справедливости / Young Justice", - "value": "1020" - }, - { - "label": "Юные Титаны / Teen Titans", - "value": "420" - }, - { - "label": "Я - Четвертый / I Am Number Four", - "value": "590" - }, - { - "label": "Я Король-Волшебник / I Am The Sorcerer King", - "value": "1292" - }, - { - "label": "Я мачеха, но моя дочь слишком милая / I'm stepmother but daughter is too cute", - "value": "777" - }, - { - "label": "Я не родился счастливчиком / I Wasn’t Born Lucky", - "value": "996" - }, - { - "label": "Я получил читерские способности в другом мире и стал экстраординарным в реальном мире / I Got a Cheat Skill in Another World and Became Unrivaled in The Real World, Too", - "value": "1900" - }, - { - "label": "Я стала потерянной дочерью злодея / I Became the Villain’s Lost Daughter", - "value": "1387" - }, - { - "label": "Ядерный трон / Nuclear Throne", - "value": "1456" - }, - { - "label": "Ярость [Пересмотрено] / Rage [Revised]", - "value": "1337" - }, - { - "label": "Ящик предложений Мэдаки / Medaka box", - "value": "874" - }, - { - "label": "Cказка для Дьявола / Tale For Satan", - "value": "1271" - }, - { - "label": "D&D стиль / D&D style", - "value": "1289" - }, - { - "label": "Dying Light 2: Stay Human", - "value": "1906" - }, - { - "label": "Fallout: Нью-Вегас / Fallout: New Vegas", - "value": "1249" - }, - { - "label": "Re: Жизнь в альтернативном мире с нуля / Re: Zero, Starting Life in Another World", - "value": "57" - }, - { - "label": "Re:Zero Начало жизни в другом мире / Re:Zero Starting Life in Another World", - "value": "1531" - }, - { - "label": "Rimworld", - "value": "1894" - }, - { - "label": "The Second Coming of Gluttony / The Second Coming of Avarice", - "value": "1236" - }, - { - "label": "Vfhdbk", - "value": "1884" - }, - { - "label": "XCOM: Враг внутри / XCOM: Enemy Unknown", - "value": "476" - }, - { - "label": "Xenus: Точка кипения / Boiling point: Road To Hell / Xenus: Boiling Point", - "value": "695" - } - ], - "inputType": "Checkbox" - }, - { - "key": "genres_ex", - "label": "Исключить жанры:", - "values": [ - { - "label": "18+", - "value": "52" - }, - { - "label": "Арт", - "value": "1" - }, - { - "label": "Боевик", - "value": "2" - }, - { - "label": "Боевые искусства", - "value": "3" - }, - { - "label": "Гаремник", - "value": "5" - }, - { - "label": "Героическое фэнтези", - "value": "7" - }, - { - "label": "Детектив", - "value": "8" - }, - { - "label": "Дзёсэй", - "value": "9" - }, - { - "label": "Додзинси", - "value": "10" - }, - { - "label": "Драма", - "value": "11" - }, - { - "label": "История", - "value": "13" - }, - { - "label": "Киберпанк", - "value": "46" - }, - { - "label": "Кодомо", - "value": "14" - }, - { - "label": "Комедия", - "value": "15" - }, - { - "label": "Литрпг", - "value": "48" - }, - { - "label": "Махо-сёдзё", - "value": "16" - }, - { - "label": "Мелодрама", - "value": "49" - }, - { - "label": "Меха", - "value": "17" - }, - { - "label": "Мистика", - "value": "18" - }, - { - "label": "Научная фантастика", - "value": "19" - }, - { - "label": "Повседневность", - "value": "20" - }, - { - "label": "Постапокалиптика", - "value": "21" - }, - { - "label": "Приключения", - "value": "22" - }, - { - "label": "Психология", - "value": "23" - }, - { - "label": "Романтика", - "value": "24" - }, - { - "label": "Самурайский боевик", - "value": "25" - }, - { - "label": "Сверхъестественное", - "value": "26" - }, - { - "label": "Сёдзё", - "value": "27" - }, - { - "label": "Сёнэн", - "value": "29" - }, - { - "label": "Смат", - "value": "45" - }, - { - "label": "Спорт", - "value": "31" - }, - { - "label": "Сэйнэн", - "value": "32" - }, - { - "label": "Сюаньхуа", - "value": "44" - }, - { - "label": "Сюаньхуань", - "value": "47" - }, - { - "label": "Сянься (XianXia)", - "value": "42" - }, - { - "label": "Трагедия", - "value": "33" - }, - { - "label": "Триллер", - "value": "34" - }, - { - "label": "Ужасы", - "value": "35" - }, - { - "label": "Уся (wuxia)", - "value": "41" - }, - { - "label": "Фантастика", - "value": "36" - }, - { - "label": "Фанфик", - "value": "50" - }, - { - "label": "Фэнтези", - "value": "37" - }, - { - "label": "Школа", - "value": "38" - }, - { - "label": "Этти", - "value": "39" - }, - { - "label": "Bl", - "value": "43" - }, - { - "label": "Gl", - "value": "40" - } - ], - "inputType": "Checkbox" - }, - { - "key": "tags_ex", - "label": "Исключить тэги:", - "values": [ - { - "label": "12+", - "value": "3316" - }, - { - "label": "16+", - "value": "83" - }, - { - "label": "Абсурд", - "value": "7973" - }, - { - "label": "Авантюристы", - "value": "222" - }, - { - "label": "Автомат", - "value": "5272" - }, - { - "label": "Авторский мир", - "value": "1062" - }, - { - "label": "Агрессивные персонажи", - "value": "3249" - }, - { - "label": "Ад", - "value": "2623" - }, - { - "label": "Ад и рай", - "value": "817" - }, - { - "label": "Адам дженсен", - "value": "1649" - }, - { - "label": "Адаптация произведения", - "value": "192" - }, - { - "label": "Адвокат", - "value": "6340" - }, - { - "label": "Адекватные главные герои", - "value": "1953" - }, - { - "label": "Азартные игры", - "value": "5301" - }, - { - "label": "Азгард", - "value": "3494" - }, - { - "label": "Азула", - "value": "5550" - }, - { - "label": "Аид", - "value": "7641" - }, - { - "label": "Айдолы", - "value": "4081" - }, - { - "label": "Академия", - "value": "316" - }, - { - "label": "Акамэ", - "value": "5059" - }, - { - "label": "Аквакинез", - "value": "5952" - }, - { - "label": "Акира", - "value": "2639" - }, - { - "label": "Акнология", - "value": "4634" - }, - { - "label": "Актерское мастерство", - "value": "4798" - }, - { - "label": "Актёры", - "value": "7506" - }, - { - "label": "Активные герои", - "value": "6376" - }, - { - "label": "Акутагава рюноске", - "value": "4113" - }, - { - "label": "Аладдин", - "value": "6489" - }, - { - "label": "Алая ведьма", - "value": "4767" - }, - { - "label": "Алиса", - "value": "4761" - }, - { - "label": "Алкоголь", - "value": "5508" - }, - { - "label": "Аллегория", - "value": "271" - }, - { - "label": "Алукард", - "value": "4914" - }, - { - "label": "Алхимики", - "value": "1164" - }, - { - "label": "Алхимия", - "value": "1473" - }, - { - "label": "Алчность", - "value": "6897" - }, - { - "label": "Альбус дамблдор", - "value": "5784" - }, - { - "label": "Альтернативное развитие событий", - "value": "5330" - }, - { - "label": "Альянсы", - "value": "328" - }, - { - "label": "Амбициозный главный герой", - "value": "3751" - }, - { - "label": "Америка", - "value": "4082" - }, - { - "label": "Амнезия", - "value": "2207" - }, - { - "label": "Аморальный герой", - "value": "18" - }, - { - "label": "Анбу", - "value": "8129" - }, - { - "label": "Ангелы", - "value": "857" - }, - { - "label": "Ангелы и демоны", - "value": "1327" - }, - { - "label": "Ангст", - "value": "4638" - }, - { - "label": "Андроиды", - "value": "1993" - }, - { - "label": "Анимализм", - "value": "5249" - }, - { - "label": "Аниме", - "value": "1294" - }, - { - "label": "Анко митараши", - "value": "5768" - }, - { - "label": "Антагонист", - "value": "2144" - }, - { - "label": "Антигерой", - "value": "7725" - }, - { - "label": "Антиквариат", - "value": "3552" - }, - { - "label": "Антимаг", - "value": "1348" - }, - { - "label": "Антиутопия", - "value": "662" - }, - { - "label": "Апокалипсис", - "value": "1498" - }, - { - "label": "Аристократия", - "value": "371" - }, - { - "label": "Аристократы", - "value": "7338" - }, - { - "label": "Армия", - "value": "1723" - }, - { - "label": "Артас", - "value": "6700" - }, - { - "label": "Артефакты", - "value": "2296" - }, - { - "label": "Археология", - "value": "6523" - }, - { - "label": "Асгард", - "value": "3635" - }, - { - "label": "Ассасин", - "value": "1415" - }, - { - "label": "Асуна", - "value": "5044" - }, - { - "label": "Аугментации", - "value": "7751" - }, - { - "label": "Ацуши накаджима", - "value": "4109" - }, - { - "label": "Аянокоджи киетака", - "value": "6862" - }, - { - "label": "Бандиты", - "value": "2188" - }, - { - "label": "Басейн", - "value": "6847" - }, - { - "label": "Баскетбол", - "value": "7933" - }, - { - "label": "Бастарды", - "value": "76" - }, - { - "label": "Бедность", - "value": "1207" - }, - { - "label": "Без культивации", - "value": "668" - }, - { - "label": "Без любовной линий", - "value": "2225" - }, - { - "label": "Без перерождений", - "value": "262" - }, - { - "label": "Без попаданца", - "value": "8065" - }, - { - "label": "Без системы", - "value": "747" - }, - { - "label": "Без юмора", - "value": "763" - }, - { - "label": "Бездна", - "value": "1026" - }, - { - "label": "Безжалостное домашнее животное", - "value": "1245" - }, - { - "label": "Безжалостные персонажи", - "value": "2986" - }, - { - "label": "Беззаботные персонажи", - "value": "3123" - }, - { - "label": "Безответная любовь", - "value": "7815" - }, - { - "label": "Безработный", - "value": "2202" - }, - { - "label": "Безумие", - "value": "37" - }, - { - "label": "Безумные персонажи", - "value": "2049" - }, - { - "label": "Бейсбол", - "value": "7623" - }, - { - "label": "Беременность", - "value": "2122" - }, - { - "label": "Бесконечный поток", - "value": "7556" - }, - { - "label": "Беспечные персонажи", - "value": "742" - }, - { - "label": "Бесплатно", - "value": "8403" - }, - { - "label": "Бессмертные персонажи", - "value": "566" - }, - { - "label": "Бесстрашные персонажи", - "value": "6921" - }, - { - "label": "Бесстыдные персонажи", - "value": "1257" - }, - { - "label": "Бесстыдный главный герой", - "value": "8190" - }, - { - "label": "Библиотека", - "value": "4210" - }, - { - "label": "Библия", - "value": "488" - }, - { - "label": "Бизнес", - "value": "704" - }, - { - "label": "Биология", - "value": "2220" - }, - { - "label": "Биомехи", - "value": "1968" - }, - { - "label": "Биседзе", - "value": "777" - }, - { - "label": "Битва за веру", - "value": "721" - }, - { - "label": "Битва за трон", - "value": "7211" - }, - { - "label": "Битва королевств", - "value": "1151" - }, - { - "label": "Битва рас", - "value": "6989" - }, - { - "label": "Битвы", - "value": "1740" - }, - { - "label": "Благородные персонажи", - "value": "2201" - }, - { - "label": "Близнецы", - "value": "2931" - }, - { - "label": "Богатство", - "value": "6522" - }, - { - "label": "Богатые персонажи", - "value": "520" - }, - { - "label": "Боги", - "value": "173" - }, - { - "label": "Богини", - "value": "30" - }, - { - "label": "Богиня", - "value": "8324" - }, - { - "label": "Богоубийца", - "value": "1253" - }, - { - "label": "Богохульство", - "value": "95" - }, - { - "label": "Боевая академия", - "value": "2108" - }, - { - "label": "Большая грудь", - "value": "4717" - }, - { - "label": "Борос", - "value": "6533" - }, - { - "label": "Борьба", - "value": "1925" - }, - { - "label": "Борьба за власть", - "value": "8072" - }, - { - "label": "Босс и подчиненный", - "value": "7157" - }, - { - "label": "Бояръ", - "value": "2307" - }, - { - "label": "Брак", - "value": "1558" - }, - { - "label": "Брак по расчету", - "value": "1389" - }, - { - "label": "Брат и сестра", - "value": "615" - }, - { - "label": "Братский комплекс", - "value": "2321" - }, - { - "label": "Броманс", - "value": "1103" - }, - { - "label": "Брошенные дети", - "value": "2846" - }, - { - "label": "Буддизм", - "value": "1871" - }, - { - "label": "Будущее", - "value": "1820" - }, - { - "label": "Бывший муж", - "value": "8080" - }, - { - "label": "Быстрое развитие", - "value": "1443" - }, - { - "label": "Бэтгерл", - "value": "2584" - }, - { - "label": "Бэтмен", - "value": "4668" - }, - { - "label": "В первый раз", - "value": "6212" - }, - { - "label": "В этот же мир", - "value": "49" - }, - { - "label": "Ваканда", - "value": "8331" - }, - { - "label": "Валькирии", - "value": "4047" - }, - { - "label": "Вампиры", - "value": "2206" - }, - { - "label": "Веб камера", - "value": "5664" - }, - { - "label": "Веб новелла", - "value": "2349" - }, - { - "label": "Ведьмак", - "value": "843" - }, - { - "label": "Ведьмы", - "value": "643" - }, - { - "label": "Везучие персонажи", - "value": "1879" - }, - { - "label": "Веном", - "value": "3994" - }, - { - "label": "Вестерн", - "value": "2131" - }, - { - "label": "Вестерос", - "value": "8171" - }, - { - "label": "Взросление", - "value": "624" - }, - { - "label": "Взрослый главный герой", - "value": "2416" - }, - { - "label": "Видео игры", - "value": "2630" - }, - { - "label": "Викинги", - "value": "267" - }, - { - "label": "Вино", - "value": "6972" - }, - { - "label": "Вирт", - "value": "6213" - }, - { - "label": "Виртуальная реальность", - "value": "325" - }, - { - "label": "Вирусы", - "value": "3327" - }, - { - "label": "Владыка демонов", - "value": "555" - }, - { - "label": "Власть", - "value": "756" - }, - { - "label": "Влюбленность", - "value": "6132" - }, - { - "label": "Внешний вид отличается от личности", - "value": "1938" - }, - { - "label": "Внучка", - "value": "8399" - }, - { - "label": "Военные", - "value": "1096" - }, - { - "label": "Возрождение", - "value": "1160" - }, - { - "label": "Воины", - "value": "287" - }, - { - "label": "Война", - "value": "443" - }, - { - "label": "Войны", - "value": "2431" - }, - { - "label": "Воландеморт", - "value": "4278" - }, - { - "label": "Волейбол", - "value": "6415" - }, - { - "label": "Волки", - "value": "1166" - }, - { - "label": "Волшебники", - "value": "122" - }, - { - "label": "Волшебные существа", - "value": "1689" - }, - { - "label": "Волшебство", - "value": "719" - }, - { - "label": "Вор", - "value": "1399" - }, - { - "label": "Воровка", - "value": "6948" - }, - { - "label": "Ворон", - "value": "848" - }, - { - "label": "Воскрешение", - "value": "6915" - }, - { - "label": "Воспоминания из другого мира", - "value": "1366" - }, - { - "label": "Воспоминания из прошлого", - "value": "1372" - }, - { - "label": "Воссоединие семьи", - "value": "8130" - }, - { - "label": "Восхождение", - "value": "380" - }, - { - "label": "Враги становятся любовниками", - "value": "978" - }, - { - "label": "Врата", - "value": "40" - }, - { - "label": "Врата в другой мир", - "value": "1957" - }, - { - "label": "Врач", - "value": "1243" - }, - { - "label": "Временная петля", - "value": "2852" - }, - { - "label": "Врмморпг", - "value": "2043" - }, - { - "label": "Все дозволено", - "value": "96" - }, - { - "label": "Всемогущий главный герой", - "value": "1414" - }, - { - "label": "Второй шанс", - "value": "2372" - }, - { - "label": "Вуайеризм", - "value": "2498" - }, - { - "label": "Выживание", - "value": "501" - }, - { - "label": "Вымышленные существа", - "value": "3466" - }, - { - "label": "Вынужденный брак", - "value": "7705" - }, - { - "label": "Высокие технологии", - "value": "653" - }, - { - "label": "Высокомерные персонажи", - "value": "3250" - }, - { - "label": "Галустян", - "value": "5199" - }, - { - "label": "Гангстеры", - "value": "7704" - }, - { - "label": "Гарем", - "value": "440" - }, - { - "label": "Гарри поттер", - "value": "226" - }, - { - "label": "Геймеры", - "value": "2130" - }, - { - "label": "Генетические модификации", - "value": "1750" - }, - { - "label": "Гениальный главный герой", - "value": "1500" - }, - { - "label": "Гений", - "value": "1650" - }, - { - "label": "Гермиона грейнджер", - "value": "4280" - }, - { - "label": "Герои", - "value": "185" - }, - { - "label": "Гигаполис", - "value": "8393" - }, - { - "label": "Гильгамеш", - "value": "6031" - }, - { - "label": "Гильдии", - "value": "900" - }, - { - "label": "Гильдия авантюристов", - "value": "1858" - }, - { - "label": "Гинтама", - "value": "4544" - }, - { - "label": "Гипноз", - "value": "358" - }, - { - "label": "Главная героиня влюбляется первой", - "value": "973" - }, - { - "label": "Главный герой бог", - "value": "164" - }, - { - "label": "Главный герой влюбляется первым", - "value": "3629" - }, - { - "label": "Главный герой выживальщик", - "value": "120" - }, - { - "label": "Главный герой гонг", - "value": "7877" - }, - { - "label": "Главный герой девушка", - "value": "257" - }, - { - "label": "Главный герой демон", - "value": "136" - }, - { - "label": "Главный герой женщина", - "value": "7329" - }, - { - "label": "Главный герой жестокий", - "value": "1553" - }, - { - "label": "Главный герой извращенец", - "value": "94" - }, - { - "label": "Главный герой имба", - "value": "2421" - }, - { - "label": "Главный герой киборг", - "value": "7780" - }, - { - "label": "Главный герой монстр", - "value": "869" - }, - { - "label": "Главный герой мужчина", - "value": "1997" - }, - { - "label": "Главный герой на стороне сил зла", - "value": "1514" - }, - { - "label": "Главный герой не адекватный", - "value": "5" - }, - { - "label": "Главный герой не психопат", - "value": "7804" - }, - { - "label": "Главный герой не человек", - "value": "2172" - }, - { - "label": "Главный герой не эмоционален", - "value": "1150" - }, - { - "label": "Главный герой подросток", - "value": "2215" - }, - { - "label": "Главный герой позитивный", - "value": "7787" - }, - { - "label": "Главный герой психопат", - "value": "7803" - }, - { - "label": "Главный герой ребенок", - "value": "2347" - }, - { - "label": "Главный герой русский", - "value": "2417" - }, - { - "label": "Главный герой сильный с самого начала", - "value": "88" - }, - { - "label": "Главный герой скрывает свою силу", - "value": "1059" - }, - { - "label": "Главный герой эгоист", - "value": "8326" - }, - { - "label": "Гномы", - "value": "1870" - }, - { - "label": "Гоблины", - "value": "2029" - }, - { - "label": "Годзилла", - "value": "6990" - }, - { - "label": "Големы", - "value": "1690" - }, - { - "label": "Голливуд", - "value": "7754" - }, - { - "label": "Головоломка", - "value": "1697" - }, - { - "label": "Горничные", - "value": "8091" - }, - { - "label": "Гробница", - "value": "388" - }, - { - "label": "Дазай осаму", - "value": "4112" - }, - { - "label": "Даньмэй", - "value": "3411" - }, - { - "label": "Даосизм", - "value": "258" - }, - { - "label": "Дарк соулс", - "value": "6057" - }, - { - "label": "Дарт вейдер", - "value": "6826" - }, - { - "label": "Дафна гринграсс", - "value": "5192" - }, - { - "label": "Дворяне", - "value": "7204" - }, - { - "label": "Девушки", - "value": "7668" - }, - { - "label": "Девушки монстры", - "value": "2231" - }, - { - "label": "Дедушка и внучка", - "value": "8400" - }, - { - "label": "Дейви джонс", - "value": "8061" - }, - { - "label": "Действие", - "value": "1425" - }, - { - "label": "Демон лорд", - "value": "153" - }, - { - "label": "Демонология", - "value": "2024" - }, - { - "label": "Демоны", - "value": "1406" - }, - { - "label": "Дети", - "value": "580" - }, - { - "label": "Джарвис", - "value": "933" - }, - { - "label": "Джедай", - "value": "4442" - }, - { - "label": "Джин", - "value": "4024" - }, - { - "label": "Джокер", - "value": "3351" - }, - { - "label": "Джон сноу", - "value": "7412" - }, - { - "label": "Джоффри баратеон", - "value": "3936" - }, - { - "label": "Дзесэй", - "value": "678" - }, - { - "label": "Дин винчестер", - "value": "6953" - }, - { - "label": "Династии", - "value": "2982" - }, - { - "label": "Динозавры", - "value": "3666" - }, - { - "label": "Директор", - "value": "1417" - }, - { - "label": "Для девушек", - "value": "1441" - }, - { - "label": "Дневник", - "value": "298" - }, - { - "label": "Добби", - "value": "6762" - }, - { - "label": "Добрый мир", - "value": "1685" - }, - { - "label": "Договоры с богами", - "value": "2152" - }, - { - "label": "Договоры с демонами", - "value": "1922" - }, - { - "label": "Доктор", - "value": "1991" - }, - { - "label": "Доктор стрэндж", - "value": "7634" - }, - { - "label": "Доминирование", - "value": "2054" - }, - { - "label": "Дота", - "value": "6965" - }, - { - "label": "Доудзюцу", - "value": "7133" - }, - { - "label": "Дочь", - "value": "3291" - }, - { - "label": "Драко малфой", - "value": "46" - }, - { - "label": "Драконы", - "value": "282" - }, - { - "label": "Драконы оборотни", - "value": "8082" - }, - { - "label": "Древние времена", - "value": "7781" - }, - { - "label": "Древний египет", - "value": "7614" - }, - { - "label": "Древний китай", - "value": "473" - }, - { - "label": "Древний мир", - "value": "4" - }, - { - "label": "Другая вселенная", - "value": "39" - }, - { - "label": "Другие планеты", - "value": "2371" - }, - { - "label": "Другой мир", - "value": "2248" - }, - { - "label": "Дружба", - "value": "1903" - }, - { - "label": "Друзья детства", - "value": "1153" - }, - { - "label": "Духи", - "value": "114" - }, - { - "label": "Духовные силы", - "value": "1955" - }, - { - "label": "Души", - "value": "1212" - }, - { - "label": "Дьявол", - "value": "1094" - }, - { - "label": "Дьявольские фрукты", - "value": "1564" - }, - { - "label": "Дэдпул", - "value": "4399" - }, - { - "label": "Евнух", - "value": "6293" - }, - { - "label": "Европейская атмосфера", - "value": "5837" - }, - { - "label": "Египет", - "value": "528" - }, - { - "label": "Еда", - "value": "2056" - }, - { - "label": "Единороги", - "value": "437" - }, - { - "label": "Екаи", - "value": "655" - }, - { - "label": "Жалкий главный герой", - "value": "97" - }, - { - "label": "Жена", - "value": "5729" - }, - { - "label": "Женское доминирование", - "value": "4622" - }, - { - "label": "Женщина в теле мужчины", - "value": "2748" - }, - { - "label": "Женщина кошка", - "value": "7513" - }, - { - "label": "Жестокие персонажи", - "value": "3153" - }, - { - "label": "Жестокий мир", - "value": "1532" - }, - { - "label": "Жестокость", - "value": "7880" - }, - { - "label": "Животные", - "value": "7488" - }, - { - "label": "Животные компаньоны", - "value": "2061" - }, - { - "label": "Жизнь и смерть", - "value": "2014" - }, - { - "label": "Жнец", - "value": "6288" - }, - { - "label": "Жойен рид", - "value": "3926" - }, - { - "label": "Заботливый главный герой", - "value": "338" - }, - { - "label": "Закалка тела", - "value": "148" - }, - { - "label": "Заклинания", - "value": "558" - }, - { - "label": "Заключенные", - "value": "3052" - }, - { - "label": "Занпакто", - "value": "1102" - }, - { - "label": "Запретная любовь", - "value": "8033" - }, - { - "label": "Запутанный сюжет", - "value": "1041" - }, - { - "label": "Захват мира", - "value": "315" - }, - { - "label": "Зачарованные", - "value": "4169" - }, - { - "label": "Звери", - "value": "1638" - }, - { - "label": "Зверодевочки", - "value": "2006" - }, - { - "label": "Зверолюди", - "value": "1018" - }, - { - "label": "Земля", - "value": "82" - }, - { - "label": "Злая организация", - "value": "7768" - }, - { - "label": "Зло", - "value": "1512" - }, - { - "label": "Злодей", - "value": "1060" - }, - { - "label": "Злодейка", - "value": "2376" - }, - { - "label": "Злой главный герой", - "value": "616" - }, - { - "label": "Злые боги", - "value": "7109" - }, - { - "label": "Злые персонажи", - "value": "3243" - }, - { - "label": "Змей", - "value": "5721" - }, - { - "label": "Знаменитости", - "value": "1341" - }, - { - "label": "Знание медицины", - "value": "1411" - }, - { - "label": "Золушка", - "value": "2980" - }, - { - "label": "Зомби", - "value": "1743" - }, - { - "label": "Зомби апокалипсис", - "value": "912" - }, - { - "label": "Зона 51", - "value": "3051" - }, - { - "label": "Зооморфы", - "value": "375" - }, - { - "label": "Зорро", - "value": "6736" - }, - { - "label": "Зрелые женщины", - "value": "1458" - }, - { - "label": "Игра", - "value": "663" - }, - { - "label": "Игра на выживание", - "value": "2182" - }, - { - "label": "Игровая система", - "value": "384" - }, - { - "label": "Игровые элементы", - "value": "720" - }, - { - "label": "Извращения", - "value": "651" - }, - { - "label": "Измена", - "value": "1874" - }, - { - "label": "Изменение характера", - "value": "1113" - }, - { - "label": "Изменения внешности", - "value": "259" - }, - { - "label": "Изменения личности", - "value": "1080" - }, - { - "label": "Изобретения", - "value": "126" - }, - { - "label": "Изуку мидория", - "value": "6967" - }, - { - "label": "Император", - "value": "867" - }, - { - "label": "Империи", - "value": "712" - }, - { - "label": "Империя", - "value": "1716" - }, - { - "label": "Инвалидность", - "value": "2073" - }, - { - "label": "Инквизитор", - "value": "143" - }, - { - "label": "Инкуб", - "value": "3264" - }, - { - "label": "Инопланетное вторжение", - "value": "209" - }, - { - "label": "Инопланетяне", - "value": "866" - }, - { - "label": "Интерактив с читателями", - "value": "472" - }, - { - "label": "Интересный сюжет", - "value": "7374" - }, - { - "label": "Интернет", - "value": "739" - }, - { - "label": "Интимные сцены", - "value": "3450" - }, - { - "label": "Интрига", - "value": "317" - }, - { - "label": "Интриги и заговоры", - "value": "1009" - }, - { - "label": "Иные миры", - "value": "35" - }, - { - "label": "Исекай", - "value": "2979" - }, - { - "label": "Искусственный интеллект", - "value": "1900" - }, - { - "label": "Исследование", - "value": "1626" - }, - { - "label": "Исторический роман", - "value": "573" - }, - { - "label": "Итачи учиха", - "value": "4556" - }, - { - "label": "Ичиго", - "value": "7254" - }, - { - "label": "Йода", - "value": "6829" - }, - { - "label": "Йоруичи", - "value": "6755" - }, - { - "label": "Калипсо", - "value": "8062" - }, - { - "label": "Каннибализм", - "value": "2249" - }, - { - "label": "Капитан америка", - "value": "6301" - }, - { - "label": "Каракура", - "value": "7473" - }, - { - "label": "Карточная игра", - "value": "1557" - }, - { - "label": "Кастиэль", - "value": "6954" - }, - { - "label": "Кафе", - "value": "3934" - }, - { - "label": "Кацуки бакуго", - "value": "7696" - }, - { - "label": "Квесты", - "value": "1707" - }, - { - "label": "Киберспорт", - "value": "1984" - }, - { - "label": "Кино", - "value": "7126" - }, - { - "label": "Китай", - "value": "3762" - }, - { - "label": "Кицунэ", - "value": "241" - }, - { - "label": "Кланы", - "value": "834" - }, - { - "label": "Клоны", - "value": "1624" - }, - { - "label": "Книги", - "value": "1068" - }, - { - "label": "Книжный червь", - "value": "521" - }, - { - "label": "Колдовство", - "value": "2681" - }, - { - "label": "колледж", - "value": "5058" - }, - { - "label": "Коллекционер", - "value": "2588" - }, - { - "label": "Кольцо", - "value": "1628" - }, - { - "label": "Коммунисты", - "value": "1042" - }, - { - "label": "Коноха", - "value": "2827" - }, - { - "label": "Контракт", - "value": "4304" - }, - { - "label": "Контроль разума", - "value": "485" - }, - { - "label": "Конфеты", - "value": "341" - }, - { - "label": "Корейцы", - "value": "6535" - }, - { - "label": "Корея", - "value": "2443" - }, - { - "label": "Королевская власть", - "value": "55" - }, - { - "label": "Королевская семья", - "value": "276" - }, - { - "label": "Королевство", - "value": "1695" - }, - { - "label": "Короткий рассказ", - "value": "239" - }, - { - "label": "Коррупция", - "value": "831" - }, - { - "label": "Космическая опера", - "value": "2245" - }, - { - "label": "Космические рейнджеры", - "value": "5860" - }, - { - "label": "Космос", - "value": "329" - }, - { - "label": "Кот", - "value": "5171" - }, - { - "label": "Кража навыков", - "value": "1159" - }, - { - "label": "Красивая главная героиня", - "value": "186" - }, - { - "label": "Красивые женщины", - "value": "66" - }, - { - "label": "Красивые персонажи", - "value": "5787" - }, - { - "label": "Красивый главный герой", - "value": "895" - }, - { - "label": "Крафт", - "value": "1599" - }, - { - "label": "Кроссовер", - "value": "75" - }, - { - "label": "Ктулху", - "value": "920" - }, - { - "label": "Кузнец", - "value": "853" - }, - { - "label": "Кукла", - "value": "3085" - }, - { - "label": "Кулинария", - "value": "2230" - }, - { - "label": "Культивация", - "value": "1901" - }, - { - "label": "Культивирование", - "value": "1860" - }, - { - "label": "Курама", - "value": "5709" - }, - { - "label": "Курилин", - "value": "6134" - }, - { - "label": "Кушина узумаки", - "value": "5222" - }, - { - "label": "Лавкрафт", - "value": "6063" - }, - { - "label": "Лара крофт", - "value": "6435" - }, - { - "label": "Легенда о зельде", - "value": "5707" - }, - { - "label": "Ленивый главный герой", - "value": "1516" - }, - { - "label": "Леон золдик", - "value": "7469" - }, - { - "label": "Лес", - "value": "6645" - }, - { - "label": "Лечебная магия", - "value": "562" - }, - { - "label": "Локи", - "value": "1725" - }, - { - "label": "Лоли", - "value": "1576" - }, - { - "label": "Лопата", - "value": "4989" - }, - { - "label": "Лорд", - "value": "8404" - }, - { - "label": "Лориен", - "value": "7397" - }, - { - "label": "Лошади", - "value": "6110" - }, - { - "label": "Лунатизм", - "value": "3520" - }, - { - "label": "Луффи", - "value": "274" - }, - { - "label": "Лучник", - "value": "1038" - }, - { - "label": "Любовный интерес влюбляется первым", - "value": "7753" - }, - { - "label": "Любовный треугольник", - "value": "2109" - }, - { - "label": "Любовь", - "value": "2297" - }, - { - "label": "Любовь с первого взгляда", - "value": "7748" - }, - { - "label": "Любящие родители", - "value": "2699" - }, - { - "label": "Люди", - "value": "3572" - }, - { - "label": "Люцифер", - "value": "5883" - }, - { - "label": "Маг", - "value": "780" - }, - { - "label": "Магазин", - "value": "4762" - }, - { - "label": "Маги", - "value": "58" - }, - { - "label": "Магическая академия", - "value": "6788" - }, - { - "label": "Магические звери", - "value": "684" - }, - { - "label": "Магические предметы", - "value": "1648" - }, - { - "label": "Магический мир", - "value": "578" - }, - { - "label": "Магия", - "value": "150" - }, - { - "label": "Магия воды", - "value": "6450" - }, - { - "label": "Магия воздуха", - "value": "7627" - }, - { - "label": "Магия земли", - "value": "7626" - }, - { - "label": "Магия и технология", - "value": "107" - }, - { - "label": "Магия крови", - "value": "7976" - }, - { - "label": "Магия льда", - "value": "1379" - }, - { - "label": "Магия огня", - "value": "7625" - }, - { - "label": "Магия призыва", - "value": "885" - }, - { - "label": "Магия природы", - "value": "6226" - }, - { - "label": "Магия стихий", - "value": "7673" - }, - { - "label": "Магия тьмы", - "value": "3596" - }, - { - "label": "Мадара", - "value": "2929" - }, - { - "label": "Мазохизм", - "value": "1961" - }, - { - "label": "Мама", - "value": "12" - }, - { - "label": "Мама и дочь", - "value": "7894" - }, - { - "label": "Мама и сын", - "value": "7895" - }, - { - "label": "Манга", - "value": "2464" - }, - { - "label": "Манипуляция временем", - "value": "932" - }, - { - "label": "Маньяк", - "value": "2026" - }, - { - "label": "Маргери тирелл", - "value": "3935" - }, - { - "label": "Марионетки", - "value": "3175" - }, - { - "label": "Марс", - "value": "4013" - }, - { - "label": "Марти стью", - "value": "594" - }, - { - "label": "Мастер на все руки", - "value": "3189" - }, - { - "label": "Матриархат", - "value": "7197" - }, - { - "label": "Мать и сестры", - "value": "7946" - }, - { - "label": "Мафия", - "value": "353" - }, - { - "label": "Мачеха", - "value": "4664" - }, - { - "label": "Мегаполис", - "value": "3322" - }, - { - "label": "Медицина", - "value": "441" - }, - { - "label": "Медленная романтика", - "value": "8383" - }, - { - "label": "Медленное развитие истории", - "value": "7462" - }, - { - "label": "Мелиодас", - "value": "7224" - }, - { - "label": "Мелодрама", - "value": "1507" - }, - { - "label": "Менеджмент", - "value": "368" - }, - { - "label": "Мерлин", - "value": "3977" - }, - { - "label": "Месть", - "value": "1218" - }, - { - "label": "Меч", - "value": "48" - }, - { - "label": "Мечники", - "value": "969" - }, - { - "label": "Мечта", - "value": "527" - }, - { - "label": "Мизуки", - "value": "4269" - }, - { - "label": "Микото", - "value": "3862" - }, - { - "label": "Милая главная героиня", - "value": "134" - }, - { - "label": "Милф", - "value": "1987" - }, - { - "label": "Милый главный герой", - "value": "2678" - }, - { - "label": "Мимик", - "value": "5706" - }, - { - "label": "Мина ашидо", - "value": "7695" - }, - { - "label": "Минато намикадзе", - "value": "5223" - }, - { - "label": "Мир будущего", - "value": "1770" - }, - { - "label": "Мир земли", - "value": "8394" - }, - { - "label": "Мир меча и магии", - "value": "1271" - }, - { - "label": "Мистер пропер", - "value": "565" - }, - { - "label": "Мифические существа", - "value": "1878" - }, - { - "label": "Мифы и легенды", - "value": "4463" - }, - { - "label": "Младшая сестра", - "value": "1523" - }, - { - "label": "Мморпг", - "value": "620" - }, - { - "label": "Много главных героев", - "value": "1191" - }, - { - "label": "Много крови", - "value": "5318" - }, - { - "label": "Много персонажей", - "value": "1539" - }, - { - "label": "Множество королевств", - "value": "32" - }, - { - "label": "Модерн", - "value": "5457" - }, - { - "label": "Мокутон", - "value": "4438" - }, - { - "label": "Молоко", - "value": "5469" - }, - { - "label": "Монархия", - "value": "3590" - }, - { - "label": "Монстры", - "value": "307" - }, - { - "label": "Море", - "value": "922" - }, - { - "label": "Моритика ринносукэ", - "value": "1142" - }, - { - "label": "Мортал комбат", - "value": "5861" - }, - { - "label": "Мошенник", - "value": "959" - }, - { - "label": "Мрачный мир", - "value": "1" - }, - { - "label": "Мужчина в женском теле", - "value": "8405" - }, - { - "label": "Музыка", - "value": "1183" - }, - { - "label": "Мультивселенная", - "value": "7410" - }, - { - "label": "Мурим", - "value": "7342" - }, - { - "label": "Мутанты", - "value": "2392" - }, - { - "label": "Мутация", - "value": "29" - }, - { - "label": "Мясо", - "value": "1503" - }, - { - "label": "На реальных событиях", - "value": "26" - }, - { - "label": "Навыки", - "value": "415" - }, - { - "label": "Нагато узумаки", - "value": "5221" - }, - { - "label": "Наемники", - "value": "1668" - }, - { - "label": "Назарик", - "value": "5369" - }, - { - "label": "Наивный главный герой", - "value": "159" - }, - { - "label": "Наложница", - "value": "4867" - }, - { - "label": "Наноботы", - "value": "2332" - }, - { - "label": "Наруто", - "value": "7177" - }, - { - "label": "Наруто и хината", - "value": "5766" - }, - { - "label": "Насилие и жестокость", - "value": "1440" - }, - { - "label": "Наука", - "value": "2150" - }, - { - "label": "Национализм", - "value": "5556" - }, - { - "label": "Нацу", - "value": "5826" - }, - { - "label": "Нацуки субару", - "value": "6656" - }, - { - "label": "Начальная школа", - "value": "3920" - }, - { - "label": "Наши дни", - "value": "1814" - }, - { - "label": "Не всесильный главный герой", - "value": "42" - }, - { - "label": "Не по канону", - "value": "1611" - }, - { - "label": "Неверность", - "value": "5735" - }, - { - "label": "Невеста", - "value": "6011" - }, - { - "label": "Неджи хьюга", - "value": "3099" - }, - { - "label": "Недооценённый главный герой", - "value": "43" - }, - { - "label": "Нежить", - "value": "1949" - }, - { - "label": "Некромаг", - "value": "7441" - }, - { - "label": "Некромант", - "value": "1914" - }, - { - "label": "Некромантия", - "value": "754" - }, - { - "label": "Ненормативная лексика", - "value": "160" - }, - { - "label": "Необычные герои", - "value": "67" - }, - { - "label": "Нет людей", - "value": "7486" - }, - { - "label": "Нетораре", - "value": "403" - }, - { - "label": "Нетори", - "value": "5393" - }, - { - "label": "Нефилимы", - "value": "7764" - }, - { - "label": "Нецензурная лексика", - "value": "4912" - }, - { - "label": "Нечисть", - "value": "4559" - }, - { - "label": "Ник фьюри", - "value": "6304" - }, - { - "label": "Ниндзюцу", - "value": "2354" - }, - { - "label": "Ниндзя", - "value": "1330" - }, - { - "label": "Новелла", - "value": "2105" - }, - { - "label": "Нэко", - "value": "147" - }, - { - "label": "Оби ван кеноби", - "value": "6830" - }, - { - "label": "Обито учиха", - "value": "2814" - }, - { - "label": "Оборотни", - "value": "53" - }, - { - "label": "Обратный гарем", - "value": "3303" - }, - { - "label": "Овощ", - "value": "6098" - }, - { - "label": "Огнестрельное оружие", - "value": "3155" - }, - { - "label": "Одержимость", - "value": "708" - }, - { - "label": "Один в поле воин", - "value": "6498" - }, - { - "label": "Онлайн игра", - "value": "1565" - }, - { - "label": "Ооками теппей", - "value": "849" - }, - { - "label": "Оригинальные персонажи", - "value": "7741" - }, - { - "label": "Орки", - "value": "1597" - }, - { - "label": "Оружие", - "value": "125" - }, - { - "label": "Основано на видео игре", - "value": "602" - }, - { - "label": "Особые способности", - "value": "2904" - }, - { - "label": "От бедности к богатству", - "value": "901" - }, - { - "label": "От слабого до сильного", - "value": "118" - }, - { - "label": "Отель", - "value": "2879" - }, - { - "label": "Отец", - "value": "3290" - }, - { - "label": "Отношения", - "value": "398" - }, - { - "label": "Отношения человек/нечеловек", - "value": "7406" - }, - { - "label": "Офис", - "value": "3460" - }, - { - "label": "Охотники", - "value": "2263" - }, - { - "label": "Оцуцуки", - "value": "5101" - }, - { - "label": "Ошейник", - "value": "2362" - }, - { - "label": "Ояш", - "value": "8048" - }, - { - "label": "Падчерица", - "value": "7023" - }, - { - "label": "Падший ангел", - "value": "184" - }, - { - "label": "Палач", - "value": "852" - }, - { - "label": "Палочка", - "value": "2682" - }, - { - "label": "Пандорум", - "value": "4360" - }, - { - "label": "Папа и дочь", - "value": "7647" - }, - { - "label": "Паразит", - "value": "1213" - }, - { - "label": "Параллельный мир", - "value": "2092" - }, - { - "label": "Парень", - "value": "619" - }, - { - "label": "Паркур", - "value": "3391" - }, - { - "label": "Пародия", - "value": "898" - }, - { - "label": "Пасхалки", - "value": "455" - }, - { - "label": "Паук", - "value": "2209" - }, - { - "label": "Пекарь", - "value": "5073" - }, - { - "label": "Первая книга", - "value": "269" - }, - { - "label": "Первая любовь", - "value": "640" - }, - { - "label": "Первый раз", - "value": "1465" - }, - { - "label": "Переводы", - "value": "24" - }, - { - "label": "Перевоплощение", - "value": "1596" - }, - { - "label": "Перевоплощение в игровом мире", - "value": "92" - }, - { - "label": "Перемещение в другой мир", - "value": "1288" - }, - { - "label": "Перемещение во времени", - "value": "146" - }, - { - "label": "Перерождение", - "value": "894" - }, - { - "label": "Перерождение в демона", - "value": "1111" - }, - { - "label": "Перерождение в дракона", - "value": "6867" - }, - { - "label": "Перерождение в злодейку", - "value": "5619" - }, - { - "label": "Перерождение в злодея", - "value": "749" - }, - { - "label": "Перерождение в ином мире", - "value": "109" - }, - { - "label": "Перерождение в монстра", - "value": "917" - }, - { - "label": "Перерождений", - "value": "335" - }, - { - "label": "Переселение", - "value": "813" - }, - { - "label": "Переселение души", - "value": "1864" - }, - { - "label": "Перси джексон", - "value": "6329" - }, - { - "label": "Пилот", - "value": "5521" - }, - { - "label": "Пилюли", - "value": "1531" - }, - { - "label": "Пират", - "value": "1579" - }, - { - "label": "Пирог", - "value": "80" - }, - { - "label": "Писатель", - "value": "734" - }, - { - "label": "Пистолеты", - "value": "4916" - }, - { - "label": "Письмо", - "value": "840" - }, - { - "label": "Питомцы", - "value": "3122" - }, - { - "label": "Планомерное развитие событий", - "value": "62" - }, - { - "label": "Племянник", - "value": "8303" - }, - { - "label": "Пленница", - "value": "4897" - }, - { - "label": "Плети", - "value": "4839" - }, - { - "label": "Пляж", - "value": "4243" - }, - { - "label": "Повар", - "value": "658" - }, - { - "label": "Повествование от первого лица", - "value": "1054" - }, - { - "label": "Повествование от разных лиц", - "value": "600" - }, - { - "label": "Повествование от третьего лица", - "value": "2116" - }, - { - "label": "Подавитель", - "value": "497" - }, - { - "label": "Подземелье", - "value": "798" - }, - { - "label": "Подростки", - "value": "636" - }, - { - "label": "Подруга", - "value": "5804" - }, - { - "label": "Подчинение", - "value": "8343" - }, - { - "label": "Подчинение и унижение", - "value": "4500" - }, - { - "label": "Покемоны", - "value": "2840" - }, - { - "label": "Полиамория", - "value": "1300" - }, - { - "label": "Полигамия", - "value": "1336" - }, - { - "label": "Политика", - "value": "1313" - }, - { - "label": "Полицейский", - "value": "1907" - }, - { - "label": "Полубог", - "value": "7170" - }, - { - "label": "Полукровка", - "value": "999" - }, - { - "label": "Полулюди", - "value": "2273" - }, - { - "label": "Поношенные трусики", - "value": "1204" - }, - { - "label": "Попаданец", - "value": "2396" - }, - { - "label": "Попаданец в другой мир", - "value": "685" - }, - { - "label": "Попаданец в игру", - "value": "6466" - }, - { - "label": "Попадание в книгу", - "value": "6957" - }, - { - "label": "Постапокалипсис", - "value": "1079" - }, - { - "label": "Похищение", - "value": "7452" - }, - { - "label": "Поэзия", - "value": "1120" - }, - { - "label": "Правитель", - "value": "2261" - }, - { - "label": "Превращения в животных", - "value": "3410" - }, - { - "label": "Преданный любовный интерес", - "value": "2055" - }, - { - "label": "Предательство", - "value": "70" - }, - { - "label": "Президент", - "value": "4334" - }, - { - "label": "Преступник", - "value": "4049" - }, - { - "label": "Преступный мир", - "value": "965" - }, - { - "label": "Призрак", - "value": "511" - }, - { - "label": "Призыв", - "value": "332" - }, - { - "label": "Призыв в другой мир", - "value": "781" - }, - { - "label": "Призыв существ", - "value": "412" - }, - { - "label": "Приложение на телефоне", - "value": "5345" - }, - { - "label": "Принудительный брак", - "value": "2954" - }, - { - "label": "Принуждение", - "value": "1442" - }, - { - "label": "Принц", - "value": "362" - }, - { - "label": "Принцесса", - "value": "2403" - }, - { - "label": "Приручение мостров", - "value": "2338" - }, - { - "label": "Прислуга", - "value": "5185" - }, - { - "label": "Пришельцы", - "value": "273" - }, - { - "label": "Проза", - "value": "2012" - }, - { - "label": "Прокачка", - "value": "1070" - }, - { - "label": "Проклятия", - "value": "1347" - }, - { - "label": "Проработанный мир", - "value": "1711" - }, - { - "label": "Пророчество", - "value": "7762" - }, - { - "label": "Против наркотиков", - "value": "8406" - }, - { - "label": "Псайкеры", - "value": "3659" - }, - { - "label": "Псионика", - "value": "5216" - }, - { - "label": "Психбольница", - "value": "6969" - }, - { - "label": "Психические расстройства", - "value": "2445" - }, - { - "label": "Психологические травмы", - "value": "3418" - }, - { - "label": "Публичный дом", - "value": "7860" - }, - { - "label": "Путешествие в другой мир", - "value": "10" - }, - { - "label": "Пух", - "value": "4286" - }, - { - "label": "Пушечное мясо", - "value": "7234" - }, - { - "label": "Пытки", - "value": "1756" - }, - { - "label": "Пьяный мастер", - "value": "1655" - }, - { - "label": "Пэнси паркинсон", - "value": "7411" - }, - { - "label": "Раб", - "value": "977" - }, - { - "label": "Рабы", - "value": "1240" - }, - { - "label": "Разведение животных", - "value": "3990" - }, - { - "label": "Развитие", - "value": "208" - }, - { - "label": "Развитие персонажа", - "value": "1780" - }, - { - "label": "Развитие поселения", - "value": "7203" - }, - { - "label": "Развитие технологий", - "value": "1875" - }, - { - "label": "Раздвоение личности", - "value": "2062" - }, - { - "label": "Разные расы", - "value": "1188" - }, - { - "label": "Разорванная помолвка", - "value": "2057" - }, - { - "label": "Разработчик", - "value": "2333" - }, - { - "label": "Ранги", - "value": "1568" - }, - { - "label": "Ранобэ", - "value": "1764" - }, - { - "label": "Расизм", - "value": "3554" - }, - { - "label": "Растение", - "value": "407" - }, - { - "label": "Реализм", - "value": "1180" - }, - { - "label": "Ребенок", - "value": "2881" - }, - { - "label": "Ревность", - "value": "293" - }, - { - "label": "Революция", - "value": "3996" - }, - { - "label": "Реинкарнация", - "value": "1302" - }, - { - "label": "Реинкарнация в другом мире", - "value": "2180" - }, - { - "label": "Реинкарнация в игровой мир", - "value": "304" - }, - { - "label": "Рейджер", - "value": "5147" - }, - { - "label": "Религия", - "value": "2184" - }, - { - "label": "Рем", - "value": "6655" - }, - { - "label": "Ремесленник", - "value": "1483" - }, - { - "label": "Ремонт", - "value": "5703" - }, - { - "label": "Репликаторы", - "value": "3495" - }, - { - "label": "Ресторан", - "value": "7519" - }, - { - "label": "Риас гремори", - "value": "6950" - }, - { - "label": "Рим", - "value": "612" - }, - { - "label": "Риннеган", - "value": "4230" - }, - { - "label": "Ритуал", - "value": "1233" - }, - { - "label": "Робот", - "value": "4011" - }, - { - "label": "Роботы", - "value": "467" - }, - { - "label": "Рок ли", - "value": "7002" - }, - { - "label": "Рокси", - "value": "7380" - }, - { - "label": "Рон уизли", - "value": "4279" - }, - { - "label": "Ророноа зоро", - "value": "1590" - }, - { - "label": "Росомаха", - "value": "1035" - }, - { - "label": "Российская империя", - "value": "2146" - }, - { - "label": "Россия", - "value": "4246" - }, - { - "label": "Рудеус", - "value": "7379" - }, - { - "label": "Руны", - "value": "2393" - }, - { - "label": "Русалки", - "value": "3127" - }, - { - "label": "Русь", - "value": "2016" - }, - { - "label": "Рыцари", - "value": "1902" - }, - { - "label": "Рэо хатаке", - "value": "2823" - }, - { - "label": "Сабли", - "value": "6136" - }, - { - "label": "Сайян", - "value": "6802" - }, - { - "label": "Сакура", - "value": "2515" - }, - { - "label": "Самец", - "value": "1592" - }, - { - "label": "Самураи", - "value": "576" - }, - { - "label": "Санса старк", - "value": "3925" - }, - { - "label": "Сарказм", - "value": "4658" - }, - { - "label": "Саске", - "value": "7237" - }, - { - "label": "Сатира", - "value": "215" - }, - { - "label": "Сборник", - "value": "7367" - }, - { - "label": "Свадьба", - "value": "1524" - }, - { - "label": "Сверхсила", - "value": "1055" - }, - { - "label": "Свинцовые книги", - "value": "5322" - }, - { - "label": "Связывание", - "value": "4506" - }, - { - "label": "Священик", - "value": "61" - }, - { - "label": "Северус снейп", - "value": "5783" - }, - { - "label": "Сёдзе", - "value": "2219" - }, - { - "label": "Секты", - "value": "1234" - }, - { - "label": "Сельское хозяйство", - "value": "787" - }, - { - "label": "Семейный конфликт", - "value": "935" - }, - { - "label": "Семья", - "value": "728" - }, - { - "label": "Сенджу", - "value": "6069" - }, - { - "label": "Серийный убийца", - "value": "261" - }, - { - "label": "Сестра", - "value": "2342" - }, - { - "label": "Сила глаза", - "value": "1019" - }, - { - "label": "Сильная героиня", - "value": "7292" - }, - { - "label": "Сильная главная героиня", - "value": "1994" - }, - { - "label": "Сильный главный герой", - "value": "570" - }, - { - "label": "Сильфиетта", - "value": "7381" - }, - { - "label": "Симбиот", - "value": "2648" - }, - { - "label": "Сириус блэк", - "value": "7655" - }, - { - "label": "Сирота", - "value": "297" - }, - { - "label": "Система", - "value": "251" - }, - { - "label": "Система уровней", - "value": "2174" - }, - { - "label": "Ситх", - "value": "1618" - }, - { - "label": "Сказка", - "value": "3570" - }, - { - "label": "Скайрим", - "value": "4032" - }, - { - "label": "Скайуокер", - "value": "6828" - }, - { - "label": "Сквиб", - "value": "4101" - }, - { - "label": "Скелет", - "value": "1315" - }, - { - "label": "Скрытые способности", - "value": "3417" - }, - { - "label": "Скульптор", - "value": "1178" - }, - { - "label": "Слабая главная героиня", - "value": "5805" - }, - { - "label": "Слабый главный герой", - "value": "731" - }, - { - "label": "Славяне", - "value": "2168" - }, - { - "label": "Слизерин", - "value": "6979" - }, - { - "label": "Слизь", - "value": "1095" - }, - { - "label": "Сломанная игрушка", - "value": "8396" - }, - { - "label": "Служанка", - "value": "3486" - }, - { - "label": "Смартфон", - "value": "457" - }, - { - "label": "Смена сущности", - "value": "8391" - }, - { - "label": "Смерть", - "value": "1779" - }, - { - "label": "Смерть основного персонажа", - "value": "1530" - }, - { - "label": "Собаки", - "value": "6109" - }, - { - "label": "Соблазн", - "value": "7994" - }, - { - "label": "Соблазнение", - "value": "2290" - }, - { - "label": "Современность", - "value": "568" - }, - { - "label": "Современные знания", - "value": "988" - }, - { - "label": "Сожительство", - "value": "3026" - }, - { - "label": "Создание армии", - "value": "1992" - }, - { - "label": "Создание королевства", - "value": "1497" - }, - { - "label": "Создание пилюль", - "value": "816" - }, - { - "label": "Создатель", - "value": "1045" - }, - { - "label": "Сокровища", - "value": "6521" - }, - { - "label": "Сокрытие истинной личности", - "value": "2894" - }, - { - "label": "Сома и эрина", - "value": "5737" - }, - { - "label": "Соперничество", - "value": "7699" - }, - { - "label": "Соседи", - "value": "4075" - }, - { - "label": "Сотрудник", - "value": "6339" - }, - { - "label": "Социология", - "value": "7618" - }, - { - "label": "Спокойная главная героиня", - "value": "236" - }, - { - "label": "Спокойный главный герой", - "value": "1656" - }, - { - "label": "Спор", - "value": "3484" - }, - { - "label": "Спортивное тело", - "value": "8317" - }, - { - "label": "Способность кражи", - "value": "7784" - }, - { - "label": "Сражения", - "value": "23" - }, - { - "label": "Средневековье", - "value": "1022" - }, - { - "label": "Сталкер", - "value": "1932" - }, - { - "label": "Становление государства", - "value": "111" - }, - { - "label": "Старшая школа", - "value": "1658" - }, - { - "label": "Стёб", - "value": "454" - }, - { - "label": "Стекло", - "value": "7453" - }, - { - "label": "Стеснительный персонаж", - "value": "152" - }, - { - "label": "Стимпанк", - "value": "1894" - }, - { - "label": "Стихи", - "value": "1309" - }, - { - "label": "Стратегия", - "value": "569" - }, - { - "label": "Строительство", - "value": "921" - }, - { - "label": "Студент", - "value": "1464" - }, - { - "label": "Студентка", - "value": "7518" - }, - { - "label": "Суккубы", - "value": "2662" - }, - { - "label": "Супер зрение", - "value": "6574" - }, - { - "label": "Супер удача", - "value": "489" - }, - { - "label": "Супергерои", - "value": "1481" - }, - { - "label": "Суперзлодеи", - "value": "2125" - }, - { - "label": "Супермен", - "value": "6997" - }, - { - "label": "Суперсилы", - "value": "2276" - }, - { - "label": "Существа", - "value": "6033" - }, - { - "label": "Сферы", - "value": "1077" - }, - { - "label": "Схемы и заговоры", - "value": "7116" - }, - { - "label": "Сценарий", - "value": "7489" - }, - { - "label": "Счастливый конец", - "value": "3293" - }, - { - "label": "Сын", - "value": "3297" - }, - { - "label": "Сэм винчестер", - "value": "7461" - }, - { - "label": "Сюаньхуа", - "value": "2560" - }, - { - "label": "Сюжетные повороты", - "value": "7202" - }, - { - "label": "Таблетки для развития", - "value": "589" - }, - { - "label": "Таинственное прошлое", - "value": "769" - }, - { - "label": "Тайная личность", - "value": "8096" - }, - { - "label": "Тайная любовь", - "value": "113" - }, - { - "label": "Тайны", - "value": "7481" - }, - { - "label": "Тайные отношения", - "value": "7450" - }, - { - "label": "Тайцы", - "value": "6413" - }, - { - "label": "Танки", - "value": "1787" - }, - { - "label": "Творчество", - "value": "20" - }, - { - "label": "Тейлор эберт", - "value": "3526" - }, - { - "label": "Телекинез", - "value": "2203" - }, - { - "label": "Телепортация", - "value": "914" - }, - { - "label": "Телохранитель", - "value": "723" - }, - { - "label": "Темари", - "value": "4810" - }, - { - "label": "Темная магия", - "value": "4788" - }, - { - "label": "Темное фэнтези", - "value": "1675" - }, - { - "label": "Темные эльфы", - "value": "7198" - }, - { - "label": "Тенсейган", - "value": "4367" - }, - { - "label": "Тетя", - "value": "4194" - }, - { - "label": "Техномагия", - "value": "508" - }, - { - "label": "Тиран", - "value": "1174" - }, - { - "label": "Титаны", - "value": "3308" - }, - { - "label": "Тодороки шото", - "value": "5105" - }, - { - "label": "Токио", - "value": "5791" - }, - { - "label": "Том реддл", - "value": "6652" - }, - { - "label": "Тони старк", - "value": "1338" - }, - { - "label": "Тор", - "value": "1800" - }, - { - "label": "Тор и локи", - "value": "2645" - }, - { - "label": "Торговля", - "value": "1637" - }, - { - "label": "Травничество", - "value": "221" - }, - { - "label": "Трагическое прошлое", - "value": "644" - }, - { - "label": "Трактир", - "value": "1918" - }, - { - "label": "Трансмиграция", - "value": "1071" - }, - { - "label": "Трансформация", - "value": "156" - }, - { - "label": "Трансформеры", - "value": "4616" - }, - { - "label": "Тревор филипс", - "value": "5427" - }, - { - "label": "Тройняшки", - "value": "7169" - }, - { - "label": "Троли", - "value": "4250" - }, - { - "label": "Трудолюбивый главный герой", - "value": "248" - }, - { - "label": "Тупой главный герой", - "value": "3710" - }, - { - "label": "Тьма", - "value": "1919" - }, - { - "label": "Тюрьма", - "value": "5597" - }, - { - "label": "Тяжёлое детство", - "value": "2253" - }, - { - "label": "Убийства", - "value": "378" - }, - { - "label": "Убийцы", - "value": "1766" - }, - { - "label": "Убийцы драконов", - "value": "1484" - }, - { - "label": "Увечья", - "value": "3266" - }, - { - "label": "Удача", - "value": "6575" - }, - { - "label": "Узумаки", - "value": "7579" - }, - { - "label": "Укротитель", - "value": "367" - }, - { - "label": "Умения", - "value": "531" - }, - { - "label": "Умная главная героиня", - "value": "1381" - }, - { - "label": "Умные персонажи", - "value": "2756" - }, - { - "label": "Умный главный герой", - "value": "2093" - }, - { - "label": "Университет", - "value": "2102" - }, - { - "label": "Унижение", - "value": "8342" - }, - { - "label": "Уничтожение мира", - "value": "81" - }, - { - "label": "Управление временем", - "value": "5648" - }, - { - "label": "Уровни", - "value": "8" - }, - { - "label": "Усиление", - "value": "3549" - }, - { - "label": "Усопп", - "value": "6737" - }, - { - "label": "Устроенный брак", - "value": "2223" - }, - { - "label": "Усыновление", - "value": "395" - }, - { - "label": "Утопия", - "value": "4677" - }, - { - "label": "Уход за детьми", - "value": "7609" - }, - { - "label": "Учеба в университете", - "value": "2797" - }, - { - "label": "Учебное заведение", - "value": "1817" - }, - { - "label": "Ученые", - "value": "1843" - }, - { - "label": "Учитель", - "value": "845" - }, - { - "label": "Учиха", - "value": "5348" - }, - { - "label": "Фамильяры", - "value": "1471" - }, - { - "label": "Фанатичная любовь", - "value": "6721" - }, - { - "label": "Фанаты", - "value": "7739" - }, - { - "label": "Фантастический мир", - "value": "2414" - }, - { - "label": "Фармацевт", - "value": "1706" - }, - { - "label": "Фашисты", - "value": "3118" - }, - { - "label": "Феи", - "value": "7185" - }, - { - "label": "Фелляция", - "value": "5880" - }, - { - "label": "Феминизм", - "value": "6527" - }, - { - "label": "Феникс", - "value": "2413" - }, - { - "label": "Фенрир", - "value": "2740" - }, - { - "label": "Феодализм", - "value": "280" - }, - { - "label": "Ферма", - "value": "285" - }, - { - "label": "Фехтовальщик", - "value": "4685" - }, - { - "label": "Филиппины", - "value": "128" - }, - { - "label": "Философия", - "value": "1859" - }, - { - "label": "Флафф", - "value": "5048" - }, - { - "label": "Флер делакур", - "value": "5191" - }, - { - "label": "Флэш", - "value": "4667" - }, - { - "label": "Фокусник", - "value": "7602" - }, - { - "label": "Фольклор", - "value": "4086" - }, - { - "label": "Фугаку", - "value": "6161" - }, - { - "label": "Фурри", - "value": "6631" - }, - { - "label": "Футбол", - "value": "1121" - }, - { - "label": "Фэнтезийный мир", - "value": "1556" - }, - { - "label": "Хакер", - "value": "475" - }, - { - "label": "Халк", - "value": "1196" - }, - { - "label": "Хан нуньен синг", - "value": "4817" - }, - { - "label": "Ханма юджиро", - "value": "4369" - }, - { - "label": "Хаос", - "value": "3117" - }, - { - "label": "Харизматичный главный герой", - "value": "2350" - }, - { - "label": "Хатаке какаши", - "value": "2820" - }, - { - "label": "Хиддлстон", - "value": "5903" - }, - { - "label": "Химавари", - "value": "2583" - }, - { - "label": "Хината", - "value": "2513" - }, - { - "label": "Хитрый главный герой", - "value": "2036" - }, - { - "label": "Хоббит", - "value": "6698" - }, - { - "label": "Хогвартс", - "value": "5954" - }, - { - "label": "Холодная главная героиня", - "value": "6507" - }, - { - "label": "Холодное оружие", - "value": "4889" - }, - { - "label": "Холодный главный герой", - "value": "2686" - }, - { - "label": "Храм", - "value": "2135" - }, - { - "label": "Христианство", - "value": "877" - }, - { - "label": "Художественная литература", - "value": "2380" - }, - { - "label": "Художница", - "value": "518" - }, - { - "label": "Хулиганы", - "value": "854" - }, - { - "label": "Цветок", - "value": "902" - }, - { - "label": "Цезарь", - "value": "1705" - }, - { - "label": "Целители", - "value": "4523" - }, - { - "label": "Церковь", - "value": "1980" - }, - { - "label": "Цундере", - "value": "1078" - }, - { - "label": "Чакра", - "value": "1393" - }, - { - "label": "Чат-система", - "value": "8407" - }, - { - "label": "Черный юмор", - "value": "2868" - }, - { - "label": "Честная главная героиня", - "value": "5855" - }, - { - "label": "Честный главный герой", - "value": "129" - }, - { - "label": "Читы", - "value": "451" - }, - { - "label": "Шантаж", - "value": "7175" - }, - { - "label": "Шаринган", - "value": "5165" - }, - { - "label": "Шинигами", - "value": "4661" - }, - { - "label": "Шиноби", - "value": "1227" - }, - { - "label": "Школьная жизнь", - "value": "284" - }, - { - "label": "Школьники", - "value": "218" - }, - { - "label": "Школьницы", - "value": "5946" - }, - { - "label": "Шлюха", - "value": "5822" - }, - { - "label": "Шоу-бизнес", - "value": "7119" - }, - { - "label": "Шпионы", - "value": "4262" - }, - { - "label": "Эволюция", - "value": "2040" - }, - { - "label": "Экзорцизм", - "value": "676" - }, - { - "label": "Экономика", - "value": "121" - }, - { - "label": "Экспансия", - "value": "110" - }, - { - "label": "Эксперименты над людьми", - "value": "7408" - }, - { - "label": "Элементальная магия", - "value": "1264" - }, - { - "label": "Эльфы", - "value": "1362" - }, - { - "label": "Эротика", - "value": "2053" - }, - { - "label": "Юмор", - "value": "7360" - }, - { - "label": "Яды", - "value": "201" - }, - { - "label": "Якудза", - "value": "4599" - }, - { - "label": "Яндере", - "value": "7111" - }, - { - "label": "Rpg", - "value": "90" - }, - { - "label": "Star wars", - "value": "1985" - }, - { - "label": "Time skip", - "value": "824" - }, - { - "label": "Warrior of light", - "value": "5289" - } - ], - "inputType": "Checkbox" - }, - { - "key": "fandoms_ex", - "label": "Исключить фэндомы:", - "values": [ - { - "label": "19 Дней - Один день / 19 Days - One Day", - "value": "838" - }, - { - "label": "47-й / Хитмэн: Агент 47 / Наёмный убийца / Hitman", - "value": "589" - }, - { - "label": "Абсолютный дуэт / Absolute Duo", - "value": "1029" - }, - { - "label": "Аватар (Короля; об Аанге; об Корре) / Avatar", - "value": "1889" - }, - { - "label": "Аватар: Легенда о Корре / Avatar legend of Korra", - "value": "351" - }, - { - "label": "Аватар: Легенда об Аанге / Avatar: The Legend of Aang / Avatar: The Last Airbender", - "value": "303" - }, - { - "label": "Аватар(Фильм, 2009) / Avatar", - "value": "19" - }, - { - "label": "Ад Данте(Данте Алигьери) / Dante's Inferno(Dante Alighieri)", - "value": "1502" - }, - { - "label": "Азур Лейн / Azur Lane", - "value": "1009" - }, - { - "label": "Айон / Aion", - "value": "1005" - }, - { - "label": "Аладдин / Aladdin", - "value": "502" - }, - { - "label": "Алиса в Стране чудес / Alice in Wonderland", - "value": "616" - }, - { - "label": "Альдноа.Зеро / Aldnoah.Zero", - "value": "1799" - }, - { - "label": "Амагами СС / Amagami SS", - "value": "900" - }, - { - "label": "Амано Мегуми полна любви! / Amano Megumi wa Sukidarake!", - "value": "991" - }, - { - "label": "Американские боги / American Gods", - "value": "1843" - }, - { - "label": "Американский папаша! / American Dad", - "value": "348" - }, - { - "label": "Ангельские ритмы! / Angel Beats!", - "value": "880" - }, - { - "label": "Анлимитед: Хёбу Кёске / Zettai Karen Children: The Unlimited - Hyoubu Kyousuke", - "value": "74" - }, - { - "label": "Апостол карточек / The Apostle of Cards", - "value": "1504" - }, - { - "label": "Арифурэта: сильнейший ремесленник в мире / Arifureta: From Commonplace to World's Strongest", - "value": "62" - }, - { - "label": "Аркан: О Паровых Заводах и Магии Обскуры / Arcanum: Of Steamworks and Magick Obscura", - "value": "1495" - }, - { - "label": "Аркейн / Arcane: League of Legends", - "value": "1154" - }, - { - "label": "Аркнайтс(Games) / Arknights", - "value": "1210" - }, - { - "label": "Армелло(Games) / Armello", - "value": "1846" - }, - { - "label": "Астра, затерянная в космосе / Kanata no Astra", - "value": "1851" - }, - { - "label": "Атака титанов / Атака на титанов / Attack on Titan", - "value": "106" - }, - { - "label": "Атлантида: Затерянный мир / Atlantis: The Lost Empire", - "value": "985" - }, - { - "label": "Бакуган Отчаянные бойцы / Bakugan Battle Brawlers", - "value": "1069" - }, - { - "label": "Банановая рыба / Banana Fish", - "value": "1685" - }, - { - "label": "Баскетбол Куроко / Kuroko no basuke", - "value": "582" - }, - { - "label": "Баффи - Истребительница вампиров / Buffy the Vampire Slayer", - "value": "115" - }, - { - "label": "Башня Бога / Tower of God", - "value": "58" - }, - { - "label": "Бездарная Нана / Munou na Nana", - "value": "954" - }, - { - "label": "Бездомный бог / Норагами / Noragami", - "value": "1014" - }, - { - "label": "Безумные Мотивы / Looney Tunes", - "value": "1140" - }, - { - "label": "Безумный азарт / Kakegurui", - "value": "334" - }, - { - "label": "Бейблэйд / Beyblade", - "value": "921" - }, - { - "label": "Бен - 10 / Ben 10", - "value": "475" - }, - { - "label": "Берсерк / Berserk", - "value": "479" - }, - { - "label": "Бесконечное лето / Everlasting Summer", - "value": "966" - }, - { - "label": "Бесконечный ужас / Terror Infinity", - "value": "381" - }, - { - "label": "Бесподобный Воинственный Бог / Peerless Martial God", - "value": "419" - }, - { - "label": "Бессмертный Деревенщина(Games) / Immortal Redneck", - "value": "1524" - }, - { - "label": "Бесстыжие / Shameless", - "value": "1759" - }, - { - "label": "Био шок(Games) / BioShock", - "value": "1095" - }, - { - "label": "Блейд / Blade", - "value": "1479" - }, - { - "label": "Блич / Bleach", - "value": "7" - }, - { - "label": "Бог войны / God Of War", - "value": "352" - }, - { - "label": "Бог из машины / Deus Ex", - "value": "612" - }, - { - "label": "Боги поступают плохо / Игры богов / Gods Behaving Badly", - "value": "301" - }, - { - "label": "Боевая академия города Астериск / Gakusen Toshi Asterisk", - "value": "884" - }, - { - "label": "Боевой континент / Combat Continent / Douluo Dalu", - "value": "739" - }, - { - "label": "Боевой молот 40-го тысячелетия / WH40K / Warhammer 40,000", - "value": "341" - }, - { - "label": "Боевой молот Фэнтезийная битва / Warhammer Fantasy Battles", - "value": "1742" - }, - { - "label": "Боевые машины(Games) / BattleTech", - "value": "1667" - }, - { - "label": "Боец Баки / Baki the Grappler", - "value": "821" - }, - { - "label": "Божественность II: Эго Дракона(Games) / Divinity II: Ego Draconis", - "value": "1538" - }, - { - "label": "Божественные Врата / Divine Gate", - "value": "1490" - }, - { - "label": "Большая автомобильная кража 5 / GTA V / Grand Theft Auto V", - "value": "1139" - }, - { - "label": "Большая автомобильная кража: Сан-Андреас / GTA: SA / Grand Theft Auto: San Andreas", - "value": "820" - }, - { - "label": "Большая разница / Far Cry", - "value": "939" - }, - { - "label": "Большой куш / Ван Пис / One Piece", - "value": "25" - }, - { - "label": "Боруто: Следующие поколения Наруто / Boruto: Naruto Next Generations", - "value": "602" - }, - { - "label": "Брак по договоренности с принцессой красных скорпионов / Arranged marriage to the princess of the Red Scorpions", - "value": "1386" - }, - { - "label": "Бэтмен за гранью: Наследие / Batman Beyond: Legacy", - "value": "1380" - }, - { - "label": "В другом мире со смартфоном / Isekai wa Smartphone to Tomo ni", - "value": "947" - }, - { - "label": "В объятиях шлюхи / JK Bitch ni Shiboraretai", - "value": "1283" - }, - { - "label": "В ожидании бедности, я собираюсь стать кузнецом / Expecting to Fall into Ruin, I Aim to Become a Blacksmith", - "value": "1475" - }, - { - "label": "В Повелителе как Довакин / In Overlord as a Dovahkiin", - "value": "1816" - }, - { - "label": "Вакфу / Wakfu", - "value": "814" - }, - { - "label": "ВАЛЛ-И / Wally", - "value": "801" - }, - { - "label": "Вампир: Маскарад - Родословные / Vampire: The Masquerade Bloodline", - "value": "1212" - }, - { - "label": "Вампирелла / Vampirella", - "value": "1214" - }, - { - "label": "Варфрейм / Warframe", - "value": "967" - }, - { - "label": "Ведьмак / The Witcher", - "value": "278" - }, - { - "label": "Великий из бродячих псов / Bungou Stray Dogs", - "value": "75" - }, - { - "label": "Великолепный парк Амаги / Amagi Brilliant Park", - "value": "813" - }, - { - "label": "Вельзепуз / Вельзевул / Beelzebub", - "value": "765" - }, - { - "label": "Веном / Venom", - "value": "978" - }, - { - "label": "Веселая ферма / Fun Farm", - "value": "1124" - }, - { - "label": "Вечная история / The Neverending Story", - "value": "547" - }, - { - "label": "Вечные(Фильм, 2021) / Eternal", - "value": "1234" - }, - { - "label": "Виви: Песнь флюоритового глаза / Vivy: Fluorite Eye's Song", - "value": "1819" - }, - { - "label": "Викинги / Vikings", - "value": "369" - }, - { - "label": "Владелец ранчо со слизью(Games) / Ранчо слизи / Slime Rancher", - "value": "1529" - }, - { - "label": "Властелин колец / Lord of the Ring", - "value": "254" - }, - { - "label": "Власть книжного червя / Honzuki no Gekokujou", - "value": "1399" - }, - { - "label": "Внук Мудрец / Kenjo no Mago", - "value": "1260" - }, - { - "label": "Внук Нурарихёна / Nurarihyon no Mago", - "value": "66" - }, - { - "label": "Во всеоружии / Overgeared", - "value": "1021" - }, - { - "label": "Во тьме(Games) / The Darkness", - "value": "938" - }, - { - "label": "Военная хроника маленькой девочки / Сага о злой Тане / The Saga of Tanya the Evil / \tGekijouban Youjo Senki", - "value": "1726" - }, - { - "label": "Возвращение в детские годы / Gaki ni Modotte Yarinaoshi!!!", - "value": "1031" - }, - { - "label": "Возрождение Серийного Убийцы / Rebirth Of A Serial Killer", - "value": "1358" - }, - { - "label": "Воинственный Бог Асура / Martial God Asura", - "value": "771" - }, - { - "label": "Война будущего / The Tomorrow War", - "value": "1174" - }, - { - "label": "Война Любовь Снег / War Love Snow", - "value": "1417" - }, - { - "label": "Волейбол! / Haikyuu!!", - "value": "697" - }, - { - "label": "Волчонок / Teen Wolf", - "value": "795" - }, - { - "label": "Волшебная Девушка Спецоперация Аска / Magical Girl Spec-Ops Asuka", - "value": "1470" - }, - { - "label": "Волшебник-воин Орфен / Majutsushi Orphen Hagure Tabi: Kimluck-hen", - "value": "1128" - }, - { - "label": "Волшебники / The Magicians", - "value": "1314" - }, - { - "label": "Волшебный учитель Нэгима! / Negima!: Magister Negi Mag", - "value": "1777" - }, - { - "label": "Воля второго цикла мироздания. / Will of the second cycle of the Worldifice.", - "value": "1036" - }, - { - "label": "Воспитание хозяина / Yours to Claim", - "value": "839" - }, - { - "label": "Восставший против неба / Against the Gods", - "value": "957" - }, - { - "label": "Восстание стражей / Хранители снов / Rise of the Guardians", - "value": "1488" - }, - { - "label": "Восхождение в Голливуде / I'm in Hollywood", - "value": "1237" - }, - { - "label": "Восхождение героя щита / The Rising of the Shield Hero", - "value": "103" - }, - { - "label": "Врата Штейна / Steins: Gate", - "value": "1044" - }, - { - "label": "Врата: там бьются наши воины / Gate: Jieitai Kanochi nite, Kaku Tatakaeri", - "value": "727" - }, - { - "label": "Время / In Time", - "value": "542" - }, - { - "label": "Всегда вялый Танака-кун / Tanaka-kun wa Itsumo Kedaruge", - "value": "1082" - }, - { - "label": "Всего лишь восьмой сын? Я с этим не смирюсь! / Hachinan tte, Sore wa Nai Deshou! / Eighth son, I don’t think so!", - "value": "1473" - }, - { - "label": "Вселенная Марвел / Marvel Universe / Marvel Comics", - "value": "6" - }, - { - "label": "Вселенная монстров / Monsterverse / Monster Verse", - "value": "905" - }, - { - "label": "Вселенная Стивена / Steven universe", - "value": "573" - }, - { - "label": "Вселенная Стрелы / Arrowverse", - "value": "488" - }, - { - "label": "Вселенная Тип Луны(Игровая компания) / Universe Type Moon", - "value": "1221" - }, - { - "label": "Вселенная DC / DC Universe / DC Comics", - "value": "36" - }, - { - "label": "Выпадение радиоактивных осадков / Fallout", - "value": "55" - }, - { - "label": "Выращивание онлайн / Cultivation Online", - "value": "1252" - }, - { - "label": "Галактическая секс-звезда / Galaxy Sex Star", - "value": "1539" - }, - { - "label": "Гало(Games) / Halo", - "value": "1338" - }, - { - "label": "Ганц / Gantz", - "value": "256" - }, - { - "label": "Гарем рабов в лабиринте другого мира / Slave Harem in the Labyrinth of the Other World", - "value": "1853" - }, - { - "label": "Гарри Поттер / Harry Potter", - "value": "1" - }, - { - "label": "Гвен-паук / Spider-Gwen", - "value": "920" - }, - { - "label": "Генерал маньяк с его сумасшедшей системой / The Maniacal General with his Crazy System", - "value": "1356" - }, - { - "label": "Генерал, вы вправе уйти. / General, You May Leave Now", - "value": "1385" - }, - { - "label": "Геншин Импакт / Genshin Impact", - "value": "689" - }, - { - "label": "Геркулес / Hercules", - "value": "721" - }, - { - "label": "Герои и замки / Heroes & Castles", - "value": "940" - }, - { - "label": "Герои меча и магии / Heroes of Might and Magic", - "value": "1002" - }, - { - "label": "Герои(телесериал) / Heroes", - "value": "864" - }, - { - "label": "Гильгамеш / Gilgamesh", - "value": "1143" - }, - { - "label": "Гинтама / Gintama", - "value": "129" - }, - { - "label": "Глубина(Фильм, 2002) / Below", - "value": "1186" - }, - { - "label": "Гнев Асуры / Asura's wrath", - "value": "100" - }, - { - "label": "Годзилла / Godzilla", - "value": "922" - }, - { - "label": "Голодные игры / The Hunger Games", - "value": "859" - }, - { - "label": "Горец / Highlander", - "value": "1761" - }, - { - "label": "Горожане(Games) / Townsmen", - "value": "1599" - }, - { - "label": "Госпожа Кагуя: в любви как на войне / Kaguya sama: Love is war", - "value": "533" - }, - { - "label": "Готика / Gothic", - "value": "418" - }, - { - "label": "Готов ли ты влюбиться в извращенку до тех пор, пока она милая? / Hentai demo Suki ni Natte Kuremasu ka", - "value": "1383" - }, - { - "label": "Гоэтия / Гоетия / Yοητεία / Ars Goetia", - "value": "772" - }, - { - "label": "Гравити Фолз / Gravity Falls", - "value": "491" - }, - { - "label": "Граница пустоты / Kara no Kyoukai", - "value": "1101" - }, - { - "label": "Гриффины / Family Guy", - "value": "349" - }, - { - "label": "Гром над небом / Thunder over the sky", - "value": "793" - }, - { - "label": "Гуррен-Лаганн / Tengen Toppa Gurren Lagann", - "value": "719" - }, - { - "label": "Да будет благословенен этот прекрасный мир! / Konosuba / Kono Subarashii Sekai ni Shukufuku wo!", - "value": "82" - }, - { - "label": "Да Здравствует Призыв! / Long Live Summons!", - "value": "948" - }, - { - "label": "Да, я паук, и что с того? / So I'm a Spider, So What? / Kumo Desu ga, Nani ka?", - "value": "910" - }, - { - "label": "Данганронпа / Danganronpa", - "value": "972" - }, - { - "label": "Две звезды Онмёджи / Sousei no Onmyouji", - "value": "1108" - }, - { - "label": "Дворянство / Благородство / Noblesse", - "value": "636" - }, - { - "label": "Девочка-волшебница Мадока Магика / Mahou Shoujo Madoka Magica", - "value": "1412" - }, - { - "label": "Девочка, которая видит это / Mieruko-chan", - "value": "1645" - }, - { - "label": "Декстер(телесериал) / Dexter", - "value": "1543" - }, - { - "label": "Демон Бездны всех царств / Abyss Demon of All Realms", - "value": "1419" - }, - { - "label": "Демоны старшей школы / High School DxD", - "value": "8" - }, - { - "label": "День независимости(Фильм, 1996) / Independence Day", - "value": "850" - }, - { - "label": "Детектив Конан / Detective Conan", - "value": "1554" - }, - { - "label": "Дети индиго из другого мира / Mondaiji-tachi ga isekai kara kuru sô desu yo", - "value": "1484" - }, - { - "label": "Джаггед Альянс 2: Агония Власти(Games) / Jagged Alliance 2", - "value": "1668" - }, - { - "label": "Джессика Джонс / Marvel's Jessica Jones", - "value": "1817" - }, - { - "label": "Джон Уик / John Wick", - "value": "388" - }, - { - "label": "Дисней / The Walt Disney Company", - "value": "503" - }, - { - "label": "Для тебя, Бессмертный / Fumetsu no Anata e / To Your Eternity", - "value": "1802" - }, - { - "label": "Дневник Будущего / Mirai Nikki", - "value": "368" - }, - { - "label": "Дневники вампира / The Vampire Diaries", - "value": "160" - }, - { - "label": "Доблесть рыцаря-неудачника / Chivalry of a Failed Knight", - "value": "1462" - }, - { - "label": "Добро пожаловать в ад, Ирума / Welcome to Demon School! Iruma-kun", - "value": "261" - }, - { - "label": "Добро пожаловать в класс превосходства / Classroom of the Elite", - "value": "122" - }, - { - "label": "Добро пожаловать! В лес похотливых эльфов! / Youkoso! Sukebe Elf no Mori e", - "value": "1034" - }, - { - "label": "Добывать ремесло / Майнкрафт / Minecraft", - "value": "102" - }, - { - "label": "Доктор Кто / Doctor Who", - "value": "277" - }, - { - "label": "Доктор Стоун / Dr. Stone", - "value": "720" - }, - { - "label": "Доля секунды: скорость / Split - second: velocity", - "value": "890" - }, - { - "label": "Дом кролика / Кофейня "Кроличий домик" / Gochuumon wa Usagi Desu ka?", - "value": "642" - }, - { - "label": "Домашний очаг / Hearthstone: Heroes of Warcraft / Hearthstone", - "value": "934" - }, - { - "label": "Домекано / Domestic Na Kanojo", - "value": "632" - }, - { - "label": "Дорогой звёзд / Звёздное преобразование / Stellar Transformation / Xing Chen Bian", - "value": "1155" - }, - { - "label": "Доспехи Бога 2: Операция Кондор / Armour of God II: Operation Condor", - "value": "1829" - }, - { - "label": "Дота 2 / Dota 2", - "value": "1105" - }, - { - "label": "Дофус / Dofus", - "value": "817" - }, - { - "label": "Дракенгард / Drakengard / Drag-On Dragoon", - "value": "919" - }, - { - "label": "Дракон-горничная госпожи Кобаяси / Kobayashi-san Chi no Maid Dragon", - "value": "673" - }, - { - "label": "Дракон-сама из семьи Касумигаока / Dragon-sama of the Kasumigaoka Family", - "value": "1458" - }, - { - "label": "Драконий жемчуг Зет / Dragon Ball Z", - "value": "307" - }, - { - "label": "Дракониум Онлайн / Draconic Online", - "value": "1360" - }, - { - "label": "Дракула / Dracula", - "value": "709" - }, - { - "label": "Древнегреческая мифология / Ancient Greek mythology", - "value": "1159" - }, - { - "label": "Дре́вние / Первородные / The Originals", - "value": "863" - }, - { - "label": "Древние свитки / The Elder Scrolls", - "value": "428" - }, - { - "label": "Древние свитки: Скайрим / TES: Skyrim", - "value": "337" - }, - { - "label": "Другой мир / Underworld", - "value": "480" - }, - { - "label": "Друид с Сеульской станции / Seoul Station Druid", - "value": "1178" - }, - { - "label": "Дьявол / Диабло / Diablo", - "value": "1787" - }, - { - "label": "Дьявол может плакать / Devil May Cry / DMC", - "value": "339" - }, - { - "label": "Дьявол Юраги-су / The Devil of Yuragi-sou", - "value": "431" - }, - { - "label": "Дьявол II(Games) / Диабло II / Diablo II", - "value": "1055" - }, - { - "label": "Дэдпул / Deadpool", - "value": "810" - }, - { - "label": "Дэнни-призрак / Danny Phantom", - "value": "109" - }, - { - "label": "Евангелион / Neon Genesis Evangelion", - "value": "583" - }, - { - "label": "Единство семи магов / Тринити: Семь Магов / Trinity Seven", - "value": "442" - }, - { - "label": "Еженедельный прыжок сёнэн / Weekly Shōnen Jump", - "value": "1629" - }, - { - "label": "Ёрмунганд / Jormungand", - "value": "77" - }, - { - "label": "Жажда скорости / Need For Speed", - "value": "1493" - }, - { - "label": "Железный человек / Iron Man", - "value": "710" - }, - { - "label": "Жемчуг дракона / Dragon Ball", - "value": "309" - }, - { - "label": "Женщина-Халк(телесериал) / She-Hulk: Attorney at Law", - "value": "1593" - }, - { - "label": "Жизнь девушки в игровом мире / A Girl’s Life In A Gaming World", - "value": "1406" - }, - { - "label": "Жизнь после / Days Gone", - "value": "1279" - }, - { - "label": "За гранью / Beyond the Boundary", - "value": "357" - }, - { - "label": "Загипнотизировать Семью / Kyonyuu Kazoku Saimin", - "value": "1032" - }, - { - "label": "Закон Уэки / The Law of Ueki", - "value": "790" - }, - { - "label": "Закулисье / Backrooms", - "value": "1827" - }, - { - "label": "Зачарованные / Charmed", - "value": "113" - }, - { - "label": "Защитники / Defenders", - "value": "1832" - }, - { - "label": "Защитница Химари / Omamori Himari", - "value": "279" - }, - { - "label": "Звёздная принцесса и силы зла\t / Стар против сил зла / Star vs. The Forces of Evil", - "value": "782" - }, - { - "label": "Звёздное дитя / Oshi no Ko", - "value": "1903" - }, - { - "label": "Звёздное ремесло / StarCraft", - "value": "386" - }, - { - "label": "Звездные Войны / Star Wars", - "value": "40" - }, - { - "label": "Звёздные войны: Войны клонов - Все типы носителей(мультсериал, 2008) / Star Wars: The Clone Wars", - "value": "1182" - }, - { - "label": "Звёздные врата / Stargate", - "value": "770" - }, - { - "label": "Звёздные врата: Атлантида / Stargate: Atlantis", - "value": "1097" - }, - { - "label": "Звездный путь / Стартрек / Star Trek", - "value": "849" - }, - { - "label": "Зверополис / Zootopia", - "value": "1449" - }, - { - "label": "Зеленая Жизнь / Green Life", - "value": "1196" - }, - { - "label": "Зеленый фонарь / The Green Lantern", - "value": "1222" - }, - { - "label": "Зетмен / Zetman", - "value": "1191" - }, - { - "label": "Игра в кальмара(телесериал) / Squid game", - "value": "1065" - }, - { - "label": "Игра престолов / Game of Thrones", - "value": "22" - }, - { - "label": "Игрок / The Gamer", - "value": "126" - }, - { - "label": "Идеальная судьба / The Perfect Destiny", - "value": "781" - }, - { - "label": "Идолмастер / The Idolmaster", - "value": "807" - }, - { - "label": "Иерихон Клайва Баркера / Иерихон / Clive Barker’s Jericho /Jericho", - "value": "320" - }, - { - "label": "Извивающийся дракон / Coiling Dragon", - "value": "692" - }, - { - "label": "Изгнаные королевства РПГ / Exiled Kingdoms RPG", - "value": "1375" - }, - { - "label": "Импульс Валькирии: Сирена / Варукири Дораиву: Сирена / Valkyrie Drive: Mermaid", - "value": "1736" - }, - { - "label": "Индекс волшебства / A Certain Magical Index", - "value": "68" - }, - { - "label": "Инуяша - Пес-демон / InuYasha", - "value": "481" - }, - { - "label": "Искусственный отбор / Triage X", - "value": "1037" - }, - { - "label": "Истинный мир боевых искусств / Zhenwu Shijie / True Martial World", - "value": "867" - }, - { - "label": "История монстров / Monogatari", - "value": "911" - }, - { - "label": "История о второстепенном персонаже который стал игроком в другой игре. / The story is about a minor character who became a player in another game.", - "value": "868" - }, - { - "label": "Кабанери железной крепости / Koutetsujou no Kabaneri", - "value": "1494" - }, - { - "label": "Каждый раз, когда я сплю, моя душа покидает мое тело / Every Day I Sleep, My Soul Goes Out of My Body", - "value": "1048" - }, - { - "label": "Как воспитать героиню из обычной девушки / Saenai Heroine no Sodatekata", - "value": "1637" - }, - { - "label": "Как игрок глупой FPS попал в иной мир / Как дурачок из стрелялки в другой мир попал / Manuke na FPS Player ga Isekai e Ochita Baai", - "value": "746" - }, - { - "label": "Как приручить дракона / How to Train Your Dragon", - "value": "687" - }, - { - "label": "Капитан Америка / Captain America", - "value": "1425" - }, - { - "label": "Капитан Марвел(Фильм, 2019) / Captain Marvel", - "value": "1594" - }, - { - "label": "Каратель / The Punisher", - "value": "387" - }, - { - "label": "Касл / Castle", - "value": "389" - }, - { - "label": "Касльвания / Castlevania", - "value": "1215" - }, - { - "label": "Катаклизм: Тёмные дни впереди / DDA / Cataclysm: Dark Days Ahead", - "value": "680" - }, - { - "label": "Квайзер со Стигматом / Адепт Святого Знака / The Qwaser of Stigmata", - "value": "72" - }, - { - "label": "Квартет из альтернативного мира / Isekai Quartet", - "value": "1801" - }, - { - "label": "Квест Девушки-монстра / Monster Girl Questt", - "value": "928" - }, - { - "label": "Квест титана(Games) / Титанический квест / Titan Quest", - "value": "1483" - }, - { - "label": "Кенши(Games) / Kenshi", - "value": "1230" - }, - { - "label": "Киберпанк 2077 / Cyberpunk 2077", - "value": "416" - }, - { - "label": "Ким Пять-с-плюсом / Kim Possible", - "value": "436" - }, - { - "label": "Киру ра Киру / Круши Кромсай / Убей или умри / Kill la Kill", - "value": "763" - }, - { - "label": "Класс убийц / Assassination classroom", - "value": "610" - }, - { - "label": "Клеймор / Claymore", - "value": "110" - }, - { - "label": "Клинок зла / Evil Blade / Übel Blatt", - "value": "722" - }, - { - "label": "Клинок королевы / Queen’s Blade", - "value": "757" - }, - { - "label": "Клинок Маню: Тайна сисечного свитка / Manyuu Hiken-chou", - "value": "501" - }, - { - "label": "Клинок рассекающий демонов / Demon Slayer: Kimetsu no Yaiba", - "value": "21" - }, - { - "label": "Клуб Винкс / Winx Club", - "value": "397" - }, - { - "label": "Книга джунглей / The Jungle Book", - "value": "1688" - }, - { - "label": "Князь тьмы с задней парты / Demon King Daimao / Ichiban Ushiro no Daimaou", - "value": "1207" - }, - { - "label": "Код Гиас / Code Geass", - "value": "340" - }, - { - "label": "Код Квалидеи / Qualidea Code", - "value": "76" - }, - { - "label": "Кольцо Элдена / Elden Ring", - "value": "1408" - }, - { - "label": "Комната / The Room", - "value": "889" - }, - { - "label": "Конь и клинок: Боевой отряд(Games) / Mount and Blade:Warband", - "value": "1477" - }, - { - "label": "Королевства Сердец / Kingdom Hearts", - "value": "407" - }, - { - "label": "Короли крестоносцев / Crusader kings", - "value": "572" - }, - { - "label": "Король бойцов / The King of Fighters", - "value": "1378" - }, - { - "label": "Король лев / The Lion king", - "value": "1705" - }, - { - "label": "Король Шаманов / Shaman King", - "value": "744" - }, - { - "label": "Корона греха / Guilty Crown", - "value": "1007" - }, - { - "label": "Корпорация лоботомии / Lobotomy corporation", - "value": "852" - }, - { - "label": "Космические рейнджеры(Games) / Space Rangers", - "value": "1508" - }, - { - "label": "Кошечка из Сакурасо / Sakurasou no Pet na Kanojo", - "value": "605" - }, - { - "label": "Красавица и чудовище / Beauty and the Beast", - "value": "1765" - }, - { - "label": "Красная угроза 3 / Command & Conquer: Red Alert 3", - "value": "742" - }, - { - "label": "Красный, Белый, Черный, Желтый / RWBY", - "value": "131" - }, - { - "label": "Кредо убийцы / Assassin's Creed", - "value": "690" - }, - { - "label": "Кризис / Crysis", - "value": "1734" - }, - { - "label": "Крушитель / The Breaker", - "value": "1080" - }, - { - "label": "Кунг-фу панда / Kung Fu Panda", - "value": "831" - }, - { - "label": "Кэйон! / K-On!", - "value": "1785" - }, - { - "label": "Кэнган Асура / Kengan Asura", - "value": "726" - }, - { - "label": "Лаборатория Декстера / Dexter Lab", - "value": "639" - }, - { - "label": "Лавкрафт / Говард Филлипс Лавкрафт / Howard Phillips Lovecraft", - "value": "1259" - }, - { - "label": "Легенда о восьми псах востока / Hakkenden: Touhou Hakken Ibun", - "value": "1699" - }, - { - "label": "Легенда о Зельде / The Legend of Zelda", - "value": "870" - }, - { - "label": "Легенда о Короле Драконов / Legend of the Dragon King", - "value": "623" - }, - { - "label": "Легенда о Легендарных Героях / Densetsu no Yuusha no Densetsu", - "value": "193" - }, - { - "label": "Легион Супергероев / The Legion of Super-Heroes", - "value": "450" - }, - { - "label": "Леди Баг и Супер-Кот / Miraculous Ladybug", - "value": "327" - }, - { - "label": "Летняя сага / Summertime Saga", - "value": "1441" - }, - { - "label": "Лига Легенд / League of Legends", - "value": "65" - }, - { - "label": "Линия фронта для девочек / Girls' Frontline", - "value": "1686" - }, - { - "label": "Литературный клуб Доки Доки / Литературный клуб / Doki Doki literature club!", - "value": "819" - }, - { - "label": "Лорд героев(Games) / Lord of Heroes", - "value": "1771" - }, - { - "label": "Лорд человечества / Lord of the People", - "value": "1896" - }, - { - "label": "Лориенская Сага / Lorien Legacies", - "value": "521" - }, - { - "label": "Любимая жена господина генерального директора / Mr.CEO's Beloved Wife", - "value": "1389" - }, - { - "label": "Любовные неприятности / To love ru", - "value": "353" - }, - { - "label": "Любовь, Деньги, Рок-н-Ролл / Love, Money, Rock'n'Roll", - "value": "1890" - }, - { - "label": "Люди в чёрном(Фильм) / Men in Black", - "value": "1193" - }, - { - "label": "Люди Икс / X-Men", - "value": "371" - }, - { - "label": "Лютер Строуд Сага / The Luther Strode Saga", - "value": "1700" - }, - { - "label": "Люцифер(телесериал) / Lucifer", - "value": "681" - }, - { - "label": "Маг на полную ставку / Quanzhi Fashi", - "value": "291" - }, - { - "label": "Маг смерти не желающий четвертой реинкарнации / The Death Mage Who Doesn’t Want a Fourth Time", - "value": "1775" - }, - { - "label": "Маг-целитель: Новый старт / Kaifuku Jutsushi no Yarinaoshi", - "value": "1311" - }, - { - "label": "Маги: Волшебный лабиринт / Magi: The Labyrinth of Magic", - "value": "1581" - }, - { - "label": "Магистр дьявольского культа / The Grandmaster of Demonic Cultivation", - "value": "608" - }, - { - "label": "Магическая академия Атараксия: Гибрид х Сердце / Hybrid x Heart Magias Academy Ataraxia", - "value": "1898" - }, - { - "label": "Магическая битва / Magic Battle / Jujutsu Kaisen", - "value": "671" - }, - { - "label": "Маленькие кошмары 2 / Little Nightmares 2", - "value": "601" - }, - { - "label": "Малефисента / Maleficent", - "value": "775" - }, - { - "label": "Мальчик с оленьими рогами / Сладкоежка / Sweet tooth", - "value": "1772" - }, - { - "label": "Маска / The mask", - "value": "847" - }, - { - "label": "Мастер Урадана / The Master of Uradan", - "value": "1395" - }, - { - "label": "Мастера меча онлайн / Sword Art Online / SAO", - "value": "324" - }, - { - "label": "Межвидовые Рецензенты / Interspecies Reviewers", - "value": "1555" - }, - { - "label": "Менеджер среднего звена Тонэгава / Chuukan Kanriroku Tonegawa", - "value": "1084" - }, - { - "label": "Мерлин / Merlin", - "value": "486" - }, - { - "label": "Мертвы к Рассвету / Dead by Daylight", - "value": "899" - }, - { - "label": "Мертвый или живой / Dead or Alive", - "value": "1563" - }, - { - "label": "Мертвый остров / Dead Island", - "value": "124" - }, - { - "label": "Месть Масамуне-куна! / Masamune-kun no Revenge", - "value": "571" - }, - { - "label": "Метавселенная Рудазова / Rudazov's Metauniverse", - "value": "1211" - }, - { - "label": "Метро 2033(Games) / Metro 2033", - "value": "1584" - }, - { - "label": "Милый во Франксе / Любимый во Франксе / Darling in the Franxx", - "value": "942" - }, - { - "label": "Мир боевых искусств / 武极天下 / Wuji Tianxia / Martial World", - "value": "620" - }, - { - "label": "Мир зомби / Zombie World", - "value": "1880" - }, - { - "label": "Мир Льда и Пламени / The World of Ice & Fire", - "value": "415" - }, - { - "label": "Мир приключений Джеки Чана(мультсериал, 2000) / ackie Chan Adventures", - "value": "1544" - }, - { - "label": "Мир танков / WoT Blitz / World of Tanks Blitz", - "value": "525" - }, - { - "label": "Мир Тьмы / World of Darkness", - "value": "145" - }, - { - "label": "Мир Эрастай / The World of Erasthay", - "value": "1836" - }, - { - "label": "Мир Warcraft / World of Warcraft", - "value": "89" - }, - { - "label": "Мировая война Z / Война миров Z / World War Z", - "value": "1217" - }, - { - "label": "Моана / Moana", - "value": "686" - }, - { - "label": "Моб психо 100 / Mob Psycho 100", - "value": "866" - }, - { - "label": "Мобильные легенды: Бах-Бах(Games) / Mobile Legends: Bang Bang", - "value": "1497" - }, - { - "label": "Могучие рейнджеры / Power Rangers", - "value": "1486" - }, - { - "label": "Может, я встречу тебя в подземелье? / DanMachi", - "value": "9" - }, - { - "label": "Мой жених сбежал / My Groom Ran Away", - "value": "1047" - }, - { - "label": "Мой маленький пони / My Little Pony", - "value": "655" - }, - { - "label": "Мой маленький пони: Дружба — это чудо / My Little Pony: Friendship is Magic", - "value": "658" - }, - { - "label": "Мой шумный дом(мультсериал, 2016) / The Loud House", - "value": "1467" - }, - { - "label": "Монстер Хай / Monster High", - "value": "1012" - }, - { - "label": "Моя возлюбленная чпокается со всеми / Kanojo wa Dare to demo Sex Sur", - "value": "1274" - }, - { - "label": "Моя геройская академия / Boku no Hero Academia", - "value": "69" - }, - { - "label": "Моя девушка - зомби / My Girlfriend is a Zombie", - "value": "754" - }, - { - "label": "Моя жена - красивый генеральный директор / My Wife is a Beautiful CEO", - "value": "1025" - }, - { - "label": "Моя жена — президент студенческого совета! / My Wife is the Student Council President / Okusama ga Seitokaichou", - "value": "241" - }, - { - "label": "Моя Марвел Академия / My marvel academia", - "value": "696" - }, - { - "label": "Моя первая модница / Hajimete no Gal", - "value": "1835" - }, - { - "label": "Моя Супер-Бывшая / My Super Ex-Girlfriend", - "value": "1828" - }, - { - "label": "Мрачный рассвет / Grim Dawn", - "value": "1113" - }, - { - "label": "Мстители / The Avengers", - "value": "1747" - }, - { - "label": "Мстители. Эра Альтрона / The Avengers. Age of Ultron", - "value": "784" - }, - { - "label": "Мулан / Mulan", - "value": "706" - }, - { - "label": "Мы не можем учится / Bokutachi wa Benkyou ga Dekinai", - "value": "912" - }, - { - "label": "Мэй Гунцин / Mei Gongqing", - "value": "753" - }, - { - "label": "Наблюдать / Overwatch", - "value": "607" - }, - { - "label": "Надпись / Inscription", - "value": "1718" - }, - { - "label": "Нам Ён / Nam Yeon", - "value": "1188" - }, - { - "label": "Наруто / Naruto", - "value": "3" - }, - { - "label": "Начало после конца / The Beginning After The End", - "value": "888" - }, - { - "label": "Не голодай / Don't Starve", - "value": "274" - }, - { - "label": "Не издевайся надо мной, Нагаторо / Ijiranaide / Nagatoro-san Don't Toy with Me, Miss Nagatoro", - "value": "1041" - }, - { - "label": "Не люблю боль, так что вкачаю все в защиту / Itai no wa Iya nano de Bougyoryoku ni Kyokufuri Shitai to Omoimasu", - "value": "517" - }, - { - "label": "Не моя вина, что я непопулярна! / Watashi ga Motenai no wa Dou Kangaetemo Omaera ga Warui", - "value": "1381" - }, - { - "label": "Небесный замок Лапута / Tenkuu no Shiro Laputa", - "value": "1109" - }, - { - "label": "Невероятные приключения ДжоДжо / JoJo's Bizarre Adventure", - "value": "20" - }, - { - "label": "Негодник, которому не снилась девочка-зайка / Rascal Does Not Dream of Bunny Girl Senpai", - "value": "1897" - }, - { - "label": "Негодяй спасает мужскую роль / The Villain Saves the Male Lead", - "value": "1224" - }, - { - "label": "Неизвестен / Persona", - "value": "205" - }, - { - "label": "Некий магический индекс / To Aru Majutsu no Index", - "value": "562" - }, - { - "label": "Некий научный акселератор / Toaru Kagaku no Accelerator", - "value": "1487" - }, - { - "label": "Ненасытный Берсерк / Boushoku no Berserk: Ore dake Level to Iu Gainen wo Toppa suru the Comic", - "value": "1195" - }, - { - "label": "Необъятные небеса / Infinite Stratos / IS", - "value": "280" - }, - { - "label": "Необъятный океан / Grand Blue", - "value": "531" - }, - { - "label": "Непревзойденная / Master Piece The Animation", - "value": "712" - }, - { - "label": "Непризнанный школой владыка демонов / Maou Gakuin no Futekigousha", - "value": "1476" - }, - { - "label": "Непутевый ученик в школе магии / Mahouka Koukou No Rettousei", - "value": "982" - }, - { - "label": "Непутевый ученик в школе магии / The Irregular at Magic High School", - "value": "630" - }, - { - "label": "Несокрушимая механическая кукла / Machine-Doll wa Kizutsukanai", - "value": "1030" - }, - { - "label": "Несправедливость / Injustice", - "value": "1026" - }, - { - "label": "Нет игры - нет жизни / Без игры жизни нет / No Game No Life", - "value": "718" - }, - { - "label": "Неуязвимый / Invincible", - "value": "702" - }, - { - "label": "НиоХ(Games) / NioH", - "value": "1465" - }, - { - "label": "Новый завет Владыки тьмы / Shinmai Maou no Testament", - "value": "1432" - }, - { - "label": "Ну и ну! Земляничные яйца / I My Me! Strawberry Eggs", - "value": "1485" - }, - { - "label": "Нулевой Уровень Целомудрия / Teisou Kannen Zero", - "value": "1209" - }, - { - "label": "О моём перерождении в меч / Tensei Shitara Ken deshita", - "value": "53" - }, - { - "label": "О моём перерождении в слизь / Tensei shitara Slime Datta Ken", - "value": "64" - }, - { - "label": "О моя Богиня / Aa! Megami-sama! / Ah! My Goddess", - "value": "915" - }, - { - "label": "Обесчещенный(Games) / Dishonored", - "value": "1073" - }, - { - "label": "Обитель зла / Resident Evil", - "value": "86" - }, - { - "label": "Огненная эмблема / Fire Emblem", - "value": "1615" - }, - { - "label": "Огненная эмблема: Пробуждение / Fire Emblem: Awakening", - "value": "1616" - }, - { - "label": "Огненная эмблема: Три Дома / Fire Emblem:Three Houses", - "value": "1716" - }, - { - "label": "Одинокий рокер! / Bocchi the Rock!", - "value": "1904" - }, - { - "label": "Одному лишь Богу ведомый мир / World God Only Knows", - "value": "1248" - }, - { - "label": "Она становится гламурной после расторжения помолвки / She gets glamorous after the engagement is annulled", - "value": "1404" - }, - { - "label": "Орк-рубака / Orc Grunt", - "value": "779" - }, - { - "label": "Освободите эту ведьму / Release that witch", - "value": "994" - }, - { - "label": "Острые козырьки(телесериал) / Peaky Blinders", - "value": "1177" - }, - { - "label": "От заката до рассвета! / From Dusk till Dawn!", - "value": "1416" - }, - { - "label": "Отброс из семьи графа / Trash of counts family", - "value": "853" - }, - { - "label": "Отряд самоубийц / The Suicide Squad", - "value": "1844" - }, - { - "label": "Отчаянные домохозяйки / Desperate Housewives", - "value": "1011" - }, - { - "label": "Отчет о буйстве духов / YuYu Hakusho", - "value": "1008" - }, - { - "label": "Охота демонического короля на свою жену / Xie Wang Zhui Qi", - "value": "1737" - }, - { - "label": "Охотник х Охотник / Hunter x Hunter", - "value": "101" - }, - { - "label": "Охотницы на демонов / Taimanin Asagi", - "value": "1463" - }, - { - "label": "Очень приятно Бог! / Kamisama Hajimemashita", - "value": "1585" - }, - { - "label": "Очень Странные Дела(телесериал) / Stranger Things", - "value": "1834" - }, - { - "label": "ПАЗЛ / PUZZLE", - "value": "1762" - }, - { - "label": "Палач Рока / DOOM", - "value": "132" - }, - { - "label": "Параграф 78(Фильм) / Paragraph 78", - "value": "923" - }, - { - "label": "Паразит: Учение о жизни / Parasyte: The Maxim", - "value": "1176" - }, - { - "label": "Пастырь(Фильм, 2011) / Priest", - "value": "1173" - }, - { - "label": "Пацаны / The Boys", - "value": "133" - }, - { - "label": "Первый детский сад во вселенной / The First Kindergarten in the Universe", - "value": "1049" - }, - { - "label": "Перевозчик / Le Transporteur", - "value": "365" - }, - { - "label": "Передающийся через кровь / Bloodborne", - "value": "229" - }, - { - "label": "Пережить / Outlast", - "value": "645" - }, - { - "label": "Перерождение / Rebirth", - "value": "550" - }, - { - "label": "Перерождение бессмертного горожанина-культиватора / Rebirth – City Cultivation / Rebirth of the Urban Immortal Cultivator", - "value": "843" - }, - { - "label": "Перерождение в монстра / Re:Monster", - "value": "85" - }, - { - "label": "Перестрой мир / Sekai O Sai Kochiku / Rebuild World", - "value": "961" - }, - { - "label": "Период полураспада(Valve) / Half-Life", - "value": "895" - }, - { - "label": "Перси Джексон / Percy Jackson", - "value": "308" - }, - { - "label": "Персона 5 / Persona 5", - "value": "1614" - }, - { - "label": "Печать ветра / Kaze no Stigma", - "value": "845" - }, - { - "label": "Пик боевых искусств / Martial Peak", - "value": "414" - }, - { - "label": "Пираты Карибского моря / Pirates of the Caribbean", - "value": "932" - }, - { - "label": "Пираты черной лагуны / Black Lagoon", - "value": "621" - }, - { - "label": "Пламенная бригада пожарных / Fire Force / Enen no Shouboutai", - "value": "841" - }, - { - "label": "Пламя бесчисленых невзгод / I' m really not demon god's lackey", - "value": "1452" - }, - { - "label": "Планетарная аннигиляция / Planetary Annihilation", - "value": "487" - }, - { - "label": "Плоскостной пейзаж: Мучение / Planescape: Torment", - "value": "1768" - }, - { - "label": "По велению адской сестры / The Testament of Sister New Devil", - "value": "18" - }, - { - "label": "Поборники тьмы / Darksiders", - "value": "1028" - }, - { - "label": "Повар небесной гостиницы / Чем кормят в ином мире / Kakuriyo no Yadomeshi", - "value": "998" - }, - { - "label": "Повар-боец Сома / В поисках божественного рецепта / Shokugeki no Souma", - "value": "191" - }, - { - "label": "Повелитель тьмы на подработке! / Hataraku Maou-sama!", - "value": "674" - }, - { - "label": "Повелитель тьмы: Другая история мира / How Not to Summon a Demon Lord / Isekai Maou to Shoukan Shoujo no Dorei Majutsu", - "value": "699" - }, - { - "label": "Повелитель(Куганэ Маруяма) / Overlord", - "value": "27" - }, - { - "label": "Повелитель(Games) / Overlord", - "value": "1623" - }, - { - "label": "Повесть о Конце Света / Record of Ragnarok", - "value": "332" - }, - { - "label": "Повесть о лунной принцессе / Tsukihime: Lunar Legend", - "value": "750" - }, - { - "label": "Повесть о Небесных островах / Фэнтези Гранблю / Granblue Fantasy", - "value": "808" - }, - { - "label": "Повседневная жизнь бессмертного короля / The Daily Life of the Immortal King / Xian Wang de Richang Shenghuo", - "value": "1466" - }, - { - "label": "Повседневная жизнь с девушкой-монстром / Monster Musume", - "value": "760" - }, - { - "label": "Пограничье(Games) / Borderlands", - "value": "992" - }, - { - "label": "Под лунами Драконьих глаз / Beneath the Dragoneye Moons", - "value": "1735" - }, - { - "label": "Подземелья и драконы / Dungeons & Dragons", - "value": "81" - }, - { - "label": "Подземная история / Андертейл / Undertale", - "value": "390" - }, - { - "label": "Поднявшийся(Games) / Risen", - "value": "1273" - }, - { - "label": "Поднятие уровня в одиночку / Solo Leveling", - "value": "127" - }, - { - "label": "Подручный Луизы-Нулизы / Zero no Tsukaima", - "value": "580" - }, - { - "label": "Пожиратель богов / God Eater", - "value": "1321" - }, - { - "label": "Поймай себя ! Моя дорогая жена / Catch You ! My Dear Wife", - "value": "1317" - }, - { - "label": "Покемон / Pokemon", - "value": "43" - }, - { - "label": "Политическая Хроника Молодой Девушки / A Young Woman's Political Record", - "value": "1306" - }, - { - "label": "Полностью пленённые / Totally Captivated", - "value": "1086" - }, - { - "label": "Полый Рыцарь(Games) / Hollow Knight", - "value": "1198" - }, - { - "label": "Пользователи Силы / Forceusers", - "value": "1162" - }, - { - "label": "Поля битвы Неизвестного игрока / ПАБГ / Player Unknown's Battlegrounds / PUBG", - "value": "622" - }, - { - "label": "Попытка приручить злого повелителя / Trying to Tame an Evil Overlord", - "value": "983" - }, - { - "label": "Поработитель Ада / Helltaker", - "value": "776" - }, - { - "label": "Порновселенная / Porn Universe", - "value": "1776" - }, - { - "label": "Портал(Valve) / Portal", - "value": "800" - }, - { - "label": "Последние из нас / Last Of Us", - "value": "1717" - }, - { - "label": "Последний Серафим / Owari no Seraph", - "value": "551" - }, - { - "label": "Последняя из рода Блау(Тайга Ри) / The last of the Blau family", - "value": "1507" - }, - { - "label": "Последняя фантазия / ファイナルファンタジ / Final Fantasy", - "value": "769" - }, - { - "label": "Преподобное безумие / Reverend Insanity", - "value": "1280" - }, - { - "label": "Преподобный Гу / Gu Zhen Ren / Daoist Gu", - "value": "1464" - }, - { - "label": "Призрачный бегун / Ghostrunner", - "value": "613" - }, - { - "label": "Призрачный гонщик / Ghost Rider", - "value": "823" - }, - { - "label": "Принц Драконов Хаоса / The Chaos Dragon Prince", - "value": "1397" - }, - { - "label": "Принц Персии / Prince of Persia", - "value": "1535" - }, - { - "label": "Принцесса монстров / Princess Resurrection", - "value": "1304" - }, - { - "label": "Принцесса Цу / Не проиграю! / Maken Ki", - "value": "675" - }, - { - "label": "Проект „Восток“ / Touhou Project", - "value": "809" - }, - { - "label": "Проект Кей / K Project", - "value": "73" - }, - { - "label": "Проклятие: Автоматизация / NieR:Automata", - "value": "1496" - }, - { - "label": "Противостояние святого / Renegade Immortal", - "value": "926" - }, - { - "label": "Прототип / Prototype", - "value": "54" - }, - { - "label": "Пуленепробиваемый / Bang-Tan / BTS", - "value": "520" - }, - { - "label": "Путешествие на Запад / Journey to the West", - "value": "1833" - }, - { - "label": "Пять невест / Go-Toubun no Hanayome", - "value": "713" - }, - { - "label": "Пять ночей у Фредди / Five nights at freddy's", - "value": "930" - }, - { - "label": "Рагнарёк Онлайн / Ragnarok Online", - "value": "953" - }, - { - "label": "Радуга 6: Осада / Rainbow Six: Siege", - "value": "421" - }, - { - "label": "Развращение Дочери / Daraku Reijou Hakoiri Ojou-sama Netorare Choukyou Kiroku", - "value": "1284" - }, - { - "label": "Рай Грисайи / Эдем в серых тонах / Grisaia no Rakuen", - "value": "584" - }, - { - "label": "Рандеву с жизнью / Date A live", - "value": "851" - }, - { - "label": "Ранма ½ / Ranma ½", - "value": "1192" - }, - { - "label": "Рапунцель: Запутанная история / Tangled", - "value": "773" - }, - { - "label": "Расколотая битвой синева небес / Battle Through the Heavens", - "value": "927" - }, - { - "label": "Рассказ служанки / The Handmaid's Tale", - "value": "1135" - }, - { - "label": "Расхитительница гробниц / Tomb Raider", - "value": "988" - }, - { - "label": "Резатель / Лангриссер / Langrisser", - "value": "792" - }, - { - "label": "Реинкарнация безработного / Mushoku Tensei", - "value": "569" - }, - { - "label": "Реинкарнация Богини / Megami Tensei", - "value": "1161" - }, - { - "label": "Репликант НиеР / NieR Replicant / NieR Gestalt", - "value": "1299" - }, - { - "label": "Рецеттия: Повесть о магазине предметов / Recettear: An Item Shop's Tale", - "value": "858" - }, - { - "label": "Ривердэйл / Riverdale", - "value": "637" - }, - { - "label": "Рик и Морти / Rick and Morty", - "value": "315" - }, - { - "label": "Розарий и Вампир / Rosario+Vampire", - "value": "83" - }, - { - "label": "Розовая пора моей школьной жизни сплошной обман / Yahari Ore no Seishun Love Come wa Machigatteiru", - "value": "856" - }, - { - "label": "Рок шоу! / Show By Rock!!", - "value": "344" - }, - { - "label": "Русалочка / The Little Mermaid", - "value": "892" - }, - { - "label": "Рыцарь и маг / Knight's & Magic", - "value": "1491" - }, - { - "label": "Сага о Винланде / Vinland Saga", - "value": "1200" - }, - { - "label": "Садистская смесь / Blend S", - "value": "1120" - }, - { - "label": "Сайт волшебниц / Mahou Shoujo Site", - "value": "909" - }, - { - "label": "Сверхъестественное(телесериал) / Supernatural", - "value": "916" - }, - { - "label": "Связь принцесс: повторное погружение / Princess Connect! Re:Dive", - "value": "1481" - }, - { - "label": "Святые / Saints Row", - "value": "1390" - }, - { - "label": "Сейлор Мун / Sailor Moon", - "value": "114" - }, - { - "label": "Секире: Тени Умирают Дважды / Sekiro: Shadows Die Twice", - "value": "1076" - }, - { - "label": "Семь смертных грехов / Nanatsu no Taizai", - "value": "61" - }, - { - "label": "Семья шпиона / Spy x Family", - "value": "1646" - }, - { - "label": "Сердца Пандоры / Pandora Hearts", - "value": "497" - }, - { - "label": "Серия Метроидов / Metroid Series", - "value": "1612" - }, - { - "label": "Серый человек / Ди: Гурэйман / D.Gray-man", - "value": "367" - }, - { - "label": "Си Тянь Гуань / Si Tian Guan", - "value": "1189" - }, - { - "label": "Сильнейший в истории ученик Кэнити / Shijou Saikyou no Deshi Kenichi", - "value": "242" - }, - { - "label": "Сильнейший в истории ученик Кэнъити / KenIchi: The Mightiest Disciple", - "value": "745" - }, - { - "label": "Сильнейший магнат / The Strongest Tycoon", - "value": "1340" - }, - { - "label": "Сильнейший мудрец низшей эмблемы / Shikkakumon no Saikyou Kenja", - "value": "1472" - }, - { - "label": "Симпсоны / The Simpsons", - "value": "1461" - }, - { - "label": "Симс / The Sims", - "value": "654" - }, - { - "label": "Симфония морской стали / Aoki Hagane no Arpeggio", - "value": "958" - }, - { - "label": "Сингулярность(Games) / Singularity", - "value": "1793" - }, - { - "label": "Синий Архив / Blue Archive", - "value": "1411" - }, - { - "label": "Синий экзорцист / Blue Exorcist", - "value": "312" - }, - { - "label": "Синяя Тюрьма: Блю Лок / Blue Lock", - "value": "1792" - }, - { - "label": "Система Богов и Демонов / God and Devil World", - "value": "1648" - }, - { - "label": "Система Спаси-Себя-Сам / The Scum Villain's Self-Saving System: Ren Zha Fanpai Zijiu Xitong", - "value": "1505" - }, - { - "label": "Система: Восьмой уровень(Д. Серебряков) / System: Eighth level", - "value": "1175" - }, - { - "label": "Сисястая Принцесса под гипнозом / Kyonyuu Princess Saimin", - "value": "1618" - }, - { - "label": "Сказание о Демонах и Богах / Tales of Demons and Gods", - "value": "59" - }, - { - "label": "Сказание о Тёмном Рыцаре ~ Призван, чтобы одолеть Героя ~ / Tale of Dark Knight~Summoned to Defeat The Hero~", - "value": "1647" - }, - { - "label": "Сказки хранителей(Games) / Guardian tales", - "value": "1068" - }, - { - "label": "Скрытая Похотливая Натура Моих Русских Сестренок и Мачехи / Muttsuri do Sukebe ro Gibo Shimai", - "value": "1282" - }, - { - "label": "Скуби-Ду / Scooby-Doo", - "value": "638" - }, - { - "label": "Скучный мир, где не существует самой идеи похабных шуток / Shimoneta to Iu Gainen ga Sonzai Shinai Taikutsu na Sekai", - "value": "830" - }, - { - "label": "Сладкая жизнь / Happy Sugar Life", - "value": "1099" - }, - { - "label": "Сладкий флирт / Amour Sucré / Sweet Crush", - "value": "495" - }, - { - "label": "Сладости и Сигареты / Candy & Cigarettes", - "value": "778" - }, - { - "label": "Следопыт Гнев Праведников / Pathfinder Wrath Of The Righteous", - "value": "1077" - }, - { - "label": "Следопыт: Творец королей / Pathfinder: Kingmaker", - "value": "1770" - }, - { - "label": "Смертельная битва / Мортал Комбат / Mortal Kombat", - "value": "806" - }, - { - "label": "Смертельный укус", - "value": "1902" - }, - { - "label": "Созданный в бездне / Made in Abyss", - "value": "952" - }, - { - "label": "Сок джунглей", - "value": "1901" - }, - { - "label": "Сокрушитель: Новые волны / The Breaker: New Waves", - "value": "1500" - }, - { - "label": "Соник еж / Sonic the hedgehog", - "value": "1052" - }, - { - "label": "Сорвиголова / Daredevil", - "value": "1690" - }, - { - "label": "Сотня / Hundred", - "value": "885" - }, - { - "label": "Спаун / Spawn", - "value": "1254" - }, - { - "label": "Спецагент Арчер / Archer", - "value": "624" - }, - { - "label": "Специалист по апгрейду из другого мира / Endless Sea of Clouds ESC", - "value": "1499" - }, - { - "label": "Спираль / Удзумаки / Uzumaki", - "value": "1164" - }, - { - "label": "СТАЛКЕР / STALKER / S.T.A.L.K.E.R", - "value": "677" - }, - { - "label": "Стальная тревога / Full Metal Panic! The Second Raid", - "value": "1489" - }, - { - "label": "Стальной алхимик / Fullmetal Alchemist", - "value": "1123" - }, - { - "label": "Стальной Гигант / The Iron Giant", - "value": "1241" - }, - { - "label": "Становление богом / Bai Lian Cheng Shen", - "value": "1315" - }, - { - "label": "Старгерл / Stargirl", - "value": "1137" - }, - { - "label": "Стелларис / Stellaris", - "value": "1098" - }, - { - "label": "Сторожевые Псы / Watch Dogs", - "value": "1886" - }, - { - "label": "Стражи Галактики / Guardians of the Galaxy", - "value": "1426" - }, - { - "label": "Страна Самоцветов / Houseki no Kuni", - "value": "1305" - }, - { - "label": "Страна чудес смертников / Зона-парк смертников / Deadman Wonderland", - "value": "857" - }, - { - "label": "Страношары / Кантриболз / Countryballs", - "value": "1895" - }, - { - "label": "Студии 20-й век / 20th Century Studios", - "value": "1715" - }, - { - "label": "Судьба / Fate", - "value": "1740" - }, - { - "label": "Судьба: Апокриф / Fate: Apocrypha", - "value": "231" - }, - { - "label": "Судьба: Великий Орден / Fate: Grand Order", - "value": "60" - }, - { - "label": "Судьба: Девочка волшебница Илия / Fate: Kaleid Liner Prisma", - "value": "789" - }, - { - "label": "Судьба: Истоки / Fate: Zero", - "value": "230" - }, - { - "label": "Судьба: Ночь схватки / Fate: Stay Night", - "value": "536" - }, - { - "label": "Сумерки / Twilight", - "value": "471" - }, - { - "label": "Супер ген бога / Super God Gene", - "value": "316" - }, - { - "label": "Супер Марио / Super Mario", - "value": "1661" - }, - { - "label": "Супергёрл(телесериал, 2015) / Supergirl", - "value": "1088" - }, - { - "label": "Супермедицинский ниндзя / Super medical ninja", - "value": "1391" - }, - { - "label": "Суперсемейка / The Incredibles", - "value": "306" - }, - { - "label": "Сэкирэй / Sekirei", - "value": "111" - }, - { - "label": "Тада не может влюбиться! / Tada-kun wa koi wo shinai!", - "value": "1905" - }, - { - "label": "Тайны Смолвиля / Smallville", - "value": "449" - }, - { - "label": "Танец клинка Элементалиста / Seireitsukai no Blade Dance", - "value": "1498" - }, - { - "label": "Твоя апрельская ложь / Your lie in april", - "value": "532" - }, - { - "label": "Те, кто охотятся на эльфов / エルフを狩るモノたち / Those Who Hunt Elves", - "value": "1168" - }, - { - "label": "Темнейшее подземелье / Darkest dungeon", - "value": "1405" - }, - { - "label": "Темные Души / Dark Souls", - "value": "200" - }, - { - "label": "Темный Ангел / Dark Angel", - "value": "1010" - }, - { - "label": "Тёмный Дворецкий / Kuroshitsuj / Dark Butler", - "value": "411" - }, - { - "label": "Темный дворецкий / Kuroshitsuji", - "value": "1043" - }, - { - "label": "Темный призыватель Апокалипсиса / The Dark Summoner of the Apocalypse", - "value": "1407" - }, - { - "label": "Тень ежа / Ёж Шэдоу / Shadow the hedgehog", - "value": "796" - }, - { - "label": "Терминатор / The Terminator", - "value": "759" - }, - { - "label": "Террарий / Terraria", - "value": "805" - }, - { - "label": "Тетрадь смерти / Death Note", - "value": "78" - }, - { - "label": "Тибериумные войны / Tiberium Wars", - "value": "1893" - }, - { - "label": "Титаник / Titanic", - "value": "1842" - }, - { - "label": "Тихий Холм / Сайлент Хилл / Silent Hill", - "value": "848" - }, - { - "label": "Тихоокеанский рубеж / Pacific Rim", - "value": "832" - }, - { - "label": "Тогайну но Чи ~Потерял кровь~(Games) / Togainu no Chi ~Lost Blood~", - "value": "1540" - }, - { - "label": "Токийские вороны / Tokyo Ravens", - "value": "836" - }, - { - "label": "Токийские мстители / Tokyo Revengers", - "value": "1064" - }, - { - "label": "Токийский Гуль / Tokyo Ghoul", - "value": "271" - }, - { - "label": "Тор / Thor", - "value": "764" - }, - { - "label": "Торико / Toriko", - "value": "342" - }, - { - "label": "Точка зрения Всеведущего читателя / Omniscient Reader’s Viewpoint", - "value": "1872" - }, - { - "label": "Трансформеры / Transformers", - "value": "117" - }, - { - "label": "Трес Наварра / Tres Navarre", - "value": "1197" - }, - { - "label": "Три Икса / xXx", - "value": "364" - }, - { - "label": "Трон: Восстание / Tron: Uprising", - "value": "1887" - }, - { - "label": "Тропико / Tropico", - "value": "694" - }, - { - "label": "Ты единственная, кто любит Великого Меня / Ore wo Suki nano wa Omae dake ka yo", - "value": "1818" - }, - { - "label": "Ты же любишь мамочку, удары которой бьют по площади двойным уроном? / Tsuujou Kougeki ga Zentai Kougeki de Ni-kai Kougeki no Okaasan wa Suki Desu ka?", - "value": "333" - }, - { - "label": "Тэнти - лишний! / Tenchi Muyo", - "value": "1316" - }, - { - "label": "У Коми-сан проблемы с общением / 古見さんは、コミュ症です / Komi Can't Communicate", - "value": "591" - }, - { - "label": "У меня мало друзей / Boku wa Tomodachi ga Sukunai", - "value": "1506" - }, - { - "label": "Убийца Акаме / Akame ga Kill", - "value": "30" - }, - { - "label": "Убийца Брайан / Carl Robert Brown", - "value": "1092" - }, - { - "label": "Убийца гоблинов / Goblin slayer", - "value": "803" - }, - { - "label": "Удар крови / Very AU strike the blood", - "value": "1255" - }, - { - "label": "Уж не зомби ли это? / Kore wa Zombie Desu ka?", - "value": "725" - }, - { - "label": "Уличный боец(Games) / Суторито Фаита / Street Fighter", - "value": "1203" - }, - { - "label": "Ультрафиолет / Ultraviolet", - "value": "1831" - }, - { - "label": "Усио и Тора / Ushio and Tora", - "value": "1501" - }, - { - "label": "Утраченное небесами / Sora no Otoshimoto / Lost Property of the Sky", - "value": "627" - }, - { - "label": "Ученик Мудреца / Kenja no Deshi wo Nanoru Kenja", - "value": "1474" - }, - { - "label": "Ученик чародея / The Sorcerer's Apprentice", - "value": "862" - }, - { - "label": "Ученики(Games) / Disciples", - "value": "1478" - }, - { - "label": "Учитель Хокаге / Hokage Master", - "value": "1319" - }, - { - "label": "Учитель-мафиози Реборн! / Katekyo Hitman Reborn!", - "value": "134" - }, - { - "label": "Ушастые Друзья / Kemono Friends", - "value": "578" - }, - { - "label": "Фальшивая любовь / Nisekoi", - "value": "1103" - }, - { - "label": "Фантастическая четвёрка / Fantastic Four", - "value": "625" - }, - { - "label": "Фантастические твари и где они обитают / Fantastic Beasts and Where to Find Them", - "value": "246" - }, - { - "label": "Финес и Ферб / Phineas and Ferb", - "value": "898" - }, - { - "label": "Флотская коллекция / Kantai Collection", - "value": "1194" - }, - { - "label": "Флэш / The Flash", - "value": "1136" - }, - { - "label": "Фонд SCP / SCP / SCP Foundation", - "value": "822" - }, - { - "label": "Форма голоса / A Silent Voice", - "value": "1100" - }, - { - "label": "Форсаж / The Fast and the Furious", - "value": "363" - }, - { - "label": "Фронт кровавой блокады / Кровавый круг - линия фронта / Kekkai Sensen / Blood Blockade Battlefront", - "value": "794" - }, - { - "label": "Футадом мир / Futadom world", - "value": "984" - }, - { - "label": "Халк / Hulk", - "value": "973" - }, - { - "label": "Хвост Феи / Fairy Tail", - "value": "13" - }, - { - "label": "Хеллбой / Hellboy", - "value": "1171" - }, - { - "label": "Хеллсинг: Война с нечистью / Hellsing", - "value": "116" - }, - { - "label": "Хикару и го / Hikaru no Go", - "value": "1121" - }, - { - "label": "Хищник / Predator", - "value": "747" - }, - { - "label": "Хоббит(Дж. Р. Р. Толкина) / The Hobbit(John R.R. Tolkien)", - "value": "1127" - }, - { - "label": "Ходячие мертвецы / The Walking Dead", - "value": "704" - }, - { - "label": "Холодное сердце / Frozen", - "value": "633" - }, - { - "label": "Хонкай удар / Honkai impact", - "value": "1332" - }, - { - "label": "Хранители Пандоры / The guardians of Pandora", - "value": "1187" - }, - { - "label": "Хранитель вечности / UQ Holder", - "value": "1469" - }, - { - "label": "Хроники Акаши / Rokudenashi Majutsu Koushi to Akashic Records", - "value": "1166" - }, - { - "label": "Хроники Ксенобладания / Дзэнобурэйдо / Xenoblade Chronicles", - "value": "1110" - }, - { - "label": "Хроники Миров(Е. Лукин) / Chronicles of the Worlds(E. Lukin)", - "value": "346" - }, - { - "label": "Хроники расхитителей гробниц / Даому Биджи / Grave Robbery Note / Dao Mu Bi Ji / Daomu Biji", - "value": "724" - }, - { - "label": "Хроники Ренегата / The Renegade Chronicles", - "value": "1225" - }, - { - "label": "Царь Горы / The Gog of the Highschool", - "value": "1285" - }, - { - "label": "Чародейки / W.I.T.C.H.", - "value": "118" - }, - { - "label": "Человек — бензопила / Chainsaw Man", - "value": "797" - }, - { - "label": "Человек — летучая мышь / Бэтмен / Bat-man / Batman", - "value": "440" - }, - { - "label": "Человек одного удара / Ванпанчмен / One Punch-Man", - "value": "70" - }, - { - "label": "Человек-паук / Spider-Man", - "value": "326" - }, - { - "label": "Чемпион! / Campione!", - "value": "534" - }, - { - "label": "Червь(Джон Маккрей) / Worm(John C. McCrae(Wildbow))", - "value": "700" - }, - { - "label": "Черная Пантера(Фильм, 2018) / Black Panther", - "value": "1605" - }, - { - "label": "Черновик(С.Лукьяненко) / Draft", - "value": "1023" - }, - { - "label": "Чернокнижник в Мире Магов / Варлок / Warlock", - "value": "635" - }, - { - "label": "Чёрные души / Black Souls", - "value": "1439" - }, - { - "label": "Чёрный зверь / Чёрный Пёс / Kuroinu", - "value": "755" - }, - { - "label": "Чёрный зверь: Развращение Благородных Воительниц / Black Beast: Corruption of the Noble Warriors", - "value": "1733" - }, - { - "label": "Чёрный клевер / Black Clover", - "value": "11" - }, - { - "label": "Что такое настоящий мир? / What is real peace?", - "value": "1336" - }, - { - "label": "Чудачества любви не помеха! / Chuunibyou Demo Koi ga Shitai!", - "value": "1719" - }, - { - "label": "Чужой / Чужие / Aliens", - "value": "1791" - }, - { - "label": "Чужой / Alien", - "value": "748" - }, - { - "label": "Чума инкорпорейтед / Plague Inc", - "value": "125" - }, - { - "label": "Шазам! / Shazam!", - "value": "1560" - }, - { - "label": "Шальной последний босс появился! / A Wild Last Boss Appeared!", - "value": "968" - }, - { - "label": "Шальные девчонки / Girl the Wild's", - "value": "965" - }, - { - "label": "Шан Чи и легенда десяти колец / Shang-Chi and the Legend of the Ten Rings", - "value": "1424" - }, - { - "label": "Шарлотта / Charlotte", - "value": "71" - }, - { - "label": "Шерлок (ВВС) / Sherlock", - "value": "492" - }, - { - "label": "Шестерни войны / Gears of War", - "value": "1346" - }, - { - "label": "Школа мертвецов / Highschool of the Dead", - "value": "98" - }, - { - "label": "Школа строгого режима / Prison School", - "value": "676" - }, - { - "label": "Школьные воины / Сила тысячи / Ikki Tosen", - "value": "818" - }, - { - "label": "Шрек(мультфильм) / Шрэк / Shrek", - "value": "1586" - }, - { - "label": "Шухер, у нас новый студент / Transfer Student The Storm Bringer", - "value": "628" - }, - { - "label": "Эволюционировать(Games) / Evolve", - "value": "1789" - }, - { - "label": "Эволюция. Естественный Отбор / Game Evolution", - "value": "287" - }, - { - "label": "Эльсворд: Эль-ий Йоин / Elsword", - "value": "199" - }, - { - "label": "Эльфийская песнь / Elfen Lied", - "value": "1899" - }, - { - "label": "Эпоха Драконов / Dragon Age", - "value": "253" - }, - { - "label": "Эр Ген Я запечатаю небеса / ISSTH / Er Gen I shall seal the heavens", - "value": "1170" - }, - { - "label": "Эрагон(Кристофер Паолини) / Eragon", - "value": "417" - }, - { - "label": "Эроманга-сэнсэй / Ero-manga Sensei", - "value": "1094" - }, - { - "label": "Эстетика заблудшего героя / Hagure Yuusha no Aesthetica", - "value": "1310" - }, - { - "label": "Эта гяру будет встречаться с отаку через 100 дней. / 100-nichigo ni Otaku-kun to Tsukiau Gal", - "value": "1246" - }, - { - "label": "Эта фарфоровая кукла влюбилась / Sono Bisque Doll wa Koi wo Suru My Dress-Up Darling", - "value": "1335" - }, - { - "label": "Это не Гарри Поттер / This is not Harry Potter", - "value": "1219" - }, - { - "label": "Этот герой неуязвим, но очень осторожен / This Hero Is Invincible but Too Cautious", - "value": "1276" - }, - { - "label": "Эффект массы / Mass Effect", - "value": "213" - }, - { - "label": "Эхо пули / Bullet Echo", - "value": "1523" - }, - { - "label": "Югио: Дуэльные монстры / Yu-Gi-Oh", - "value": "1814" - }, - { - "label": "Югио! Вреинс / Yu-Gi-Oh! VRAINS", - "value": "1888" - }, - { - "label": "Юна из гостиницы Юраги / Yuuna of Yuragi Manor", - "value": "493" - }, - { - "label": "Юная Лига Справедливости / Young Justice", - "value": "1020" - }, - { - "label": "Юные Титаны / Teen Titans", - "value": "420" - }, - { - "label": "Я - Четвертый / I Am Number Four", - "value": "590" - }, - { - "label": "Я Король-Волшебник / I Am The Sorcerer King", - "value": "1292" - }, - { - "label": "Я мачеха, но моя дочь слишком милая / I'm stepmother but daughter is too cute", - "value": "777" - }, - { - "label": "Я не родился счастливчиком / I Wasn’t Born Lucky", - "value": "996" - }, - { - "label": "Я получил читерские способности в другом мире и стал экстраординарным в реальном мире / I Got a Cheat Skill in Another World and Became Unrivaled in The Real World, Too", - "value": "1900" - }, - { - "label": "Я стала потерянной дочерью злодея / I Became the Villain’s Lost Daughter", - "value": "1387" - }, - { - "label": "Ядерный трон / Nuclear Throne", - "value": "1456" - }, - { - "label": "Ярость [Пересмотрено] / Rage [Revised]", - "value": "1337" - }, - { - "label": "Ящик предложений Мэдаки / Medaka box", - "value": "874" - }, - { - "label": "Cказка для Дьявола / Tale For Satan", - "value": "1271" - }, - { - "label": "D&D стиль / D&D style", - "value": "1289" - }, - { - "label": "Dying Light 2: Stay Human", - "value": "1906" - }, - { - "label": "Fallout: Нью-Вегас / Fallout: New Vegas", - "value": "1249" - }, - { - "label": "Re: Жизнь в альтернативном мире с нуля / Re: Zero, Starting Life in Another World", - "value": "57" - }, - { - "label": "Re:Zero Начало жизни в другом мире / Re:Zero Starting Life in Another World", - "value": "1531" - }, - { - "label": "Rimworld", - "value": "1894" - }, - { - "label": "The Second Coming of Gluttony / The Second Coming of Avarice", - "value": "1236" - }, - { - "label": "Vfhdbk", - "value": "1884" - }, - { - "label": "XCOM: Враг внутри / XCOM: Enemy Unknown", - "value": "476" - }, - { - "label": "Xenus: Точка кипения / Boiling point: Road To Hell / Xenus: Boiling Point", - "value": "695" - } - ], - "inputType": "Checkbox" - }, - { - "key": "atmosphere", - "label": "Атмосфера:", - "values": [ - { - "label": "Неважно", - "value": "0" - }, - { - "label": "Позитивная", - "value": "1" - }, - { - "label": "Dark", - "value": "2" - } - ], - "inputType": "Picker" - }, - { - "key": "adult", - "label": "Возрастные ограничения:", - "values": [ - { - "label": "Все", - "value": "0" - }, - { - "label": "Только 18+", - "value": "2" - }, - { - "label": "Убрать 18+", - "value": "1" - } - ], - "inputType": "Picker" - } - ] - }, - { - "id": "erolate", - "sourceSite": "https://erolate.com", - "sourceName": "Erolate", - "filters": [ - { - "key": "cat", - "label": "Из раздела каталога:", - "values": [ - { - "label": "Неважно", - "value": "0" - }, - { - "label": "Авторские", - "value": "12" - }, - { - "label": "Авторские", - "value": "35" - }, - { - "label": "Английские", - "value": "34" - }, - { - "label": "Игры 18+", - "value": "3" - }, - { - "label": "Китайские", - "value": "31" - }, - { - "label": "Комиксы", - "value": "29" - }, - { - "label": "Корейские", - "value": "33" - }, - { - "label": "Манга для взрослых", - "value": "30" - }, - { - "label": "Машинный перевод", - "value": "38" - }, - { - "label": "Переводы", - "value": "15" - }, - { - "label": "Фанфики", - "value": "16" - }, - { - "label": "Эротические рассказы", - "value": "2" - } - ], - "inputType": "Picker" - }, - { - "key": "s_lang", - "label": "Язык оригинала:", - "values": [ - { - "label": "Неважно", - "value": "0" - }, - { - "label": "Абхазский", - "value": "20" - }, - { - "label": "Аварский", - "value": "21" - }, - { - "label": "Азербайджанский", - "value": "22" - }, - { - "label": "Аймара", - "value": "23" - }, - { - "label": "Акан", - "value": "24" - }, - { - "label": "Албанский", - "value": "25" - }, - { - "label": "Амхарский", - "value": "26" - }, - { - "label": "Английский", - "value": "2" - }, - { - "label": "Арабский", - "value": "27" - }, - { - "label": "Арагонский", - "value": "28" - }, - { - "label": "Арберешский", - "value": "29" - }, - { - "label": "Армянский", - "value": "30" - }, - { - "label": "Ассамский", - "value": "31" - }, - { - "label": "Астурийский", - "value": "32" - }, - { - "label": "Афарский", - "value": "33" - }, - { - "label": "Африкаанс", - "value": "34" - }, - { - "label": "Ацтекский", - "value": "35" - }, - { - "label": "Баварский", - "value": "36" - }, - { - "label": "Бамбарийский", - "value": "37" - }, - { - "label": "Баскский", - "value": "39" - }, - { - "label": "Башкирский", - "value": "40" - }, - { - "label": "Белорусский", - "value": "10" - }, - { - "label": "Бенгальский", - "value": "41" - }, - { - "label": "Бирманский", - "value": "42" - }, - { - "label": "Бислама", - "value": "43" - }, - { - "label": "Бихари", - "value": "44" - }, - { - "label": "Болгарский", - "value": "45" - }, - { - "label": "Боснийский", - "value": "234" - }, - { - "label": "Бретонский", - "value": "47" - }, - { - "label": "Валенсийский", - "value": "48" - }, - { - "label": "Валлийский", - "value": "49" - }, - { - "label": "Валлонский", - "value": "50" - }, - { - "label": "Венгерский", - "value": "51" - }, - { - "label": "Венда", - "value": "52" - }, - { - "label": "Венетский", - "value": "53" - }, - { - "label": "Верхнелужицкий", - "value": "54" - }, - { - "label": "Волоф", - "value": "55" - }, - { - "label": "Вьетнамский", - "value": "57" - }, - { - "label": "Гавайский", - "value": "58" - }, - { - "label": "Гаитянский", - "value": "59" - }, - { - "label": "Галисийский", - "value": "60" - }, - { - "label": "Гереро", - "value": "61" - }, - { - "label": "Голландский", - "value": "62" - }, - { - "label": "Греческий", - "value": "63" - }, - { - "label": "Грузинский", - "value": "64" - }, - { - "label": "Гуарани", - "value": "65" - }, - { - "label": "Гуджарати", - "value": "66" - }, - { - "label": "Датский", - "value": "19" - }, - { - "label": "Дзонг-кэ", - "value": "68" - }, - { - "label": "Древнегреческий", - "value": "69" - }, - { - "label": "Западно-фламандский", - "value": "70" - }, - { - "label": "Зулу", - "value": "71" - }, - { - "label": "Иврит", - "value": "15" - }, - { - "label": "Игбо", - "value": "72" - }, - { - "label": "Идиш", - "value": "73" - }, - { - "label": "Илоко", - "value": "74" - }, - { - "label": "Индонезийский", - "value": "75" - }, - { - "label": "Интерлингва", - "value": "76" - }, - { - "label": "Инуктитут", - "value": "77" - }, - { - "label": "Инупиак", - "value": "78" - }, - { - "label": "Ирландский", - "value": "79" - }, - { - "label": "Исландский", - "value": "80" - }, - { - "label": "Испанский", - "value": "6" - }, - { - "label": "Итальянский", - "value": "5" - }, - { - "label": "Йоруба", - "value": "81" - }, - { - "label": "Кабильский", - "value": "82" - }, - { - "label": "Казахский", - "value": "83" - }, - { - "label": "Калмыцкий", - "value": "235" - }, - { - "label": "Каннада", - "value": "84" - }, - { - "label": "Кантонский юэ", - "value": "85" - }, - { - "label": "Канури", - "value": "86" - }, - { - "label": "Каталанский", - "value": "87" - }, - { - "label": "Кашмири", - "value": "88" - }, - { - "label": "Кечуа", - "value": "90" - }, - { - "label": "Кикуйю", - "value": "91" - }, - { - "label": "Киньяруанда", - "value": "92" - }, - { - "label": "Киргизский", - "value": "93" - }, - { - "label": "Китайский", - "value": "7" - }, - { - "label": "Клингонский", - "value": "94" - }, - { - "label": "Коми", - "value": "95" - }, - { - "label": "Конго", - "value": "96" - }, - { - "label": "Конкани", - "value": "97" - }, - { - "label": "Корейский", - "value": "98" - }, - { - "label": "Корсиканский", - "value": "100" - }, - { - "label": "Котава", - "value": "101" - }, - { - "label": "Кри", - "value": "102" - }, - { - "label": "Курдский", - "value": "105" - }, - { - "label": "Кхмерский", - "value": "107" - }, - { - "label": "Лакский", - "value": "233" - }, - { - "label": "Лаосский", - "value": "109" - }, - { - "label": "Латынь", - "value": "110" - }, - { - "label": "Латышский", - "value": "111" - }, - { - "label": "Лезгинский", - "value": "112" - }, - { - "label": "Лимбургский", - "value": "113" - }, - { - "label": "Лингала", - "value": "114" - }, - { - "label": "Литовский", - "value": "115" - }, - { - "label": "Луба", - "value": "118" - }, - { - "label": "Луганда", - "value": "119" - }, - { - "label": "Люксембургский", - "value": "120" - }, - { - "label": "Македонский", - "value": "121" - }, - { - "label": "Малагасийский", - "value": "122" - }, - { - "label": "Малайский", - "value": "123" - }, - { - "label": "Мальдивский", - "value": "125" - }, - { - "label": "Мальтийский", - "value": "126" - }, - { - "label": "Маори", - "value": "127" - }, - { - "label": "Марийский", - "value": "232" - }, - { - "label": "Маршалльский", - "value": "130" - }, - { - "label": "Молдавский", - "value": "11" - }, - { - "label": "Монгольский", - "value": "133" - }, - { - "label": "Мяо (хмонг)", - "value": "209" - }, - { - "label": "Навахо", - "value": "135" - }, - { - "label": "Неаполитанский", - "value": "139" - }, - { - "label": "Немецкий", - "value": "3" - }, - { - "label": "Непальский", - "value": "140" - }, - { - "label": "Норвежский", - "value": "18" - }, - { - "label": "Осетинский", - "value": "147" - }, - { - "label": "Пакистанский", - "value": "230" - }, - { - "label": "Пенджабский", - "value": "149" - }, - { - "label": "Персидский", - "value": "151" - }, - { - "label": "Польский", - "value": "152" - }, - { - "label": "Португальский", - "value": "153" - }, - { - "label": "Румынский", - "value": "158" - }, - { - "label": "Русский", - "value": "1" - }, - { - "label": "Санскрит", - "value": "163" - }, - { - "label": "Сардинский", - "value": "164" - }, - { - "label": "Сербохорватский", - "value": "166" - }, - { - "label": "Словацкий", - "value": "170" - }, - { - "label": "Словенский", - "value": "171" - }, - { - "label": "Сомали", - "value": "172" - }, - { - "label": "Старотурецкий", - "value": "174" - }, - { - "label": "Суахили", - "value": "175" - }, - { - "label": "Сунданский", - "value": "176" - }, - { - "label": "Тагальский", - "value": "177" - }, - { - "label": "Таджикский", - "value": "178" - }, - { - "label": "Таитянский", - "value": "179" - }, - { - "label": "Тайваньский", - "value": "180" - }, - { - "label": "Тайский", - "value": "181" - }, - { - "label": "Тамильский", - "value": "182" - }, - { - "label": "Татарский", - "value": "12" - }, - { - "label": "Телугу", - "value": "184" - }, - { - "label": "Тибетский", - "value": "185" - }, - { - "label": "Тигринья", - "value": "186" - }, - { - "label": "Ток-писин", - "value": "187" - }, - { - "label": "Токи пона", - "value": "188" - }, - { - "label": "Тонганский", - "value": "189" - }, - { - "label": "Тсвана", - "value": "191" - }, - { - "label": "Тсонга", - "value": "192" - }, - { - "label": "Турецкий", - "value": "193" - }, - { - "label": "Туркменский", - "value": "194" - }, - { - "label": "Удмуртский", - "value": "196" - }, - { - "label": "Узбекский", - "value": "197" - }, - { - "label": "Уйгурский", - "value": "198" - }, - { - "label": "Украинский", - "value": "9" - }, - { - "label": "Фиджийский", - "value": "201" - }, - { - "label": "Филиппинский", - "value": "229" - }, - { - "label": "Финский", - "value": "17" - }, - { - "label": "Французский", - "value": "4" - }, - { - "label": "Фризский", - "value": "203" - }, - { - "label": "Фулах", - "value": "204" - }, - { - "label": "Хауса", - "value": "206" - }, - { - "label": "Хинди", - "value": "207" - }, - { - "label": "Хири-моту", - "value": "208" - }, - { - "label": "Чеченский", - "value": "213" - }, - { - "label": "Чешский", - "value": "13" - }, - { - "label": "Чувашский", - "value": "217" - }, - { - "label": "Шведский", - "value": "16" - }, - { - "label": "Швейцарский немецкий", - "value": "218" - }, - { - "label": "Шона", - "value": "219" - }, - { - "label": "Шотландский", - "value": "67" - }, - { - "label": "Эве", - "value": "221" - }, - { - "label": "Эскимосский", - "value": "223" - }, - { - "label": "Эсперанто", - "value": "14" - }, - { - "label": "Эстонский", - "value": "224" - }, - { - "label": "Южно-корейский", - "value": "231" - }, - { - "label": "Юкатекский", - "value": "225" - }, - { - "label": "Яванский", - "value": "227" - }, - { - "label": "Японский", - "value": "8" - } - ], - "inputType": "Picker" - }, - { - "key": "t_lang", - "label": "Язык перевода:", - "values": [ - { - "label": "Неважно", - "value": "0" - }, - { - "label": "Абхазский", - "value": "20" - }, - { - "label": "Аварский", - "value": "21" - }, - { - "label": "Азербайджанский", - "value": "22" - }, - { - "label": "Аймара", - "value": "23" - }, - { - "label": "Акан", - "value": "24" - }, - { - "label": "Албанский", - "value": "25" - }, - { - "label": "Амхарский", - "value": "26" - }, - { - "label": "Английский", - "value": "2" - }, - { - "label": "Арабский", - "value": "27" - }, - { - "label": "Арагонский", - "value": "28" - }, - { - "label": "Арберешский", - "value": "29" - }, - { - "label": "Армянский", - "value": "30" - }, - { - "label": "Ассамский", - "value": "31" - }, - { - "label": "Астурийский", - "value": "32" - }, - { - "label": "Афарский", - "value": "33" - }, - { - "label": "Африкаанс", - "value": "34" - }, - { - "label": "Ацтекский", - "value": "35" - }, - { - "label": "Баварский", - "value": "36" - }, - { - "label": "Бамбарийский", - "value": "37" - }, - { - "label": "Баскский", - "value": "39" - }, - { - "label": "Башкирский", - "value": "40" - }, - { - "label": "Белорусский", - "value": "10" - }, - { - "label": "Бенгальский", - "value": "41" - }, - { - "label": "Бирманский", - "value": "42" - }, - { - "label": "Бислама", - "value": "43" - }, - { - "label": "Бихари", - "value": "44" - }, - { - "label": "Болгарский", - "value": "45" - }, - { - "label": "Боснийский", - "value": "234" - }, - { - "label": "Бретонский", - "value": "47" - }, - { - "label": "Валенсийский", - "value": "48" - }, - { - "label": "Валлийский", - "value": "49" - }, - { - "label": "Валлонский", - "value": "50" - }, - { - "label": "Венгерский", - "value": "51" - }, - { - "label": "Венда", - "value": "52" - }, - { - "label": "Венетский", - "value": "53" - }, - { - "label": "Верхнелужицкий", - "value": "54" - }, - { - "label": "Волоф", - "value": "55" - }, - { - "label": "Вьетнамский", - "value": "57" - }, - { - "label": "Гавайский", - "value": "58" - }, - { - "label": "Гаитянский", - "value": "59" - }, - { - "label": "Галисийский", - "value": "60" - }, - { - "label": "Гереро", - "value": "61" - }, - { - "label": "Голландский", - "value": "62" - }, - { - "label": "Греческий", - "value": "63" - }, - { - "label": "Грузинский", - "value": "64" - }, - { - "label": "Гуарани", - "value": "65" - }, - { - "label": "Гуджарати", - "value": "66" - }, - { - "label": "Датский", - "value": "19" - }, - { - "label": "Дзонг-кэ", - "value": "68" - }, - { - "label": "Древнегреческий", - "value": "69" - }, - { - "label": "Западно-фламандский", - "value": "70" - }, - { - "label": "Зулу", - "value": "71" - }, - { - "label": "Иврит", - "value": "15" - }, - { - "label": "Игбо", - "value": "72" - }, - { - "label": "Идиш", - "value": "73" - }, - { - "label": "Илоко", - "value": "74" - }, - { - "label": "Индонезийский", - "value": "75" - }, - { - "label": "Интерлингва", - "value": "76" - }, - { - "label": "Инуктитут", - "value": "77" - }, - { - "label": "Инупиак", - "value": "78" - }, - { - "label": "Ирландский", - "value": "79" - }, - { - "label": "Исландский", - "value": "80" - }, - { - "label": "Испанский", - "value": "6" - }, - { - "label": "Итальянский", - "value": "5" - }, - { - "label": "Йоруба", - "value": "81" - }, - { - "label": "Кабильский", - "value": "82" - }, - { - "label": "Казахский", - "value": "83" - }, - { - "label": "Калмыцкий", - "value": "235" - }, - { - "label": "Каннада", - "value": "84" - }, - { - "label": "Кантонский юэ", - "value": "85" - }, - { - "label": "Канури", - "value": "86" - }, - { - "label": "Каталанский", - "value": "87" - }, - { - "label": "Кашмири", - "value": "88" - }, - { - "label": "Кечуа", - "value": "90" - }, - { - "label": "Кикуйю", - "value": "91" - }, - { - "label": "Киньяруанда", - "value": "92" - }, - { - "label": "Киргизский", - "value": "93" - }, - { - "label": "Китайский", - "value": "7" - }, - { - "label": "Клингонский", - "value": "94" - }, - { - "label": "Коми", - "value": "95" - }, - { - "label": "Конго", - "value": "96" - }, - { - "label": "Конкани", - "value": "97" - }, - { - "label": "Корейский", - "value": "98" - }, - { - "label": "Корсиканский", - "value": "100" - }, - { - "label": "Котава", - "value": "101" - }, - { - "label": "Кри", - "value": "102" - }, - { - "label": "Курдский", - "value": "105" - }, - { - "label": "Кхмерский", - "value": "107" - }, - { - "label": "Лакский", - "value": "233" - }, - { - "label": "Лаосский", - "value": "109" - }, - { - "label": "Латынь", - "value": "110" - }, - { - "label": "Латышский", - "value": "111" - }, - { - "label": "Лезгинский", - "value": "112" - }, - { - "label": "Лимбургский", - "value": "113" - }, - { - "label": "Лингала", - "value": "114" - }, - { - "label": "Литовский", - "value": "115" - }, - { - "label": "Луба", - "value": "118" - }, - { - "label": "Луганда", - "value": "119" - }, - { - "label": "Люксембургский", - "value": "120" - }, - { - "label": "Македонский", - "value": "121" - }, - { - "label": "Малагасийский", - "value": "122" - }, - { - "label": "Малайский", - "value": "123" - }, - { - "label": "Мальдивский", - "value": "125" - }, - { - "label": "Мальтийский", - "value": "126" - }, - { - "label": "Маори", - "value": "127" - }, - { - "label": "Марийский", - "value": "232" - }, - { - "label": "Маршалльский", - "value": "130" - }, - { - "label": "Молдавский", - "value": "11" - }, - { - "label": "Монгольский", - "value": "133" - }, - { - "label": "Мяо (хмонг)", - "value": "209" - }, - { - "label": "Навахо", - "value": "135" - }, - { - "label": "Неаполитанский", - "value": "139" - }, - { - "label": "Немецкий", - "value": "3" - }, - { - "label": "Непальский", - "value": "140" - }, - { - "label": "Норвежский", - "value": "18" - }, - { - "label": "Осетинский", - "value": "147" - }, - { - "label": "Пакистанский", - "value": "230" - }, - { - "label": "Пенджабский", - "value": "149" - }, - { - "label": "Персидский", - "value": "151" - }, - { - "label": "Польский", - "value": "152" - }, - { - "label": "Португальский", - "value": "153" - }, - { - "label": "Румынский", - "value": "158" - }, - { - "label": "Русский", - "value": "1" - }, - { - "label": "Санскрит", - "value": "163" - }, - { - "label": "Сардинский", - "value": "164" - }, - { - "label": "Сербохорватский", - "value": "166" - }, - { - "label": "Словацкий", - "value": "170" - }, - { - "label": "Словенский", - "value": "171" - }, - { - "label": "Сомали", - "value": "172" - }, - { - "label": "Старотурецкий", - "value": "174" - }, - { - "label": "Суахили", - "value": "175" - }, - { - "label": "Сунданский", - "value": "176" - }, - { - "label": "Тагальский", - "value": "177" - }, - { - "label": "Таджикский", - "value": "178" - }, - { - "label": "Таитянский", - "value": "179" - }, - { - "label": "Тайваньский", - "value": "180" - }, - { - "label": "Тайский", - "value": "181" - }, - { - "label": "Тамильский", - "value": "182" - }, - { - "label": "Татарский", - "value": "12" - }, - { - "label": "Телугу", - "value": "184" - }, - { - "label": "Тибетский", - "value": "185" - }, - { - "label": "Тигринья", - "value": "186" - }, - { - "label": "Ток-писин", - "value": "187" - }, - { - "label": "Токи пона", - "value": "188" - }, - { - "label": "Тонганский", - "value": "189" - }, - { - "label": "Тсвана", - "value": "191" - }, - { - "label": "Тсонга", - "value": "192" - }, - { - "label": "Турецкий", - "value": "193" - }, - { - "label": "Туркменский", - "value": "194" - }, - { - "label": "Удмуртский", - "value": "196" - }, - { - "label": "Узбекский", - "value": "197" - }, - { - "label": "Уйгурский", - "value": "198" - }, - { - "label": "Украинский", - "value": "9" - }, - { - "label": "Фиджийский", - "value": "201" - }, - { - "label": "Филиппинский", - "value": "229" - }, - { - "label": "Финский", - "value": "17" - }, - { - "label": "Французский", - "value": "4" - }, - { - "label": "Фризский", - "value": "203" - }, - { - "label": "Фулах", - "value": "204" - }, - { - "label": "Хауса", - "value": "206" - }, - { - "label": "Хинди", - "value": "207" - }, - { - "label": "Хири-моту", - "value": "208" - }, - { - "label": "Чеченский", - "value": "213" - }, - { - "label": "Чешский", - "value": "13" - }, - { - "label": "Чувашский", - "value": "217" - }, - { - "label": "Шведский", - "value": "16" - }, - { - "label": "Швейцарский немецкий", - "value": "218" - }, - { - "label": "Шона", - "value": "219" - }, - { - "label": "Шотландский", - "value": "67" - }, - { - "label": "Эве", - "value": "221" - }, - { - "label": "Эскимосский", - "value": "223" - }, - { - "label": "Эсперанто", - "value": "14" - }, - { - "label": "Эстонский", - "value": "224" - }, - { - "label": "Южно-корейский", - "value": "231" - }, - { - "label": "Юкатекский", - "value": "225" - }, - { - "label": "Яванский", - "value": "227" - }, - { - "label": "Японский", - "value": "8" - } - ], - "inputType": "Picker" - }, - { - "key": "type", - "label": "Тип:", - "values": [ - { - "label": "Неважно", - "value": "0" - }, - { - "label": "Только авторские", - "value": "2" - }, - { - "label": "Только переводы", - "value": "1" - } - ], - "inputType": "Picker" - }, - { - "key": "trash", - "label": "Другое:", - "values": [ - { - "label": "Без фэндомов", - "value": "fandoms_ex_all" - }, - { - "label": "Готовые на 100%", - "value": "ready" - }, - { - "label": "Доступные для перевода", - "value": "tr" - }, - { - "label": "Доступные для скачивания", - "value": "gen" - }, - { - "label": "Завершённые проекты", - "value": "wealth" - }, - { - "label": "Распродажа", - "value": "discount" - }, - { - "label": "Только онгоинги", - "value": "ongoings" - }, - { - "label": "Убрать машинный", - "value": "remove_machinelate" - } - ], - "inputType": "Checkbox" - }, - { - "key": "sort", - "label": "Сортировка:", - "values": [ - { - "label": "По рейтингу", - "value": "6" - }, - { - "label": "По дате последней активности", - "value": "4" - }, - { - "label": "По дате создания", - "value": "3" - }, - { - "label": "По кол-ву бесплатных глав", - "value": "11" - }, - { - "label": "По кол-ву в закладках", - "value": "13" - }, - { - "label": "По кол-ву в избранном", - "value": "14" - }, - { - "label": "По кол-ву лайков", - "value": "8" - }, - { - "label": "По кол-ву переведённых глав", - "value": "7" - }, - { - "label": "По кол-ву рецензий", - "value": "12" - }, - { - "label": "По кол-ву страниц", - "value": "10" - }, - { - "label": "По названию на языке оригинала", - "value": "1" - }, - { - "label": "По названию на языке перевода", - "value": "2" - }, - { - "label": "По просмотрам", - "value": "5" - }, - { - "label": "По степени готовности", - "value": "0" - }, - { - "label": "Случайно", - "value": "9" - } - ], - "inputType": "Picker" - }, - { - "key": "genres", - "label": "Жанры:", - "values": [ - { - "label": "Анал", - "value": "2" - }, - { - "label": "Бдсм", - "value": "3" - }, - { - "label": "Большая грудь", - "value": "5" - }, - { - "label": "Большая попка", - "value": "6" - }, - { - "label": "Большой член", - "value": "7" - }, - { - "label": "Бондаж", - "value": "8" - }, - { - "label": "В первый раз", - "value": "9" - }, - { - "label": "В цвете", - "value": "10" - }, - { - "label": "Гарем", - "value": "11" - }, - { - "label": "Гендарная интрига", - "value": "12" - }, - { - "label": "Групповой секс", - "value": "13" - }, - { - "label": "Детектив", - "value": "39" - }, - { - "label": "Драма", - "value": "14" - }, - { - "label": "Зрелые женщины (milf)", - "value": "15" - }, - { - "label": "Измена", - "value": "16" - }, - { - "label": "Изнасилование", - "value": "17" - }, - { - "label": "Инцест", - "value": "18" - }, - { - "label": "Исторический", - "value": "19" - }, - { - "label": "Комедия", - "value": "20" - }, - { - "label": "Контроль над разумом", - "value": "35" - }, - { - "label": "Маленькая грудь", - "value": "21" - }, - { - "label": "Мистика", - "value": "40" - }, - { - "label": "Научная фантастика", - "value": "22" - }, - { - "label": "Нетораре", - "value": "23" - }, - { - "label": "Оральный секс", - "value": "24" - }, - { - "label": "Повседневность", - "value": "41" - }, - { - "label": "Приключения", - "value": "38" - }, - { - "label": "Публичный секс", - "value": "33" - }, - { - "label": "Романтика", - "value": "25" - }, - { - "label": "С изображениями", - "value": "36" - }, - { - "label": "Сверхъестественное", - "value": "34" - }, - { - "label": "Смат", - "value": "37" - }, - { - "label": "Тентакли", - "value": "26" - }, - { - "label": "Трагедия", - "value": "27" - }, - { - "label": "Ужасы", - "value": "28" - }, - { - "label": "Фантастика", - "value": "32" - }, - { - "label": "Фэнтези", - "value": "29" - }, - { - "label": "Чикан", - "value": "30" - }, - { - "label": "Этти", - "value": "31" - }, - { - "label": "Ahegao", - "value": "1" - } - ], - "inputType": "Checkbox" - }, - { - "key": "tags", - "label": "Тэги:", - "values": [ - { - "label": "+18", - "value": "141" - }, - { - "label": "18+", - "value": "200" - }, - { - "label": "21+", - "value": "334" - }, - { - "label": "Адекватные главные герои", - "value": "253" - }, - { - "label": "Азартные игры", - "value": "210" - }, - { - "label": "Айдолы", - "value": "364" - }, - { - "label": "Акула", - "value": "53" - }, - { - "label": "Альтернативное развитие событий", - "value": "338" - }, - { - "label": "Аморальный главный герой", - "value": "219" - }, - { - "label": "Анал", - "value": "7" - }, - { - "label": "Анальный секс", - "value": "67" - }, - { - "label": "Ангелы", - "value": "114" - }, - { - "label": "Антигерой", - "value": "226" - }, - { - "label": "Аристократия", - "value": "260" - }, - { - "label": "Артефакт", - "value": "379" - }, - { - "label": "Афродизиак", - "value": "276" - }, - { - "label": "Ахегао", - "value": "240" - }, - { - "label": "Бабушка беременна от внука", - "value": "393" - }, - { - "label": "Бабушка и внук", - "value": "380" - }, - { - "label": "Бдсм", - "value": "131" - }, - { - "label": "Беременность", - "value": "148" - }, - { - "label": "Бесплатно", - "value": "79" - }, - { - "label": "Бесстрашные персонажи", - "value": "339" - }, - { - "label": "Библиотека", - "value": "265" - }, - { - "label": "Бистиалити", - "value": "391" - }, - { - "label": "Битва за трон", - "value": "404" - }, - { - "label": "Близнецы", - "value": "198" - }, - { - "label": "Блондинка", - "value": "91" - }, - { - "label": "Богатые персонажи", - "value": "248" - }, - { - "label": "Боги", - "value": "115" - }, - { - "label": "Боевик", - "value": "252" - }, - { - "label": "Большая грудь", - "value": "33" - }, - { - "label": "Большая попка", - "value": "328" - }, - { - "label": "Большой член", - "value": "76" - }, - { - "label": "Большой член сына", - "value": "396" - }, - { - "label": "Босс и подчиненный", - "value": "330" - }, - { - "label": "Брак", - "value": "182" - }, - { - "label": "Брак по расчёту", - "value": "346" - }, - { - "label": "Брат", - "value": "29" - }, - { - "label": "Брат и сестра", - "value": "30" - }, - { - "label": "Брюнетка", - "value": "28" - }, - { - "label": "Бэтмен", - "value": "369" - }, - { - "label": "Бэтмен", - "value": "170" - }, - { - "label": "В первый раз", - "value": "179" - }, - { - "label": "Вагинальный секс", - "value": "57" - }, - { - "label": "Вагинальный секс", - "value": "171" - }, - { - "label": "Вайурист", - "value": "9" - }, - { - "label": "Вампиры", - "value": "133" - }, - { - "label": "Ван-пис", - "value": "335" - }, - { - "label": "Веб камера", - "value": "289" - }, - { - "label": "Ведьмы", - "value": "232" - }, - { - "label": "Викинги", - "value": "307" - }, - { - "label": "Виртуальная реальность", - "value": "382" - }, - { - "label": "Вирус", - "value": "203" - }, - { - "label": "Внучка", - "value": "189" - }, - { - "label": "Война", - "value": "387" - }, - { - "label": "Воспоминания из прошлого", - "value": "405" - }, - { - "label": "Враги становятся любовниками", - "value": "410" - }, - { - "label": "Время", - "value": "81" - }, - { - "label": "Второй шанс", - "value": "244" - }, - { - "label": "Вуайеризм", - "value": "62" - }, - { - "label": "Выживание", - "value": "135" - }, - { - "label": "Гарем", - "value": "107" - }, - { - "label": "Гарри поттер", - "value": "97" - }, - { - "label": "Гвен", - "value": "402" - }, - { - "label": "Гг имба", - "value": "87" - }, - { - "label": "Генетические модификации", - "value": "314" - }, - { - "label": "Гипноз", - "value": "143" - }, - { - "label": "Главная героиня девушка", - "value": "147" - }, - { - "label": "Главный герой женщина", - "value": "213" - }, - { - "label": "Главный герой извращенец", - "value": "116" - }, - { - "label": "Главный герой мужчина", - "value": "117" - }, - { - "label": "Глубокое горло", - "value": "94" - }, - { - "label": "Гоблины", - "value": "230" - }, - { - "label": "Город", - "value": "139" - }, - { - "label": "Городское фэнтези", - "value": "297" - }, - { - "label": "Грудное молоко", - "value": "225" - }, - { - "label": "Групповой секс", - "value": "72" - }, - { - "label": "Гэнг-бэнг", - "value": "235" - }, - { - "label": "Гяру", - "value": "222" - }, - { - "label": "Двойное проникновение", - "value": "42" - }, - { - "label": "Двойной анал", - "value": "47" - }, - { - "label": "Дворяне", - "value": "246" - }, - { - "label": "Деамоны старший школы", - "value": "291" - }, - { - "label": "Девственница", - "value": "119" - }, - { - "label": "Девушки-монстры", - "value": "223" - }, - { - "label": "Демоны", - "value": "98" - }, - { - "label": "Детектив", - "value": "249" - }, - { - "label": "Дзёсэй", - "value": "259" - }, - { - "label": "Доктор", - "value": "326" - }, - { - "label": "Дом", - "value": "138" - }, - { - "label": "Доминирование", - "value": "18" - }, - { - "label": "Дочь", - "value": "153" - }, - { - "label": "Дочь беременна от отца", - "value": "348" - }, - { - "label": "Древние времена", - "value": "383" - }, - { - "label": "Древний китай", - "value": "261" - }, - { - "label": "Другой мир", - "value": "365" - }, - { - "label": "Дружба", - "value": "325" - }, - { - "label": "Друзья детства", - "value": "183" - }, - { - "label": "Дядя", - "value": "160" - }, - { - "label": "Жена", - "value": "70" - }, - { - "label": "Жена и муж", - "value": "99" - }, - { - "label": "Жена шлюха", - "value": "236" - }, - { - "label": "Женское доминирование", - "value": "100" - }, - { - "label": "Жесткий секс", - "value": "283" - }, - { - "label": "Жёсткий секс", - "value": "101" - }, - { - "label": "Жестокие персонажи", - "value": "254" - }, - { - "label": "Жестокий мир", - "value": "336" - }, - { - "label": "Жестокость", - "value": "123" - }, - { - "label": "Заботливый главный герой", - "value": "340" - }, - { - "label": "Зависимость", - "value": "370" - }, - { - "label": "Заключение", - "value": "196" - }, - { - "label": "Заключённые", - "value": "384" - }, - { - "label": "Замок", - "value": "140" - }, - { - "label": "Запретная любовь", - "value": "273" - }, - { - "label": "Заражение", - "value": "206" - }, - { - "label": "Звёздные войны", - "value": "120" - }, - { - "label": "Зверодевочки", - "value": "158" - }, - { - "label": "Зло", - "value": "343" - }, - { - "label": "Золовка", - "value": "77" - }, - { - "label": "Золотой дождь", - "value": "146" - }, - { - "label": "Зомби апокалипсис", - "value": "241" - }, - { - "label": "Зоофилия", - "value": "144" - }, - { - "label": "Зрелые женщины", - "value": "398" - }, - { - "label": "Игровые элементы", - "value": "385" - }, - { - "label": "Извращения", - "value": "192" - }, - { - "label": "Измена", - "value": "71" - }, - { - "label": "Изменения внешности", - "value": "315" - }, - { - "label": "Изменения личности", - "value": "316" - }, - { - "label": "Изнасилование", - "value": "275" - }, - { - "label": "Изуку мидория", - "value": "337" - }, - { - "label": "Ино", - "value": "127" - }, - { - "label": "Инопланетяне", - "value": "304" - }, - { - "label": "Интересный сюжет", - "value": "349" - }, - { - "label": "Интимные сцены", - "value": "322" - }, - { - "label": "Интриги и заговоры", - "value": "262" - }, - { - "label": "Интроверт", - "value": "38" - }, - { - "label": "Инфекция", - "value": "207" - }, - { - "label": "Инцест", - "value": "35" - }, - { - "label": "Исторический роман", - "value": "406" - }, - { - "label": "Камера", - "value": "92" - }, - { - "label": "Колледж", - "value": "82" - }, - { - "label": "Комикс", - "value": "286" - }, - { - "label": "Контроль", - "value": "19" - }, - { - "label": "Контроль над разумом", - "value": "181" - }, - { - "label": "Контроль разума", - "value": "65" - }, - { - "label": "Кончил внутрь", - "value": "221" - }, - { - "label": "Королевская семья", - "value": "358" - }, - { - "label": "Коррупция", - "value": "49" - }, - { - "label": "Космос", - "value": "204" - }, - { - "label": "Красивая главная героиня", - "value": "255" - }, - { - "label": "Красивые женщины", - "value": "321" - }, - { - "label": "Красивый главный герой", - "value": "266" - }, - { - "label": "Ксенофилия", - "value": "386" - }, - { - "label": "Кулинария", - "value": "362" - }, - { - "label": "Культвация", - "value": "86" - }, - { - "label": "Кунилингус", - "value": "152" - }, - { - "label": "Кушина", - "value": "399" - }, - { - "label": "Лактация", - "value": "11" - }, - { - "label": "Лесби", - "value": "408" - }, - { - "label": "Лишение девственности", - "value": "212" - }, - { - "label": "Лоли", - "value": "218" - }, - { - "label": "Лунатизм", - "value": "279" - }, - { - "label": "Любовь", - "value": "89" - }, - { - "label": "Магический мир", - "value": "357" - }, - { - "label": "Магия", - "value": "80" - }, - { - "label": "Мама", - "value": "3" - }, - { - "label": "Мама беременна от сына", - "value": "274" - }, - { - "label": "Мама и дочь", - "value": "163" - }, - { - "label": "Мама и сын", - "value": "1" - }, - { - "label": "Мама супермена", - "value": "39" - }, - { - "label": "Манипуляция временем", - "value": "292" - }, - { - "label": "Марвел", - "value": "290" - }, - { - "label": "Марвел", - "value": "173" - }, - { - "label": "Марти стью", - "value": "102" - }, - { - "label": "Массаж", - "value": "224" - }, - { - "label": "Мастурбация", - "value": "63" - }, - { - "label": "Мать", - "value": "239" - }, - { - "label": "Мать и дочь", - "value": "381" - }, - { - "label": "Мать и сын", - "value": "237" - }, - { - "label": "Мафия", - "value": "256" - }, - { - "label": "Мачеха", - "value": "197" - }, - { - "label": "Мачеха беременна от сына", - "value": "395" - }, - { - "label": "Мачеха и сын", - "value": "394" - }, - { - "label": "Медсестра", - "value": "341" - }, - { - "label": "Межрассовый", - "value": "54" - }, - { - "label": "Месть", - "value": "306" - }, - { - "label": "Меха", - "value": "268" - }, - { - "label": "Ми", - "value": "243" - }, - { - "label": "Милф", - "value": "34" - }, - { - "label": "Милф", - "value": "180" - }, - { - "label": "Минет", - "value": "52" - }, - { - "label": "Мистика", - "value": "250" - }, - { - "label": "Младшая сестра", - "value": "154" - }, - { - "label": "Много спермы", - "value": "409" - }, - { - "label": "Модель", - "value": "324" - }, - { - "label": "Монстры", - "value": "333" - }, - { - "label": "Мошеничество", - "value": "44" - }, - { - "label": "Мужская беременность", - "value": "363" - }, - { - "label": "Мужчина протагонист", - "value": "108" - }, - { - "label": "Музыка", - "value": "331" - }, - { - "label": "Мэри съюха", - "value": "309" - }, - { - "label": "Наруко", - "value": "400" - }, - { - "label": "Наруто", - "value": "46" - }, - { - "label": "Насилие", - "value": "128" - }, - { - "label": "Насилие и жестокость", - "value": "193" - }, - { - "label": "Научный эксперимент", - "value": "313" - }, - { - "label": "Нежить", - "value": "373" - }, - { - "label": "Некромантия", - "value": "298" - }, - { - "label": "Ненормативная лексика", - "value": "124" - }, - { - "label": "Нетораре", - "value": "69" - }, - { - "label": "Нетори", - "value": "284" - }, - { - "label": "Нижнее бельё", - "value": "392" - }, - { - "label": "Ниндзя", - "value": "296" - }, - { - "label": "Ношеные трусики", - "value": "166" - }, - { - "label": "Нудизм", - "value": "156" - }, - { - "label": "Няня", - "value": "88" - }, - { - "label": "Обмен женами", - "value": "78" - }, - { - "label": "Оборотни", - "value": "136" - }, - { - "label": "Обратный гарем", - "value": "214" - }, - { - "label": "Одержимость", - "value": "345" - }, - { - "label": "Омегаверс", - "value": "368" - }, - { - "label": "Оплодотворение", - "value": "157" - }, - { - "label": "Оральный секс", - "value": "10" - }, - { - "label": "Оргия", - "value": "356" - }, - { - "label": "Орки", - "value": "388" - }, - { - "label": "От слабого к сильному", - "value": "351" - }, - { - "label": "Отец", - "value": "2" - }, - { - "label": "Отец делится с сыном", - "value": "6" - }, - { - "label": "Отец и дочь", - "value": "205" - }, - { - "label": "Отец куколд", - "value": "272" - }, - { - "label": "Офис", - "value": "234" - }, - { - "label": "Падчерица", - "value": "271" - }, - { - "label": "Пайзури", - "value": "195" - }, - { - "label": "Папа и дочь", - "value": "360" - }, - { - "label": "Паразиты", - "value": "208" - }, - { - "label": "Параллельный мир", - "value": "320" - }, - { - "label": "Пародия", - "value": "371" - }, - { - "label": "Первый раз", - "value": "159" - }, - { - "label": "Перемещение в другой мир", - "value": "347" - }, - { - "label": "Перемещение во времени", - "value": "245" - }, - { - "label": "Перерождение", - "value": "109" - }, - { - "label": "Перерождение в злодея", - "value": "202" - }, - { - "label": "Пирсинг", - "value": "145" - }, - { - "label": "Писатель", - "value": "267" - }, - { - "label": "Планомерное развитие событий", - "value": "350" - }, - { - "label": "Повседневность", - "value": "247" - }, - { - "label": "Подглядывание", - "value": "280" - }, - { - "label": "Подчинение", - "value": "106" - }, - { - "label": "Подчинение и унижение", - "value": "211" - }, - { - "label": "Поедание киски", - "value": "26" - }, - { - "label": "Покемоны", - "value": "132" - }, - { - "label": "Покорная", - "value": "8" - }, - { - "label": "Полигамия", - "value": "352" - }, - { - "label": "Половое воспитание", - "value": "37" - }, - { - "label": "Полулюди", - "value": "231" - }, - { - "label": "Попаданец", - "value": "103" - }, - { - "label": "Попадание в книгу", - "value": "361" - }, - { - "label": "Порка", - "value": "20" - }, - { - "label": "Порно", - "value": "278" - }, - { - "label": "Постапокалипсис", - "value": "332" - }, - { - "label": "Потеря девственности", - "value": "142" - }, - { - "label": "Похищение", - "value": "161" - }, - { - "label": "Преданные любовный интерес", - "value": "407" - }, - { - "label": "Призраки", - "value": "412" - }, - { - "label": "Приключения", - "value": "134" - }, - { - "label": "Принуждение", - "value": "66" - }, - { - "label": "Психология", - "value": "238" - }, - { - "label": "Публично", - "value": "85" - }, - { - "label": "Публичный секс", - "value": "233" - }, - { - "label": "Раб", - "value": "353" - }, - { - "label": "Рабы", - "value": "308" - }, - { - "label": "Разват", - "value": "58" - }, - { - "label": "Разврат", - "value": "64" - }, - { - "label": "Райзен", - "value": "95" - }, - { - "label": "Раса инопланетных космических лесбиянок", - "value": "294" - }, - { - "label": "Религия", - "value": "403" - }, - { - "label": "Рестленг", - "value": "84" - }, - { - "label": "Риас гремори", - "value": "389" - }, - { - "label": "Романтика", - "value": "178" - }, - { - "label": "Рыжий", - "value": "90" - }, - { - "label": "С", - "value": "413" - }, - { - "label": "Сакура", - "value": "126" - }, - { - "label": "Самолет", - "value": "93" - }, - { - "label": "Санса старк", - "value": "277" - }, - { - "label": "Санта", - "value": "372" - }, - { - "label": "Свадьба", - "value": "73" - }, - { - "label": "Сверхсила", - "value": "228" - }, - { - "label": "Сверхъестественное", - "value": "319" - }, - { - "label": "Свингеры", - "value": "201" - }, - { - "label": "Свободные отношения", - "value": "186" - }, - { - "label": "Связывание", - "value": "137" - }, - { - "label": "Сёдзе", - "value": "264" - }, - { - "label": "Секс", - "value": "21" - }, - { - "label": "Секс без проникновения", - "value": "68" - }, - { - "label": "Секс втроем", - "value": "43" - }, - { - "label": "Секс игрушки", - "value": "59" - }, - { - "label": "Секс рабыня", - "value": "55" - }, - { - "label": "Секс с монстрами", - "value": "56" - }, - { - "label": "Секс с учителем", - "value": "184" - }, - { - "label": "Секса будет много", - "value": "151" - }, - { - "label": "Сексуальное желание", - "value": "209" - }, - { - "label": "Селфцест", - "value": "397" - }, - { - "label": "Семья", - "value": "5" - }, - { - "label": "Сестра", - "value": "31" - }, - { - "label": "Сестра беременна от брата", - "value": "355" - }, - { - "label": "Сильный с самого начала", - "value": "112" - }, - { - "label": "Симбиоз", - "value": "50" - }, - { - "label": "Сирена", - "value": "51" - }, - { - "label": "Система", - "value": "104" - }, - { - "label": "Сиськи", - "value": "285" - }, - { - "label": "Сквирт", - "value": "164" - }, - { - "label": "Скрытый секс", - "value": "287" - }, - { - "label": "Служанка", - "value": "215" - }, - { - "label": "Соб", - "value": "281" - }, - { - "label": "Соблазнение", - "value": "162" - }, - { - "label": "Современность", - "value": "217" - }, - { - "label": "Соколиный Глаз", - "value": "176" - }, - { - "label": "Соперничество", - "value": "216" - }, - { - "label": "Соседи", - "value": "61" - }, - { - "label": "Соседка", - "value": "312" - }, - { - "label": "Сперма", - "value": "229" - }, - { - "label": "Сперма на лицо", - "value": "199" - }, - { - "label": "Спящие", - "value": "187" - }, - { - "label": "Старшая сестра", - "value": "311" - }, - { - "label": "Стеб", - "value": "111" - }, - { - "label": "Студенты", - "value": "177" - }, - { - "label": "Суккуб", - "value": "390" - }, - { - "label": "Супергерои", - "value": "305" - }, - { - "label": "Суперспособности", - "value": "300" - }, - { - "label": "Сын", - "value": "4" - }, - { - "label": "Твинцест", - "value": "188" - }, - { - "label": "Темное фэнтези", - "value": "293" - }, - { - "label": "Тентакли", - "value": "303" - }, - { - "label": "Тетя", - "value": "113" - }, - { - "label": "Тетя беременна от племянника", - "value": "376" - }, - { - "label": "Тетя и племянник", - "value": "377" - }, - { - "label": "Техника", - "value": "302" - }, - { - "label": "Технологии", - "value": "301" - }, - { - "label": "Тёща", - "value": "270" - }, - { - "label": "Тиран", - "value": "310" - }, - { - "label": "Трагическое прошлое", - "value": "251" - }, - { - "label": "Трансмиграция", - "value": "269" - }, - { - "label": "Трансформация", - "value": "317" - }, - { - "label": "Триллер", - "value": "344" - }, - { - "label": "Трусики", - "value": "165" - }, - { - "label": "Убийства", - "value": "258" - }, - { - "label": "Удача", - "value": "299" - }, - { - "label": "Ужасы", - "value": "375" - }, - { - "label": "Улучшение тела", - "value": "288" - }, - { - "label": "Умная главная героиня", - "value": "242" - }, - { - "label": "Умные персонажи", - "value": "257" - }, - { - "label": "Умный главный герой", - "value": "354" - }, - { - "label": "Университет", - "value": "323" - }, - { - "label": "Ученик", - "value": "83" - }, - { - "label": "Ф", - "value": "149" - }, - { - "label": "Фанатичная любовь", - "value": "366" - }, - { - "label": "Фанаты", - "value": "367" - }, - { - "label": "Фантастика", - "value": "295" - }, - { - "label": "Фанфик", - "value": "40" - }, - { - "label": "Фелляция", - "value": "22" - }, - { - "label": "Ферма", - "value": "191" - }, - { - "label": "Фетиш", - "value": "60" - }, - { - "label": "Флэш", - "value": "121" - }, - { - "label": "Футанария", - "value": "150" - }, - { - "label": "Фэнтези", - "value": "359" - }, - { - "label": "Хентай", - "value": "75" - }, - { - "label": "Хината", - "value": "110" - }, - { - "label": "Холодная главная героиня", - "value": "263" - }, - { - "label": "Черная вдова", - "value": "220" - }, - { - "label": "Черная Вдова", - "value": "175" - }, - { - "label": "Черный юмор", - "value": "374" - }, - { - "label": "Читерство", - "value": "45" - }, - { - "label": "Чтение мыслей", - "value": "227" - }, - { - "label": "Чудовища", - "value": "378" - }, - { - "label": "Шантаж", - "value": "129" - }, - { - "label": "Школа", - "value": "118" - }, - { - "label": "Школьная жизнь", - "value": "318" - }, - { - "label": "Шлюха", - "value": "32" - }, - { - "label": "Шоу-бизнес", - "value": "329" - }, - { - "label": "Шоу-бизнес", - "value": "172" - }, - { - "label": "Эксгибиционизм", - "value": "74" - }, - { - "label": "Элементы бдсм", - "value": "185" - }, - { - "label": "Эмма уотсон", - "value": "342" - }, - { - "label": "Эмма Уотсон", - "value": "169" - }, - { - "label": "Эротика", - "value": "36" - }, - { - "label": "Этти", - "value": "327" - }, - { - "label": "Юмор", - "value": "105" - }, - { - "label": "Яндере", - "value": "155" - }, - { - "label": "Bl", - "value": "125" - }, - { - "label": "Dc", - "value": "411" - }, - { - "label": "Gl", - "value": "96" - }, - { - "label": "Harry potter", - "value": "190" - }, - { - "label": "Harry potter", - "value": "168" - }, - { - "label": "Hentai", - "value": "282" - }, - { - "label": "Marvel", - "value": "194" - }, - { - "label": "Marvel", - "value": "174" - }, - { - "label": "Milf", - "value": "167" - }, - { - "label": "Mj", - "value": "401" - } - ], - "inputType": "Checkbox" - }, - { - "key": "fandoms", - "label": "Фэндом:", - "values": [ - { - "label": "Аватар: Легенда о Корре / Avatar legend of Korra", - "value": "46" - }, - { - "label": "Аватар: Легенда об Аанге / Avatar: The Legend of Aang / Avatar: The Last Airbender", - "value": "45" - }, - { - "label": "Аладдин / Aladdin", - "value": "86" - }, - { - "label": "Алиса в Стране чудес / Alice in Wonderland", - "value": "90" - }, - { - "label": "Американский папаша / American Dad", - "value": "85" - }, - { - "label": "Атака титанов / Атака на титанов / Attack on Titan", - "value": "41" - }, - { - "label": "Блич / Bleach", - "value": "58" - }, - { - "label": "Боевой континент", - "value": "101" - }, - { - "label": "Большой куш / One Piece", - "value": "18" - }, - { - "label": "Боруто: Новое поколение Наруто / Boruto: Naruto Next Generations", - "value": "9" - }, - { - "label": "Бэтмен / The Batman", - "value": "36" - }, - { - "label": "Ведьмак / The Witcher", - "value": "53" - }, - { - "label": "Военная хроника маленькой девочки", - "value": "100" - }, - { - "label": "Волейбол / Haikyu!!", - "value": "37" - }, - { - "label": "Вселенная Марвел / Marvel Universe", - "value": "7" - }, - { - "label": "Вселенная Марвел / Marvel Universe / Marvel Comics", - "value": "52" - }, - { - "label": "Вселенная Стивена", - "value": "61" - }, - { - "label": "Вселенная DC / DC Universe / DC Comics", - "value": "48" - }, - { - "label": "Гарри Поттер / Harry Potter", - "value": "4" - }, - { - "label": "Гоэтия / Гоетия / Yοητεία / Ars Goetia", - "value": "77" - }, - { - "label": "Демоны старшей школы / High School DxD", - "value": "10" - }, - { - "label": "День сурка / Groundhog Day", - "value": "3" - }, - { - "label": "Джессика Джонс / Marvel's Jessica Jones", - "value": "42" - }, - { - "label": "Дисней / The Walt Disney Company", - "value": "74" - }, - { - "label": "Древние свитки: Скайрим / TES: Skyrim", - "value": "15" - }, - { - "label": "Дэдпул / Deadpool", - "value": "22" - }, - { - "label": "Дэнни-призрак / Danny Phantom", - "value": "51" - }, - { - "label": "Железный человек / Iron Man", - "value": "19" - }, - { - "label": "Звёздная принцесса и силы зла / Стар против сил зла / Star vs. The Forces of Evil", - "value": "50" - }, - { - "label": "Звездные Войны / Star Wars", - "value": "43" - }, - { - "label": "Звёздные Войны / Star Wars", - "value": "16" - }, - { - "label": "Игра престолов", - "value": "78" - }, - { - "label": "Касльвания / Castlevania", - "value": "29" - }, - { - "label": "Киберпанк 2077 / Cyberpunk 2077", - "value": "6" - }, - { - "label": "Код Гиас / Code Geass", - "value": "84" - }, - { - "label": "Кольцо Элдена", - "value": "60" - }, - { - "label": "Королевства Сердец / Kingdom Hearts", - "value": "93" - }, - { - "label": "Красавица и чудовище / Beauty and the Beast", - "value": "91" - }, - { - "label": "Красный, Белый, Черный, Желтый / RWBY", - "value": "32" - }, - { - "label": "Кунг фу панда", - "value": "81" - }, - { - "label": "Лига Легенд / League of Legends", - "value": "5" - }, - { - "label": "Люди Икс / X-Men", - "value": "25" - }, - { - "label": "Маг на полную ставку / Quanzhi Fashi", - "value": "30" - }, - { - "label": "Мастера меча онлайн / Sword Art Online / SAO", - "value": "47" - }, - { - "label": "Мир Тьмы / World of Darkness", - "value": "28" - }, - { - "label": "Мой маленький пони / My Little Pony", - "value": "72" - }, - { - "label": "Мой маленький пони: Дружба — это чудо / My Little Pony: Friendship is Magic", - "value": "71" - }, - { - "label": "Моя геройская академия / Boku no Hero Academia", - "value": "8" - }, - { - "label": "Мстители / The Avengers", - "value": "20" - }, - { - "label": "Мстители. Эра Альтрона / The Avengers. Age of Ultron", - "value": "24" - }, - { - "label": "Мулан / Mulan", - "value": "94" - }, - { - "label": "Наруто / Naruto", - "value": "2" - }, - { - "label": "Овервотч", - "value": "79" - }, - { - "label": "Поднятие уровня в одиночку", - "value": "87" - }, - { - "label": "Порновселенная / Porn Universe", - "value": "31" - }, - { - "label": "Прототип / Prototype", - "value": "44" - }, - { - "label": "Рапунцель: Запутанная история / Tangled", - "value": "96" - }, - { - "label": "Розовая пора моей школьной жизни сплошной обман / Yahari Ore no Seishun Love Come wa Machigatteiru", - "value": "14" - }, - { - "label": "Русалочка / The Little Mermaid", - "value": "97" - }, - { - "label": "Сага о Винланде", - "value": "66" - }, - { - "label": "Светлячок / Firefly", - "value": "76" - }, - { - "label": "Сильнейший в истории ученик Кэнити / Shijou Saikyou no Deshi Kenichi", - "value": "13" - }, - { - "label": "Симпсоны / The Simpsons", - "value": "73" - }, - { - "label": "Судьба: Великий Приказ / Fate: Grand Order", - "value": "54" - }, - { - "label": "Супергёрл(телесериал, 2015) / Supergirl", - "value": "95" - }, - { - "label": "Супермен / Superman", - "value": "1" - }, - { - "label": "Теория большого взрыва / The Big Bang Theory", - "value": "75" - }, - { - "label": "Тор / Thor", - "value": "27" - }, - { - "label": "У Коми-сан проблемы с общением / 古見さんは、コミュ症です / Komi Can't Communicate", - "value": "11" - }, - { - "label": "Убийца Акаме / Akame ga Kill", - "value": "40" - }, - { - "label": "Уэнздей / Wednesday", - "value": "26" - }, - { - "label": "Фантастическая четвёрка / Fantastic Four", - "value": "21" - }, - { - "label": "Флэш / The Flash", - "value": "17" - }, - { - "label": "Хвост Феи / Fairy Tail", - "value": "59" - }, - { - "label": "Холодное сердце / Frozen", - "value": "92" - }, - { - "label": "Человек одного удара / Ванпанчмен / One Punch-Man", - "value": "39" - }, - { - "label": "Человек-паук / Spider-Man", - "value": "23" - }, - { - "label": "Чёрный зверь / Чёрный Пёс / Kuroinu", - "value": "35" - }, - { - "label": "Чёрный зверь: Развращение Благородных Воительниц / Black Beast: Corruption of the Noble Warriors", - "value": "34" - }, - { - "label": "Школа мертвецов", - "value": "67" - }, - { - "label": "Школа строгого режима / Prison School", - "value": "12" - }, - { - "label": "Эффект Массы / Mass Effect", - "value": "57" - }, - { - "label": "Юные Титаны / Teen Titans", - "value": "49" - }, - { - "label": "Ars Goetia | Gods and Demons", - "value": "69" - }, - { - "label": "Biohazard", - "value": "99" - }, - { - "label": "CL", - "value": "70" - }, - { - "label": "Daraku Reijou Hakoiri Ojou-sama Netorare Choukyou Kiroku", - "value": "55" - }, - { - "label": "Doom", - "value": "64" - }, - { - "label": "Granblue fantasy", - "value": "88" - }, - { - "label": "Halo", - "value": "80" - }, - { - "label": "Highschool of the Dead/Школа мертвецов", - "value": "68" - }, - { - "label": "JK Bitch ni Shiboraretai", - "value": "56" - }, - { - "label": "Monogatari Series", - "value": "65" - }, - { - "label": "Monster girl quest", - "value": "62" - }, - { - "label": "Over", - "value": "102" - }, - { - "label": "Rapunzel/Рапунцель", - "value": "83" - }, - { - "label": "Resident Evil", - "value": "98" - }, - { - "label": "Solo leveling", - "value": "63" - }, - { - "label": "Tentacle Locker", - "value": "89" - }, - { - "label": "X-COM", - "value": "82" - } - ], - "inputType": "Checkbox" - }, - { - "key": "genres_ex", - "label": "Исключить жанры:", - "values": [ - { - "label": "Анал", - "value": "2" - }, - { - "label": "Бдсм", - "value": "3" - }, - { - "label": "Большая грудь", - "value": "5" - }, - { - "label": "Большая попка", - "value": "6" - }, - { - "label": "Большой член", - "value": "7" - }, - { - "label": "Бондаж", - "value": "8" - }, - { - "label": "В первый раз", - "value": "9" - }, - { - "label": "В цвете", - "value": "10" - }, - { - "label": "Гарем", - "value": "11" - }, - { - "label": "Гендарная интрига", - "value": "12" - }, - { - "label": "Групповой секс", - "value": "13" - }, - { - "label": "Детектив", - "value": "39" - }, - { - "label": "Драма", - "value": "14" - }, - { - "label": "Зрелые женщины (milf)", - "value": "15" - }, - { - "label": "Измена", - "value": "16" - }, - { - "label": "Изнасилование", - "value": "17" - }, - { - "label": "Инцест", - "value": "18" - }, - { - "label": "Исторический", - "value": "19" - }, - { - "label": "Комедия", - "value": "20" - }, - { - "label": "Контроль над разумом", - "value": "35" - }, - { - "label": "Маленькая грудь", - "value": "21" - }, - { - "label": "Мистика", - "value": "40" - }, - { - "label": "Научная фантастика", - "value": "22" - }, - { - "label": "Нетораре", - "value": "23" - }, - { - "label": "Оральный секс", - "value": "24" - }, - { - "label": "Повседневность", - "value": "41" - }, - { - "label": "Приключения", - "value": "38" - }, - { - "label": "Публичный секс", - "value": "33" - }, - { - "label": "Романтика", - "value": "25" - }, - { - "label": "С изображениями", - "value": "36" - }, - { - "label": "Сверхъестественное", - "value": "34" - }, - { - "label": "Смат", - "value": "37" - }, - { - "label": "Тентакли", - "value": "26" - }, - { - "label": "Трагедия", - "value": "27" - }, - { - "label": "Ужасы", - "value": "28" - }, - { - "label": "Фантастика", - "value": "32" - }, - { - "label": "Фэнтези", - "value": "29" - }, - { - "label": "Чикан", - "value": "30" - }, - { - "label": "Этти", - "value": "31" - }, - { - "label": "Ahegao", - "value": "1" - } - ], - "inputType": "Checkbox" - }, - { - "key": "tags_ex", - "label": "Исключить тэги:", - "values": [ - { - "label": "+18", - "value": "141" - }, - { - "label": "18+", - "value": "200" - }, - { - "label": "21+", - "value": "334" - }, - { - "label": "Адекватные главные герои", - "value": "253" - }, - { - "label": "Азартные игры", - "value": "210" - }, - { - "label": "Айдолы", - "value": "364" - }, - { - "label": "Акула", - "value": "53" - }, - { - "label": "Альтернативное развитие событий", - "value": "338" - }, - { - "label": "Аморальный главный герой", - "value": "219" - }, - { - "label": "Анал", - "value": "7" - }, - { - "label": "Анальный секс", - "value": "67" - }, - { - "label": "Ангелы", - "value": "114" - }, - { - "label": "Антигерой", - "value": "226" - }, - { - "label": "Аристократия", - "value": "260" - }, - { - "label": "Артефакт", - "value": "379" - }, - { - "label": "Афродизиак", - "value": "276" - }, - { - "label": "Ахегао", - "value": "240" - }, - { - "label": "Бабушка беременна от внука", - "value": "393" - }, - { - "label": "Бабушка и внук", - "value": "380" - }, - { - "label": "Бдсм", - "value": "131" - }, - { - "label": "Беременность", - "value": "148" - }, - { - "label": "Бесплатно", - "value": "79" - }, - { - "label": "Бесстрашные персонажи", - "value": "339" - }, - { - "label": "Библиотека", - "value": "265" - }, - { - "label": "Бистиалити", - "value": "391" - }, - { - "label": "Битва за трон", - "value": "404" - }, - { - "label": "Близнецы", - "value": "198" - }, - { - "label": "Блондинка", - "value": "91" - }, - { - "label": "Богатые персонажи", - "value": "248" - }, - { - "label": "Боги", - "value": "115" - }, - { - "label": "Боевик", - "value": "252" - }, - { - "label": "Большая грудь", - "value": "33" - }, - { - "label": "Большая попка", - "value": "328" - }, - { - "label": "Большой член", - "value": "76" - }, - { - "label": "Большой член сына", - "value": "396" - }, - { - "label": "Босс и подчиненный", - "value": "330" - }, - { - "label": "Брак", - "value": "182" - }, - { - "label": "Брак по расчёту", - "value": "346" - }, - { - "label": "Брат", - "value": "29" - }, - { - "label": "Брат и сестра", - "value": "30" - }, - { - "label": "Брюнетка", - "value": "28" - }, - { - "label": "Бэтмен", - "value": "369" - }, - { - "label": "Бэтмен", - "value": "170" - }, - { - "label": "В первый раз", - "value": "179" - }, - { - "label": "Вагинальный секс", - "value": "57" - }, - { - "label": "Вагинальный секс", - "value": "171" - }, - { - "label": "Вайурист", - "value": "9" - }, - { - "label": "Вампиры", - "value": "133" - }, - { - "label": "Ван-пис", - "value": "335" - }, - { - "label": "Веб камера", - "value": "289" - }, - { - "label": "Ведьмы", - "value": "232" - }, - { - "label": "Викинги", - "value": "307" - }, - { - "label": "Виртуальная реальность", - "value": "382" - }, - { - "label": "Вирус", - "value": "203" - }, - { - "label": "Внучка", - "value": "189" - }, - { - "label": "Война", - "value": "387" - }, - { - "label": "Воспоминания из прошлого", - "value": "405" - }, - { - "label": "Враги становятся любовниками", - "value": "410" - }, - { - "label": "Время", - "value": "81" - }, - { - "label": "Второй шанс", - "value": "244" - }, - { - "label": "Вуайеризм", - "value": "62" - }, - { - "label": "Выживание", - "value": "135" - }, - { - "label": "Гарем", - "value": "107" - }, - { - "label": "Гарри поттер", - "value": "97" - }, - { - "label": "Гвен", - "value": "402" - }, - { - "label": "Гг имба", - "value": "87" - }, - { - "label": "Генетические модификации", - "value": "314" - }, - { - "label": "Гипноз", - "value": "143" - }, - { - "label": "Главная героиня девушка", - "value": "147" - }, - { - "label": "Главный герой женщина", - "value": "213" - }, - { - "label": "Главный герой извращенец", - "value": "116" - }, - { - "label": "Главный герой мужчина", - "value": "117" - }, - { - "label": "Глубокое горло", - "value": "94" - }, - { - "label": "Гоблины", - "value": "230" - }, - { - "label": "Город", - "value": "139" - }, - { - "label": "Городское фэнтези", - "value": "297" - }, - { - "label": "Грудное молоко", - "value": "225" - }, - { - "label": "Групповой секс", - "value": "72" - }, - { - "label": "Гэнг-бэнг", - "value": "235" - }, - { - "label": "Гяру", - "value": "222" - }, - { - "label": "Двойное проникновение", - "value": "42" - }, - { - "label": "Двойной анал", - "value": "47" - }, - { - "label": "Дворяне", - "value": "246" - }, - { - "label": "Деамоны старший школы", - "value": "291" - }, - { - "label": "Девственница", - "value": "119" - }, - { - "label": "Девушки-монстры", - "value": "223" - }, - { - "label": "Демоны", - "value": "98" - }, - { - "label": "Детектив", - "value": "249" - }, - { - "label": "Дзёсэй", - "value": "259" - }, - { - "label": "Доктор", - "value": "326" - }, - { - "label": "Дом", - "value": "138" - }, - { - "label": "Доминирование", - "value": "18" - }, - { - "label": "Дочь", - "value": "153" - }, - { - "label": "Дочь беременна от отца", - "value": "348" - }, - { - "label": "Древние времена", - "value": "383" - }, - { - "label": "Древний китай", - "value": "261" - }, - { - "label": "Другой мир", - "value": "365" - }, - { - "label": "Дружба", - "value": "325" - }, - { - "label": "Друзья детства", - "value": "183" - }, - { - "label": "Дядя", - "value": "160" - }, - { - "label": "Жена", - "value": "70" - }, - { - "label": "Жена и муж", - "value": "99" - }, - { - "label": "Жена шлюха", - "value": "236" - }, - { - "label": "Женское доминирование", - "value": "100" - }, - { - "label": "Жесткий секс", - "value": "283" - }, - { - "label": "Жёсткий секс", - "value": "101" - }, - { - "label": "Жестокие персонажи", - "value": "254" - }, - { - "label": "Жестокий мир", - "value": "336" - }, - { - "label": "Жестокость", - "value": "123" - }, - { - "label": "Заботливый главный герой", - "value": "340" - }, - { - "label": "Зависимость", - "value": "370" - }, - { - "label": "Заключение", - "value": "196" - }, - { - "label": "Заключённые", - "value": "384" - }, - { - "label": "Замок", - "value": "140" - }, - { - "label": "Запретная любовь", - "value": "273" - }, - { - "label": "Заражение", - "value": "206" - }, - { - "label": "Звёздные войны", - "value": "120" - }, - { - "label": "Зверодевочки", - "value": "158" - }, - { - "label": "Зло", - "value": "343" - }, - { - "label": "Золовка", - "value": "77" - }, - { - "label": "Золотой дождь", - "value": "146" - }, - { - "label": "Зомби апокалипсис", - "value": "241" - }, - { - "label": "Зоофилия", - "value": "144" - }, - { - "label": "Зрелые женщины", - "value": "398" - }, - { - "label": "Игровые элементы", - "value": "385" - }, - { - "label": "Извращения", - "value": "192" - }, - { - "label": "Измена", - "value": "71" - }, - { - "label": "Изменения внешности", - "value": "315" - }, - { - "label": "Изменения личности", - "value": "316" - }, - { - "label": "Изнасилование", - "value": "275" - }, - { - "label": "Изуку мидория", - "value": "337" - }, - { - "label": "Ино", - "value": "127" - }, - { - "label": "Инопланетяне", - "value": "304" - }, - { - "label": "Интересный сюжет", - "value": "349" - }, - { - "label": "Интимные сцены", - "value": "322" - }, - { - "label": "Интриги и заговоры", - "value": "262" - }, - { - "label": "Интроверт", - "value": "38" - }, - { - "label": "Инфекция", - "value": "207" - }, - { - "label": "Инцест", - "value": "35" - }, - { - "label": "Исторический роман", - "value": "406" - }, - { - "label": "Камера", - "value": "92" - }, - { - "label": "Колледж", - "value": "82" - }, - { - "label": "Комикс", - "value": "286" - }, - { - "label": "Контроль", - "value": "19" - }, - { - "label": "Контроль над разумом", - "value": "181" - }, - { - "label": "Контроль разума", - "value": "65" - }, - { - "label": "Кончил внутрь", - "value": "221" - }, - { - "label": "Королевская семья", - "value": "358" - }, - { - "label": "Коррупция", - "value": "49" - }, - { - "label": "Космос", - "value": "204" - }, - { - "label": "Красивая главная героиня", - "value": "255" - }, - { - "label": "Красивые женщины", - "value": "321" - }, - { - "label": "Красивый главный герой", - "value": "266" - }, - { - "label": "Ксенофилия", - "value": "386" - }, - { - "label": "Кулинария", - "value": "362" - }, - { - "label": "Культвация", - "value": "86" - }, - { - "label": "Кунилингус", - "value": "152" - }, - { - "label": "Кушина", - "value": "399" - }, - { - "label": "Лактация", - "value": "11" - }, - { - "label": "Лесби", - "value": "408" - }, - { - "label": "Лишение девственности", - "value": "212" - }, - { - "label": "Лоли", - "value": "218" - }, - { - "label": "Лунатизм", - "value": "279" - }, - { - "label": "Любовь", - "value": "89" - }, - { - "label": "Магический мир", - "value": "357" - }, - { - "label": "Магия", - "value": "80" - }, - { - "label": "Мама", - "value": "3" - }, - { - "label": "Мама беременна от сына", - "value": "274" - }, - { - "label": "Мама и дочь", - "value": "163" - }, - { - "label": "Мама и сын", - "value": "1" - }, - { - "label": "Мама супермена", - "value": "39" - }, - { - "label": "Манипуляция временем", - "value": "292" - }, - { - "label": "Марвел", - "value": "290" - }, - { - "label": "Марвел", - "value": "173" - }, - { - "label": "Марти стью", - "value": "102" - }, - { - "label": "Массаж", - "value": "224" - }, - { - "label": "Мастурбация", - "value": "63" - }, - { - "label": "Мать", - "value": "239" - }, - { - "label": "Мать и дочь", - "value": "381" - }, - { - "label": "Мать и сын", - "value": "237" - }, - { - "label": "Мафия", - "value": "256" - }, - { - "label": "Мачеха", - "value": "197" - }, - { - "label": "Мачеха беременна от сына", - "value": "395" - }, - { - "label": "Мачеха и сын", - "value": "394" - }, - { - "label": "Медсестра", - "value": "341" - }, - { - "label": "Межрассовый", - "value": "54" - }, - { - "label": "Месть", - "value": "306" - }, - { - "label": "Меха", - "value": "268" - }, - { - "label": "Ми", - "value": "243" - }, - { - "label": "Милф", - "value": "34" - }, - { - "label": "Милф", - "value": "180" - }, - { - "label": "Минет", - "value": "52" - }, - { - "label": "Мистика", - "value": "250" - }, - { - "label": "Младшая сестра", - "value": "154" - }, - { - "label": "Много спермы", - "value": "409" - }, - { - "label": "Модель", - "value": "324" - }, - { - "label": "Монстры", - "value": "333" - }, - { - "label": "Мошеничество", - "value": "44" - }, - { - "label": "Мужская беременность", - "value": "363" - }, - { - "label": "Мужчина протагонист", - "value": "108" - }, - { - "label": "Музыка", - "value": "331" - }, - { - "label": "Мэри съюха", - "value": "309" - }, - { - "label": "Наруко", - "value": "400" - }, - { - "label": "Наруто", - "value": "46" - }, - { - "label": "Насилие", - "value": "128" - }, - { - "label": "Насилие и жестокость", - "value": "193" - }, - { - "label": "Научный эксперимент", - "value": "313" - }, - { - "label": "Нежить", - "value": "373" - }, - { - "label": "Некромантия", - "value": "298" - }, - { - "label": "Ненормативная лексика", - "value": "124" - }, - { - "label": "Нетораре", - "value": "69" - }, - { - "label": "Нетори", - "value": "284" - }, - { - "label": "Нижнее бельё", - "value": "392" - }, - { - "label": "Ниндзя", - "value": "296" - }, - { - "label": "Ношеные трусики", - "value": "166" - }, - { - "label": "Нудизм", - "value": "156" - }, - { - "label": "Няня", - "value": "88" - }, - { - "label": "Обмен женами", - "value": "78" - }, - { - "label": "Оборотни", - "value": "136" - }, - { - "label": "Обратный гарем", - "value": "214" - }, - { - "label": "Одержимость", - "value": "345" - }, - { - "label": "Омегаверс", - "value": "368" - }, - { - "label": "Оплодотворение", - "value": "157" - }, - { - "label": "Оральный секс", - "value": "10" - }, - { - "label": "Оргия", - "value": "356" - }, - { - "label": "Орки", - "value": "388" - }, - { - "label": "От слабого к сильному", - "value": "351" - }, - { - "label": "Отец", - "value": "2" - }, - { - "label": "Отец делится с сыном", - "value": "6" - }, - { - "label": "Отец и дочь", - "value": "205" - }, - { - "label": "Отец куколд", - "value": "272" - }, - { - "label": "Офис", - "value": "234" - }, - { - "label": "Падчерица", - "value": "271" - }, - { - "label": "Пайзури", - "value": "195" - }, - { - "label": "Папа и дочь", - "value": "360" - }, - { - "label": "Паразиты", - "value": "208" - }, - { - "label": "Параллельный мир", - "value": "320" - }, - { - "label": "Пародия", - "value": "371" - }, - { - "label": "Первый раз", - "value": "159" - }, - { - "label": "Перемещение в другой мир", - "value": "347" - }, - { - "label": "Перемещение во времени", - "value": "245" - }, - { - "label": "Перерождение", - "value": "109" - }, - { - "label": "Перерождение в злодея", - "value": "202" - }, - { - "label": "Пирсинг", - "value": "145" - }, - { - "label": "Писатель", - "value": "267" - }, - { - "label": "Планомерное развитие событий", - "value": "350" - }, - { - "label": "Повседневность", - "value": "247" - }, - { - "label": "Подглядывание", - "value": "280" - }, - { - "label": "Подчинение", - "value": "106" - }, - { - "label": "Подчинение и унижение", - "value": "211" - }, - { - "label": "Поедание киски", - "value": "26" - }, - { - "label": "Покемоны", - "value": "132" - }, - { - "label": "Покорная", - "value": "8" - }, - { - "label": "Полигамия", - "value": "352" - }, - { - "label": "Половое воспитание", - "value": "37" - }, - { - "label": "Полулюди", - "value": "231" - }, - { - "label": "Попаданец", - "value": "103" - }, - { - "label": "Попадание в книгу", - "value": "361" - }, - { - "label": "Порка", - "value": "20" - }, - { - "label": "Порно", - "value": "278" - }, - { - "label": "Постапокалипсис", - "value": "332" - }, - { - "label": "Потеря девственности", - "value": "142" - }, - { - "label": "Похищение", - "value": "161" - }, - { - "label": "Преданные любовный интерес", - "value": "407" - }, - { - "label": "Призраки", - "value": "412" - }, - { - "label": "Приключения", - "value": "134" - }, - { - "label": "Принуждение", - "value": "66" - }, - { - "label": "Психология", - "value": "238" - }, - { - "label": "Публично", - "value": "85" - }, - { - "label": "Публичный секс", - "value": "233" - }, - { - "label": "Раб", - "value": "353" - }, - { - "label": "Рабы", - "value": "308" - }, - { - "label": "Разват", - "value": "58" - }, - { - "label": "Разврат", - "value": "64" - }, - { - "label": "Райзен", - "value": "95" - }, - { - "label": "Раса инопланетных космических лесбиянок", - "value": "294" - }, - { - "label": "Религия", - "value": "403" - }, - { - "label": "Рестленг", - "value": "84" - }, - { - "label": "Риас гремори", - "value": "389" - }, - { - "label": "Романтика", - "value": "178" - }, - { - "label": "Рыжий", - "value": "90" - }, - { - "label": "С", - "value": "413" - }, - { - "label": "Сакура", - "value": "126" - }, - { - "label": "Самолет", - "value": "93" - }, - { - "label": "Санса старк", - "value": "277" - }, - { - "label": "Санта", - "value": "372" - }, - { - "label": "Свадьба", - "value": "73" - }, - { - "label": "Сверхсила", - "value": "228" - }, - { - "label": "Сверхъестественное", - "value": "319" - }, - { - "label": "Свингеры", - "value": "201" - }, - { - "label": "Свободные отношения", - "value": "186" - }, - { - "label": "Связывание", - "value": "137" - }, - { - "label": "Сёдзе", - "value": "264" - }, - { - "label": "Секс", - "value": "21" - }, - { - "label": "Секс без проникновения", - "value": "68" - }, - { - "label": "Секс втроем", - "value": "43" - }, - { - "label": "Секс игрушки", - "value": "59" - }, - { - "label": "Секс рабыня", - "value": "55" - }, - { - "label": "Секс с монстрами", - "value": "56" - }, - { - "label": "Секс с учителем", - "value": "184" - }, - { - "label": "Секса будет много", - "value": "151" - }, - { - "label": "Сексуальное желание", - "value": "209" - }, - { - "label": "Селфцест", - "value": "397" - }, - { - "label": "Семья", - "value": "5" - }, - { - "label": "Сестра", - "value": "31" - }, - { - "label": "Сестра беременна от брата", - "value": "355" - }, - { - "label": "Сильный с самого начала", - "value": "112" - }, - { - "label": "Симбиоз", - "value": "50" - }, - { - "label": "Сирена", - "value": "51" - }, - { - "label": "Система", - "value": "104" - }, - { - "label": "Сиськи", - "value": "285" - }, - { - "label": "Сквирт", - "value": "164" - }, - { - "label": "Скрытый секс", - "value": "287" - }, - { - "label": "Служанка", - "value": "215" - }, - { - "label": "Соб", - "value": "281" - }, - { - "label": "Соблазнение", - "value": "162" - }, - { - "label": "Современность", - "value": "217" - }, - { - "label": "Соколиный Глаз", - "value": "176" - }, - { - "label": "Соперничество", - "value": "216" - }, - { - "label": "Соседи", - "value": "61" - }, - { - "label": "Соседка", - "value": "312" - }, - { - "label": "Сперма", - "value": "229" - }, - { - "label": "Сперма на лицо", - "value": "199" - }, - { - "label": "Спящие", - "value": "187" - }, - { - "label": "Старшая сестра", - "value": "311" - }, - { - "label": "Стеб", - "value": "111" - }, - { - "label": "Студенты", - "value": "177" - }, - { - "label": "Суккуб", - "value": "390" - }, - { - "label": "Супергерои", - "value": "305" - }, - { - "label": "Суперспособности", - "value": "300" - }, - { - "label": "Сын", - "value": "4" - }, - { - "label": "Твинцест", - "value": "188" - }, - { - "label": "Темное фэнтези", - "value": "293" - }, - { - "label": "Тентакли", - "value": "303" - }, - { - "label": "Тетя", - "value": "113" - }, - { - "label": "Тетя беременна от племянника", - "value": "376" - }, - { - "label": "Тетя и племянник", - "value": "377" - }, - { - "label": "Техника", - "value": "302" - }, - { - "label": "Технологии", - "value": "301" - }, - { - "label": "Тёща", - "value": "270" - }, - { - "label": "Тиран", - "value": "310" - }, - { - "label": "Трагическое прошлое", - "value": "251" - }, - { - "label": "Трансмиграция", - "value": "269" - }, - { - "label": "Трансформация", - "value": "317" - }, - { - "label": "Триллер", - "value": "344" - }, - { - "label": "Трусики", - "value": "165" - }, - { - "label": "Убийства", - "value": "258" - }, - { - "label": "Удача", - "value": "299" - }, - { - "label": "Ужасы", - "value": "375" - }, - { - "label": "Улучшение тела", - "value": "288" - }, - { - "label": "Умная главная героиня", - "value": "242" - }, - { - "label": "Умные персонажи", - "value": "257" - }, - { - "label": "Умный главный герой", - "value": "354" - }, - { - "label": "Университет", - "value": "323" - }, - { - "label": "Ученик", - "value": "83" - }, - { - "label": "Ф", - "value": "149" - }, - { - "label": "Фанатичная любовь", - "value": "366" - }, - { - "label": "Фанаты", - "value": "367" - }, - { - "label": "Фантастика", - "value": "295" - }, - { - "label": "Фанфик", - "value": "40" - }, - { - "label": "Фелляция", - "value": "22" - }, - { - "label": "Ферма", - "value": "191" - }, - { - "label": "Фетиш", - "value": "60" - }, - { - "label": "Флэш", - "value": "121" - }, - { - "label": "Футанария", - "value": "150" - }, - { - "label": "Фэнтези", - "value": "359" - }, - { - "label": "Хентай", - "value": "75" - }, - { - "label": "Хината", - "value": "110" - }, - { - "label": "Холодная главная героиня", - "value": "263" - }, - { - "label": "Черная вдова", - "value": "220" - }, - { - "label": "Черная Вдова", - "value": "175" - }, - { - "label": "Черный юмор", - "value": "374" - }, - { - "label": "Читерство", - "value": "45" - }, - { - "label": "Чтение мыслей", - "value": "227" - }, - { - "label": "Чудовища", - "value": "378" - }, - { - "label": "Шантаж", - "value": "129" - }, - { - "label": "Школа", - "value": "118" - }, - { - "label": "Школьная жизнь", - "value": "318" - }, - { - "label": "Шлюха", - "value": "32" - }, - { - "label": "Шоу-бизнес", - "value": "329" - }, - { - "label": "Шоу-бизнес", - "value": "172" - }, - { - "label": "Эксгибиционизм", - "value": "74" - }, - { - "label": "Элементы бдсм", - "value": "185" - }, - { - "label": "Эмма уотсон", - "value": "342" - }, - { - "label": "Эмма Уотсон", - "value": "169" - }, - { - "label": "Эротика", - "value": "36" - }, - { - "label": "Этти", - "value": "327" - }, - { - "label": "Юмор", - "value": "105" - }, - { - "label": "Яндере", - "value": "155" - }, - { - "label": "Bl", - "value": "125" - }, - { - "label": "Dc", - "value": "411" - }, - { - "label": "Gl", - "value": "96" - }, - { - "label": "Harry potter", - "value": "190" - }, - { - "label": "Harry potter", - "value": "168" - }, - { - "label": "Hentai", - "value": "282" - }, - { - "label": "Marvel", - "value": "194" - }, - { - "label": "Marvel", - "value": "174" - }, - { - "label": "Milf", - "value": "167" - }, - { - "label": "Mj", - "value": "401" - } - ], - "inputType": "Checkbox" - }, - { - "key": "fandoms_ex", - "label": "Исключить фэндомы:", - "values": [ - { - "label": "Аватар: Легенда о Корре / Avatar legend of Korra", - "value": "46" - }, - { - "label": "Аватар: Легенда об Аанге / Avatar: The Legend of Aang / Avatar: The Last Airbender", - "value": "45" - }, - { - "label": "Аладдин / Aladdin", - "value": "86" - }, - { - "label": "Алиса в Стране чудес / Alice in Wonderland", - "value": "90" - }, - { - "label": "Американский папаша / American Dad", - "value": "85" - }, - { - "label": "Атака титанов / Атака на титанов / Attack on Titan", - "value": "41" - }, - { - "label": "Блич / Bleach", - "value": "58" - }, - { - "label": "Боевой континент", - "value": "101" - }, - { - "label": "Большой куш / One Piece", - "value": "18" - }, - { - "label": "Боруто: Новое поколение Наруто / Boruto: Naruto Next Generations", - "value": "9" - }, - { - "label": "Бэтмен / The Batman", - "value": "36" - }, - { - "label": "Ведьмак / The Witcher", - "value": "53" - }, - { - "label": "Военная хроника маленькой девочки", - "value": "100" - }, - { - "label": "Волейбол / Haikyu!!", - "value": "37" - }, - { - "label": "Вселенная Марвел / Marvel Universe", - "value": "7" - }, - { - "label": "Вселенная Марвел / Marvel Universe / Marvel Comics", - "value": "52" - }, - { - "label": "Вселенная Стивена", - "value": "61" - }, - { - "label": "Вселенная DC / DC Universe / DC Comics", - "value": "48" - }, - { - "label": "Гарри Поттер / Harry Potter", - "value": "4" - }, - { - "label": "Гоэтия / Гоетия / Yοητεία / Ars Goetia", - "value": "77" - }, - { - "label": "Демоны старшей школы / High School DxD", - "value": "10" - }, - { - "label": "День сурка / Groundhog Day", - "value": "3" - }, - { - "label": "Джессика Джонс / Marvel's Jessica Jones", - "value": "42" - }, - { - "label": "Дисней / The Walt Disney Company", - "value": "74" - }, - { - "label": "Древние свитки: Скайрим / TES: Skyrim", - "value": "15" - }, - { - "label": "Дэдпул / Deadpool", - "value": "22" - }, - { - "label": "Дэнни-призрак / Danny Phantom", - "value": "51" - }, - { - "label": "Железный человек / Iron Man", - "value": "19" - }, - { - "label": "Звёздная принцесса и силы зла / Стар против сил зла / Star vs. The Forces of Evil", - "value": "50" - }, - { - "label": "Звездные Войны / Star Wars", - "value": "43" - }, - { - "label": "Звёздные Войны / Star Wars", - "value": "16" - }, - { - "label": "Игра престолов", - "value": "78" - }, - { - "label": "Касльвания / Castlevania", - "value": "29" - }, - { - "label": "Киберпанк 2077 / Cyberpunk 2077", - "value": "6" - }, - { - "label": "Код Гиас / Code Geass", - "value": "84" - }, - { - "label": "Кольцо Элдена", - "value": "60" - }, - { - "label": "Королевства Сердец / Kingdom Hearts", - "value": "93" - }, - { - "label": "Красавица и чудовище / Beauty and the Beast", - "value": "91" - }, - { - "label": "Красный, Белый, Черный, Желтый / RWBY", - "value": "32" - }, - { - "label": "Кунг фу панда", - "value": "81" - }, - { - "label": "Лига Легенд / League of Legends", - "value": "5" - }, - { - "label": "Люди Икс / X-Men", - "value": "25" - }, - { - "label": "Маг на полную ставку / Quanzhi Fashi", - "value": "30" - }, - { - "label": "Мастера меча онлайн / Sword Art Online / SAO", - "value": "47" - }, - { - "label": "Мир Тьмы / World of Darkness", - "value": "28" - }, - { - "label": "Мой маленький пони / My Little Pony", - "value": "72" - }, - { - "label": "Мой маленький пони: Дружба — это чудо / My Little Pony: Friendship is Magic", - "value": "71" - }, - { - "label": "Моя геройская академия / Boku no Hero Academia", - "value": "8" - }, - { - "label": "Мстители / The Avengers", - "value": "20" - }, - { - "label": "Мстители. Эра Альтрона / The Avengers. Age of Ultron", - "value": "24" - }, - { - "label": "Мулан / Mulan", - "value": "94" - }, - { - "label": "Наруто / Naruto", - "value": "2" - }, - { - "label": "Овервотч", - "value": "79" - }, - { - "label": "Поднятие уровня в одиночку", - "value": "87" - }, - { - "label": "Порновселенная / Porn Universe", - "value": "31" - }, - { - "label": "Прототип / Prototype", - "value": "44" - }, - { - "label": "Рапунцель: Запутанная история / Tangled", - "value": "96" - }, - { - "label": "Розовая пора моей школьной жизни сплошной обман / Yahari Ore no Seishun Love Come wa Machigatteiru", - "value": "14" - }, - { - "label": "Русалочка / The Little Mermaid", - "value": "97" - }, - { - "label": "Сага о Винланде", - "value": "66" - }, - { - "label": "Светлячок / Firefly", - "value": "76" - }, - { - "label": "Сильнейший в истории ученик Кэнити / Shijou Saikyou no Deshi Kenichi", - "value": "13" - }, - { - "label": "Симпсоны / The Simpsons", - "value": "73" - }, - { - "label": "Судьба: Великий Приказ / Fate: Grand Order", - "value": "54" - }, - { - "label": "Супергёрл(телесериал, 2015) / Supergirl", - "value": "95" - }, - { - "label": "Супермен / Superman", - "value": "1" - }, - { - "label": "Теория большого взрыва / The Big Bang Theory", - "value": "75" - }, - { - "label": "Тор / Thor", - "value": "27" - }, - { - "label": "У Коми-сан проблемы с общением / 古見さんは、コミュ症です / Komi Can't Communicate", - "value": "11" - }, - { - "label": "Убийца Акаме / Akame ga Kill", - "value": "40" - }, - { - "label": "Уэнздей / Wednesday", - "value": "26" - }, - { - "label": "Фантастическая четвёрка / Fantastic Four", - "value": "21" - }, - { - "label": "Флэш / The Flash", - "value": "17" - }, - { - "label": "Хвост Феи / Fairy Tail", - "value": "59" - }, - { - "label": "Холодное сердце / Frozen", - "value": "92" - }, - { - "label": "Человек одного удара / Ванпанчмен / One Punch-Man", - "value": "39" - }, - { - "label": "Человек-паук / Spider-Man", - "value": "23" - }, - { - "label": "Чёрный зверь / Чёрный Пёс / Kuroinu", - "value": "35" - }, - { - "label": "Чёрный зверь: Развращение Благородных Воительниц / Black Beast: Corruption of the Noble Warriors", - "value": "34" - }, - { - "label": "Школа мертвецов", - "value": "67" - }, - { - "label": "Школа строгого режима / Prison School", - "value": "12" - }, - { - "label": "Эффект Массы / Mass Effect", - "value": "57" - }, - { - "label": "Юные Титаны / Teen Titans", - "value": "49" - }, - { - "label": "Ars Goetia | Gods and Demons", - "value": "69" - }, - { - "label": "Biohazard", - "value": "99" - }, - { - "label": "CL", - "value": "70" - }, - { - "label": "Daraku Reijou Hakoiri Ojou-sama Netorare Choukyou Kiroku", - "value": "55" - }, - { - "label": "Doom", - "value": "64" - }, - { - "label": "Granblue fantasy", - "value": "88" - }, - { - "label": "Halo", - "value": "80" - }, - { - "label": "Highschool of the Dead/Школа мертвецов", - "value": "68" - }, - { - "label": "JK Bitch ni Shiboraretai", - "value": "56" - }, - { - "label": "Monogatari Series", - "value": "65" - }, - { - "label": "Monster girl quest", - "value": "62" - }, - { - "label": "Over", - "value": "102" - }, - { - "label": "Rapunzel/Рапунцель", - "value": "83" - }, - { - "label": "Resident Evil", - "value": "98" - }, - { - "label": "Solo leveling", - "value": "63" - }, - { - "label": "Tentacle Locker", - "value": "89" - }, - { - "label": "X-COM", - "value": "82" - } - ], - "inputType": "Checkbox" - }, - { - "key": "atmosphere", - "label": "Атмосфера:", - "values": [ - { - "label": "Неважно", - "value": "0" - }, - { - "label": "Позитивная", - "value": "1" - }, - { - "label": "Dark", - "value": "2" - } - ], - "inputType": "Picker" - }, - { - "key": "adult", - "label": "Возрастные ограничения:", - "values": [ - { - "label": "Все", - "value": "0" - }, - { - "label": "Только 18+", - "value": "2" - }, - { - "label": "Убрать 18+", - "value": "1" - } - ], - "inputType": "Picker" - } - ] - } -] \ No newline at end of file diff --git a/template.min.ts b/template.min.ts deleted file mode 100644 index 9800bf3..0000000 --- a/template.min.ts +++ /dev/null @@ -1,54 +0,0 @@ -// import { load as parseHTML } from "cheerio"; -// import dayjs from 'dayjs'; -import { fetchFile, fetchApi } from "@libs/fetch"; -import { Novel, Plugin, Chapter } from "@typings/plugin"; -// import { parseMadaraDate } from "@libs/parseMadaraDate"; -// import { isUrlAbsolute } from '@libs/isAbsoluteUrl'; -// import { showToast } from "@libs/showToast"; -// import { Filter, FilterInputs } from "@libs/filterInputs"; -// import { NovelStatus } from '@libs/novelStatus'; -// import { defaultCover } from "@libs/defaultCover"; - - -export const id = ""; -export const name = "Source name"; -export const icon = ""; -export const version = "0.0.0"; -export const site = ""; -// export const filters: Filter[] = []; - -export const popularNovels: Plugin.popularNovels = async function ( - page, - { filters, showLatestNovels } -) { - const novels: Novel.Item[] = []; - - return novels; -}; - - -export const parseNovelAndChapters: Plugin.parseNovelAndChapters = - async function (novelUrl) { - const novel: Novel.instance = { - url: novelUrl, - chapters: [], - }; - - return novel; - }; - -export const parseChapter: Plugin.parseChapter = async function (chapterUrl) { - const chapterText = ""; - - return chapterText; -}; - -export const searchNovels: Plugin.searchNovels = async (searchTerm) => { - const novels: Novel.Item[] = []; - - return novels; -}; - -export const fetchImage: Plugin.fetchImage = async (url) => { - return await fetchFile(url, {}); -}; diff --git a/template.ts b/template.ts deleted file mode 100644 index 801eb25..0000000 --- a/template.ts +++ /dev/null @@ -1,90 +0,0 @@ -// import { load as parseHTML } from "cheerio"; -// import dayjs from 'dayjs'; -import { fetchFile, fetchApi } from "@libs/fetch"; -import { Novel, Plugin, Chapter } from "@typings/plugin"; -// import { parseMadaraDate } from "@libs/parseMadaraDate"; -// import { isUrlAbsolute } from '@libs/isAbsoluteUrl'; -// import { showToast } from "@libs/showToast"; -// import { Filter, FilterInputs } from "@libs/filterInputs"; -// import { NovelStatus } from '@libs/novelStatus'; -// import { defaultCover } from "@libs/defaultCover"; - -export const id = ""; // string and must be unique -export const name = "Source name"; -export const icon = ""; // The relative path to the icon without @icons . For example: 'src/vi/hakolightnovel/icon.png' -export const version = "0.0.0"; // xx.xx.xx -export const site = ""; // the link to the site -// export const filters: Filter[] = []; - -export const popularNovels: Plugin.popularNovels = async function ( - page, - { filters, showLatestNovels } -) { - const novels: Novel.Item[] = []; - /* - Do something.... - novel = { - name: '', - url: '', must be absolute - cover: '', - } - novels.push(novel); - */ - return novels; -}; - -export const parseNovelAndChapters: Plugin.parseNovelAndChapters = - async function (novelUrl) { - const novel: Novel.instance = { - url: novelUrl, - chapters: [], - }; - - /** - * novel.name = ''; - * novel.cover = ''; - * novel.summary = ''; - * novel.author = ''; - * novel.artist = ''; - * novel.status = ''; - * novel.genres = ''; join by commas. For example: 'romcom, action, school' - */ - - /* - Do something.... - chapter = { - name: '', chapter name should contain vol, chap num (eg: vol 1 chap 11.5: abcxyz) - it helps a alot in migation - url: '', must be absoulute - releaseTime: '', - } - novel.chapters.push(chapter); - */ - - return novel; - }; - -export const parseChapter: Plugin.parseChapter = async function (chapterUrl) { - // Do something... - const chapterText = ""; - return chapterText; -}; - -export const searchNovels: Plugin.searchNovels = async function (searchTerm) { - const novels: Novel.Item[] = []; - /* - Do something.... - const novel = { - name: '', - url: '', must be absolute - cover: '', - } - novels.push(novel); - */ - return novels; -}; - -export const fetchImage: Plugin.fetchImage = async function (url) { - // Some site cant fetch images normally (maybe need some headers) - // Must return base64 of image - return await fetchFile(url, {}); -}; diff --git a/test_web/api/plugins.ts b/test_web/api/plugins.ts index e0011ca..f43c0a0 100644 --- a/test_web/api/plugins.ts +++ b/test_web/api/plugins.ts @@ -24,9 +24,9 @@ export const all_plugins = (): PluginList => { const requirePath = `@plugins/${languageEnglish.toLowerCase()}/${ plugin.split(".")[0] }`; - const instance = require(requirePath); + const instance = require(requirePath).default; const { id, name, version, icon } = instance; - const info: Plugin.Info = { + const info: Plugin.PluginItem = { id, name, lang: languageNative, @@ -42,21 +42,20 @@ export const all_plugins = (): PluginList => { const getPlugin = async ( requirePath: string -): Promise => { - const plugin = await require(requirePath); +): Promise => { + const plugin = await require(requirePath).default; if (isPlugin(plugin)) return plugin; return null; }; +export const getFilter = async ( + pluginRequirePath: string +) => (await getPlugin(pluginRequirePath))?.filters; + export const popularNovels = async ( pluginRequirePath: string, - options: Plugin.Options -) => { - const plugin = await getPlugin(pluginRequirePath); - if (!plugin) return null; - const popularNovels = await plugin.popularNovels(1, options); - return popularNovels; -}; + options: Plugin.PopularNovelsOptions +) => (await getPlugin(pluginRequirePath))?.popularNovels(1, options); export const searchNovels = async ( pluginRequirePath: string, diff --git a/test_web/index.html b/test_web/index.html index 177f13a..a23278c 100644 --- a/test_web/index.html +++ b/test_web/index.html @@ -7,6 +7,7 @@ + Testing plugin @@ -30,9 +31,31 @@
+
popularNovels - +
Loading...
@@ -46,7 +69,7 @@
- +
@@ -62,7 +85,7 @@
- +
@@ -82,7 +105,7 @@
- +
@@ -100,7 +123,7 @@
- +
@@ -111,7 +134,9 @@
- + + + \ No newline at end of file diff --git a/test_web/static/css/index.css b/test_web/static/css/index.css index bc2b149..d2a612e 100644 --- a/test_web/static/css/index.css +++ b/test_web/static/css/index.css @@ -1,3 +1,8 @@ +*{ + margin: 0; + padding: 0; + box-sizing: border-box; +} .navbar{ width: 1080px; align-items: center; @@ -119,3 +124,7 @@ grid-template-columns: 15rem 15rem 15rem 15rem; grid-gap: 0, 0; } + +.select-option-text{ + padding-left: 1rem; +} \ No newline at end of file diff --git a/test_web/static/css/mdb5.css b/test_web/static/css/mdb5.css new file mode 100644 index 0000000..982382c --- /dev/null +++ b/test_web/static/css/mdb5.css @@ -0,0 +1,19301 @@ +/*! + * + * Version: MDB Pro 6.4.2 + * + * Copyright: Material Design for Bootstrap + * https://mdbootstrap.com/ + * + * If you don't have a PRO license, you can purchase one here: + * https://mdbootstrap.com/docs/standard/pro/ + * + * Enterprise quotations, standard license & license customization: + * https://mdbootstrap.com/general/license/ + * + * Documentation: + * https://mdbootstrap.com/docs/standard/ + * + * Support: + * https://mdbootstrap.com/support/ + * + * Contact: + * contact@mdbootstrap.com + * + */ + :root { + --mdb-red: #f44336; + --mdb-pink: #e91e63; + --mdb-purple: #9c27b0; + --mdb-indigo: #3f51b5; + --mdb-blue: #2196f3; + --mdb-cyan: #00bcd4; + --mdb-teal: #009688; + --mdb-green: #4caf50; + --mdb-yellow: #ffeb3b; + --mdb-orange: #ff9800; + --mdb-white: #fff; + --mdb-black: #000; + --mdb-gray: #757575; + --mdb-gray-dark: #4f4f4f; + --mdb-gray-50: #fbfbfb; + --mdb-gray-100: #f5f5f5; + --mdb-gray-200: #eee; + --mdb-gray-300: #e0e0e0; + --mdb-gray-400: #bdbdbd; + --mdb-gray-500: #9e9e9e; + --mdb-gray-600: #757575; + --mdb-gray-700: #616161; + --mdb-gray-800: #4f4f4f; + --mdb-gray-900: #262626; + --mdb-primary: #3b71ca; + --mdb-secondary: #9fa6b2; + --mdb-success: #14a44d; + --mdb-danger: #dc4c64; + --mdb-warning: #e4a11b; + --mdb-info: #54b4d3; + --mdb-light: #fbfbfb; + --mdb-dark: #332d2d; + --mdb-primary-rgb: 59,113,202; + --mdb-secondary-rgb: 159,166,178; + --mdb-success-rgb: 20,164,77; + --mdb-danger-rgb: 220,76,100; + --mdb-warning-rgb: 228,161,27; + --mdb-info-rgb: 84,180,211; + --mdb-light-rgb: 251,251,251; + --mdb-dark-rgb: 51,45,45; + --mdb-white-rgb: 255,255,255; + --mdb-black-rgb: 0,0,0; + --mdb-body-color-rgb: 79,79,79; + --mdb-body-bg-rgb: 255,255,255; + --mdb-font-sans-serif: system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue","Noto Sans","Liberation Sans",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji"; + --mdb-font-monospace: SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace; + --mdb-gradient: linear-gradient(180deg,hsla(0,0%,100%,0.15),hsla(0,0%,100%,0)); + --mdb-body-font-family: var(--mdb-font-roboto); + --mdb-body-font-size: 1rem; + --mdb-body-font-weight: 400; + --mdb-body-line-height: 1.6; + --mdb-body-color: #4f4f4f; + --mdb-body-bg: #fff; + --mdb-border-width: 1px; + --mdb-border-style: solid; + --mdb-border-color: #e0e0e0; + --mdb-border-color-translucent: rgba(0,0,0,0.175); + --mdb-border-radius: 0.25rem; + --mdb-border-radius-sm: 0.25rem; + --mdb-border-radius-lg: 0.5rem; + --mdb-border-radius-xl: 1rem; + --mdb-border-radius-2xl: 2rem; + --mdb-border-radius-pill: 50rem; + --mdb-link-color: #3b71ca; + --mdb-link-hover-color: #386bc0; + --mdb-code-color: #e91e63; + --mdb-highlight-bg: #fff9c4 +} + +*,:after,:before { + box-sizing: border-box +} + +@media(prefers-reduced-motion:no-preference) { + :root { + scroll-behavior: smooth + } +} + +body { + margin: 0; + font-family: var(--mdb-body-font-family); + font-size: var(--mdb-body-font-size); + font-weight: var(--mdb-body-font-weight); + line-height: var(--mdb-body-line-height); + color: var(--mdb-body-color); + text-align: var(--mdb-body-text-align); + background-color: var(--mdb-body-bg); + -webkit-text-size-adjust: 100%; + -webkit-tap-highlight-color: rgba(0,0,0,0) +} + +hr { + margin: 1rem 0; + color: inherit; + border: 0; + border-top: 1px solid; + opacity: .25 +} + +.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6 { + margin-top: 0; + margin-bottom: .5rem; + font-weight: 500; + line-height: 1.2 +} + +.h1,h1 { + font-size: calc(1.375rem + 1.5vw) +} + +@media(min-width: 1200px) { + .h1,h1 { + font-size:2.5rem + } +} + +.h2,h2 { + font-size: calc(1.325rem + .9vw) +} + +@media(min-width: 1200px) { + .h2,h2 { + font-size:2rem + } +} + +.h3,h3 { + font-size: calc(1.3rem + .6vw) +} + +@media(min-width: 1200px) { + .h3,h3 { + font-size:1.75rem + } +} + +.h4,h4 { + font-size: calc(1.275rem + .3vw) +} + +@media(min-width: 1200px) { + .h4,h4 { + font-size:1.5rem + } +} + +.h5,h5 { + font-size: 1.25rem +} + +.h6,h6 { + font-size: 1rem +} + +p { + margin-top: 0; + margin-bottom: 1rem +} + +abbr[title] { + -webkit-text-decoration: underline dotted; + text-decoration: underline dotted; + cursor: help; + -webkit-text-decoration-skip-ink: none; + text-decoration-skip-ink: none +} + +address { + margin-bottom: 1rem; + font-style: normal; + line-height: inherit +} + +ol,ul { + padding-left: 2rem +} + +dl,ol,ul { + margin-top: 0; + margin-bottom: 1rem +} + +ol ol,ol ul,ul ol,ul ul { + margin-bottom: 0 +} + +dt { + font-weight: 700 +} + +dd { + margin-bottom: .5rem; + margin-left: 0 +} + +blockquote { + margin: 0 0 1rem +} + +b,strong { + font-weight: bolder +} + +.small,small { + font-size: .875em +} + +.mark,mark { + padding: .1875em; + background-color: var(--mdb-highlight-bg) +} + +sub,sup { + position: relative; + font-size: .75em; + line-height: 0; + vertical-align: baseline +} + +sub { + bottom: -.25em +} + +sup { + top: -.5em +} + +a { + color: var(--mdb-link-color) +} + +a,a:hover { + text-decoration: none +} + +a:hover { + color: var(--mdb-link-hover-color) +} + +a:not([href]):not([class]),a:not([href]):not([class]):hover { + color: inherit; + text-decoration: none +} + +code,kbd,pre,samp { + font-family: var(--mdb-font-monospace); + font-size: 1em +} + +pre { + display: block; + margin-top: 0; + margin-bottom: 1rem; + overflow: auto; + font-size: .875em +} + +pre code { + font-size: inherit; + color: inherit; + word-break: normal +} + +code { + font-size: .875em; + color: var(--mdb-code-color); + word-wrap: break-word +} + +a>code { + color: inherit +} + +kbd { + padding: .1875rem .375rem; + font-size: .875em; + color: var(--mdb-body-bg); + background-color: var(--mdb-body-color); + border-radius: .25rem +} + +kbd kbd { + padding: 0; + font-size: 1em +} + +figure { + margin: 0 0 1rem +} + +img,svg { + vertical-align: middle +} + +table { + caption-side: bottom; + border-collapse: collapse +} + +caption { + padding-top: 1rem; + padding-bottom: 1rem; + color: #757575; + text-align: left +} + +th { + text-align: inherit; + text-align: -webkit-match-parent +} + +tbody,td,tfoot,th,thead,tr { + border: 0 solid; + border-color: inherit +} + +label { + display: inline-block +} + +button { + border-radius: 0 +} + +button:focus:not(:focus-visible) { + outline: 0 +} + +button,input,optgroup,select,textarea { + margin: 0; + font-family: inherit; + font-size: inherit; + line-height: inherit +} + +button,select { + text-transform: none +} + +[role=button] { + cursor: pointer +} + +select { + word-wrap: normal +} + +select:disabled { + opacity: 1 +} + +[list]:not([type=date]):not([type=datetime-local]):not([type=month]):not([type=week]):not([type=time])::-webkit-calendar-picker-indicator { + display: none!important +} + +[type=button],[type=reset],[type=submit],button { + -webkit-appearance: button +} + +[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled),button:not(:disabled) { + cursor: pointer +} + +::-moz-focus-inner { + padding: 0; + border-style: none +} + +textarea { + resize: vertical +} + +fieldset { + min-width: 0; + padding: 0; + margin: 0; + border: 0 +} + +legend { + float: left; + width: 100%; + padding: 0; + margin-bottom: .5rem; + font-size: calc(1.275rem + .3vw); + line-height: inherit +} + +@media(min-width: 1200px) { + legend { + font-size:1.5rem + } +} + +legend+* { + clear: left +} + +::-webkit-datetime-edit-day-field,::-webkit-datetime-edit-fields-wrapper,::-webkit-datetime-edit-hour-field,::-webkit-datetime-edit-minute,::-webkit-datetime-edit-month-field,::-webkit-datetime-edit-text,::-webkit-datetime-edit-year-field { + padding: 0 +} + +::-webkit-inner-spin-button { + height: auto +} + +[type=search] { + outline-offset: -2px; + -webkit-appearance: textfield +} + +/*!rtl:raw: +[type="tel"], +[type="url"], +[type="email"], +[type="number"] { + direction: ltr; +} +*/ +::-webkit-search-decoration { + -webkit-appearance: none +} + +::-webkit-color-swatch-wrapper { + padding: 0 +} + +::file-selector-button { + font: inherit; + -webkit-appearance: button +} + +output { + display: inline-block +} + +iframe { + border: 0 +} + +summary { + display: list-item; + cursor: pointer +} + +progress { + vertical-align: baseline +} + +[hidden] { + display: none!important +} + +.lead { + font-size: 1.25rem; + font-weight: 300 +} + +.display-1 { + font-size: calc(1.625rem + 4.5vw); + font-weight: 300; + line-height: 1.2 +} + +@media(min-width: 1200px) { + .display-1 { + font-size:5rem + } +} + +.display-2 { + font-size: calc(1.575rem + 3.9vw); + font-weight: 300; + line-height: 1.2 +} + +@media(min-width: 1200px) { + .display-2 { + font-size:4.5rem + } +} + +.display-3 { + font-size: calc(1.525rem + 3.3vw); + font-weight: 300; + line-height: 1.2 +} + +@media(min-width: 1200px) { + .display-3 { + font-size:4rem + } +} + +.display-4 { + font-size: calc(1.475rem + 2.7vw); + font-weight: 300; + line-height: 1.2 +} + +@media(min-width: 1200px) { + .display-4 { + font-size:3.5rem + } +} + +.display-5 { + font-size: calc(1.425rem + 2.1vw); + font-weight: 300; + line-height: 1.2 +} + +@media(min-width: 1200px) { + .display-5 { + font-size:3rem + } +} + +.display-6 { + font-size: calc(1.375rem + 1.5vw); + font-weight: 300; + line-height: 1.2 +} + +@media(min-width: 1200px) { + .display-6 { + font-size:2.5rem + } +} + +.list-inline,.list-unstyled { + padding-left: 0; + list-style: none +} + +.list-inline-item { + display: inline-block +} + +.list-inline-item:not(:last-child) { + margin-right: .5rem +} + +.initialism { + font-size: .875em; + text-transform: uppercase +} + +.blockquote { + margin-bottom: 1rem; + font-size: 1.25rem +} + +.blockquote>:last-child { + margin-bottom: 0 +} + +.blockquote-footer { + margin-top: -1rem; + margin-bottom: 1rem; + font-size: .875em; + color: #757575 +} + +.blockquote-footer:before { + content: "— " +} + +.img-fluid,.img-thumbnail { + max-width: 100%; + height: auto +} + +.img-thumbnail { + padding: .25rem; + background-color: #fff; + border: 1px solid var(--mdb-border-color); + border-radius: .25rem; + box-shadow: 0 .125rem .25rem rgba(0,0,0,.075) +} + +.figure { + display: inline-block +} + +.figure-img { + margin-bottom: .5rem; + line-height: 1 +} + +.figure-caption { + font-size: .875em; + color: #757575 +} + +.container,.container-fluid,.container-lg,.container-md,.container-sm,.container-xl,.container-xxl { + --mdb-gutter-x: 1.5rem; + --mdb-gutter-y: 0; + width: 100%; + padding-right: calc(var(--mdb-gutter-x)*0.5); + padding-left: calc(var(--mdb-gutter-x)*0.5); + margin-right: auto; + margin-left: auto +} + +@media(min-width: 576px) { + .container,.container-sm { + max-width:540px + } +} + +@media(min-width: 768px) { + .container,.container-md,.container-sm { + max-width:720px + } +} + +@media(min-width: 992px) { + .container,.container-lg,.container-md,.container-sm { + max-width:960px + } +} + +@media(min-width: 1200px) { + .container,.container-lg,.container-md,.container-sm,.container-xl { + max-width:1140px + } +} + +@media(min-width: 1400px) { + .container,.container-lg,.container-md,.container-sm,.container-xl,.container-xxl { + max-width:1320px + } +} + +.row { + --mdb-gutter-x: 1.5rem; + --mdb-gutter-y: 0; + display: flex; + flex-wrap: wrap; + margin-top: calc(var(--mdb-gutter-y)*-1); + margin-right: calc(var(--mdb-gutter-x)*-0.5); + margin-left: calc(var(--mdb-gutter-x)*-0.5) +} + +.row>* { + flex-shrink: 0; + width: 100%; + max-width: 100%; + padding-right: calc(var(--mdb-gutter-x)*0.5); + padding-left: calc(var(--mdb-gutter-x)*0.5); + margin-top: var(--mdb-gutter-y) +} + +.col { + flex: 1 0 0% +} + +.row-cols-auto>* { + flex: 0 0 auto; + width: auto +} + +.row-cols-1>* { + flex: 0 0 auto; + width: 100% +} + +.row-cols-2>* { + flex: 0 0 auto; + width: 50% +} + +.row-cols-3>* { + flex: 0 0 auto; + width: 33.3333333333% +} + +.row-cols-4>* { + flex: 0 0 auto; + width: 25% +} + +.row-cols-5>* { + flex: 0 0 auto; + width: 20% +} + +.row-cols-6>* { + flex: 0 0 auto; + width: 16.6666666667% +} + +.col-auto { + flex: 0 0 auto; + width: auto +} + +.col-1 { + flex: 0 0 auto; + width: 8.33333333% +} + +.col-2 { + flex: 0 0 auto; + width: 16.66666667% +} + +.col-3 { + flex: 0 0 auto; + width: 25% +} + +.col-4 { + flex: 0 0 auto; + width: 33.33333333% +} + +.col-5 { + flex: 0 0 auto; + width: 41.66666667% +} + +.col-6 { + flex: 0 0 auto; + width: 50% +} + +.col-7 { + flex: 0 0 auto; + width: 58.33333333% +} + +.col-8 { + flex: 0 0 auto; + width: 66.66666667% +} + +.col-9 { + flex: 0 0 auto; + width: 75% +} + +.col-10 { + flex: 0 0 auto; + width: 83.33333333% +} + +.col-11 { + flex: 0 0 auto; + width: 91.66666667% +} + +.col-12 { + flex: 0 0 auto; + width: 100% +} + +.offset-1 { + margin-left: 8.33333333% +} + +.offset-2 { + margin-left: 16.66666667% +} + +.offset-3 { + margin-left: 25% +} + +.offset-4 { + margin-left: 33.33333333% +} + +.offset-5 { + margin-left: 41.66666667% +} + +.offset-6 { + margin-left: 50% +} + +.offset-7 { + margin-left: 58.33333333% +} + +.offset-8 { + margin-left: 66.66666667% +} + +.offset-9 { + margin-left: 75% +} + +.offset-10 { + margin-left: 83.33333333% +} + +.offset-11 { + margin-left: 91.66666667% +} + +.g-0,.gx-0 { + --mdb-gutter-x: 0 +} + +.g-0,.gy-0 { + --mdb-gutter-y: 0 +} + +.g-1,.gx-1 { + --mdb-gutter-x: 0.25rem +} + +.g-1,.gy-1 { + --mdb-gutter-y: 0.25rem +} + +.g-2,.gx-2 { + --mdb-gutter-x: 0.5rem +} + +.g-2,.gy-2 { + --mdb-gutter-y: 0.5rem +} + +.g-3,.gx-3 { + --mdb-gutter-x: 1rem +} + +.g-3,.gy-3 { + --mdb-gutter-y: 1rem +} + +.g-4,.gx-4 { + --mdb-gutter-x: 1.5rem +} + +.g-4,.gy-4 { + --mdb-gutter-y: 1.5rem +} + +.g-5,.gx-5 { + --mdb-gutter-x: 3rem +} + +.g-5,.gy-5 { + --mdb-gutter-y: 3rem +} + +@media(min-width: 576px) { + .col-sm { + flex:1 0 0% + } + + .row-cols-sm-auto>* { + flex: 0 0 auto; + width: auto + } + + .row-cols-sm-1>* { + flex: 0 0 auto; + width: 100% + } + + .row-cols-sm-2>* { + flex: 0 0 auto; + width: 50% + } + + .row-cols-sm-3>* { + flex: 0 0 auto; + width: 33.3333333333% + } + + .row-cols-sm-4>* { + flex: 0 0 auto; + width: 25% + } + + .row-cols-sm-5>* { + flex: 0 0 auto; + width: 20% + } + + .row-cols-sm-6>* { + flex: 0 0 auto; + width: 16.6666666667% + } + + .col-sm-auto { + flex: 0 0 auto; + width: auto + } + + .col-sm-1 { + flex: 0 0 auto; + width: 8.33333333% + } + + .col-sm-2 { + flex: 0 0 auto; + width: 16.66666667% + } + + .col-sm-3 { + flex: 0 0 auto; + width: 25% + } + + .col-sm-4 { + flex: 0 0 auto; + width: 33.33333333% + } + + .col-sm-5 { + flex: 0 0 auto; + width: 41.66666667% + } + + .col-sm-6 { + flex: 0 0 auto; + width: 50% + } + + .col-sm-7 { + flex: 0 0 auto; + width: 58.33333333% + } + + .col-sm-8 { + flex: 0 0 auto; + width: 66.66666667% + } + + .col-sm-9 { + flex: 0 0 auto; + width: 75% + } + + .col-sm-10 { + flex: 0 0 auto; + width: 83.33333333% + } + + .col-sm-11 { + flex: 0 0 auto; + width: 91.66666667% + } + + .col-sm-12 { + flex: 0 0 auto; + width: 100% + } + + .offset-sm-0 { + margin-left: 0 + } + + .offset-sm-1 { + margin-left: 8.33333333% + } + + .offset-sm-2 { + margin-left: 16.66666667% + } + + .offset-sm-3 { + margin-left: 25% + } + + .offset-sm-4 { + margin-left: 33.33333333% + } + + .offset-sm-5 { + margin-left: 41.66666667% + } + + .offset-sm-6 { + margin-left: 50% + } + + .offset-sm-7 { + margin-left: 58.33333333% + } + + .offset-sm-8 { + margin-left: 66.66666667% + } + + .offset-sm-9 { + margin-left: 75% + } + + .offset-sm-10 { + margin-left: 83.33333333% + } + + .offset-sm-11 { + margin-left: 91.66666667% + } + + .g-sm-0,.gx-sm-0 { + --mdb-gutter-x: 0 + } + + .g-sm-0,.gy-sm-0 { + --mdb-gutter-y: 0 + } + + .g-sm-1,.gx-sm-1 { + --mdb-gutter-x: 0.25rem + } + + .g-sm-1,.gy-sm-1 { + --mdb-gutter-y: 0.25rem + } + + .g-sm-2,.gx-sm-2 { + --mdb-gutter-x: 0.5rem + } + + .g-sm-2,.gy-sm-2 { + --mdb-gutter-y: 0.5rem + } + + .g-sm-3,.gx-sm-3 { + --mdb-gutter-x: 1rem + } + + .g-sm-3,.gy-sm-3 { + --mdb-gutter-y: 1rem + } + + .g-sm-4,.gx-sm-4 { + --mdb-gutter-x: 1.5rem + } + + .g-sm-4,.gy-sm-4 { + --mdb-gutter-y: 1.5rem + } + + .g-sm-5,.gx-sm-5 { + --mdb-gutter-x: 3rem + } + + .g-sm-5,.gy-sm-5 { + --mdb-gutter-y: 3rem + } +} + +@media(min-width: 768px) { + .col-md { + flex:1 0 0% + } + + .row-cols-md-auto>* { + flex: 0 0 auto; + width: auto + } + + .row-cols-md-1>* { + flex: 0 0 auto; + width: 100% + } + + .row-cols-md-2>* { + flex: 0 0 auto; + width: 50% + } + + .row-cols-md-3>* { + flex: 0 0 auto; + width: 33.3333333333% + } + + .row-cols-md-4>* { + flex: 0 0 auto; + width: 25% + } + + .row-cols-md-5>* { + flex: 0 0 auto; + width: 20% + } + + .row-cols-md-6>* { + flex: 0 0 auto; + width: 16.6666666667% + } + + .col-md-auto { + flex: 0 0 auto; + width: auto + } + + .col-md-1 { + flex: 0 0 auto; + width: 8.33333333% + } + + .col-md-2 { + flex: 0 0 auto; + width: 16.66666667% + } + + .col-md-3 { + flex: 0 0 auto; + width: 25% + } + + .col-md-4 { + flex: 0 0 auto; + width: 33.33333333% + } + + .col-md-5 { + flex: 0 0 auto; + width: 41.66666667% + } + + .col-md-6 { + flex: 0 0 auto; + width: 50% + } + + .col-md-7 { + flex: 0 0 auto; + width: 58.33333333% + } + + .col-md-8 { + flex: 0 0 auto; + width: 66.66666667% + } + + .col-md-9 { + flex: 0 0 auto; + width: 75% + } + + .col-md-10 { + flex: 0 0 auto; + width: 83.33333333% + } + + .col-md-11 { + flex: 0 0 auto; + width: 91.66666667% + } + + .col-md-12 { + flex: 0 0 auto; + width: 100% + } + + .offset-md-0 { + margin-left: 0 + } + + .offset-md-1 { + margin-left: 8.33333333% + } + + .offset-md-2 { + margin-left: 16.66666667% + } + + .offset-md-3 { + margin-left: 25% + } + + .offset-md-4 { + margin-left: 33.33333333% + } + + .offset-md-5 { + margin-left: 41.66666667% + } + + .offset-md-6 { + margin-left: 50% + } + + .offset-md-7 { + margin-left: 58.33333333% + } + + .offset-md-8 { + margin-left: 66.66666667% + } + + .offset-md-9 { + margin-left: 75% + } + + .offset-md-10 { + margin-left: 83.33333333% + } + + .offset-md-11 { + margin-left: 91.66666667% + } + + .g-md-0,.gx-md-0 { + --mdb-gutter-x: 0 + } + + .g-md-0,.gy-md-0 { + --mdb-gutter-y: 0 + } + + .g-md-1,.gx-md-1 { + --mdb-gutter-x: 0.25rem + } + + .g-md-1,.gy-md-1 { + --mdb-gutter-y: 0.25rem + } + + .g-md-2,.gx-md-2 { + --mdb-gutter-x: 0.5rem + } + + .g-md-2,.gy-md-2 { + --mdb-gutter-y: 0.5rem + } + + .g-md-3,.gx-md-3 { + --mdb-gutter-x: 1rem + } + + .g-md-3,.gy-md-3 { + --mdb-gutter-y: 1rem + } + + .g-md-4,.gx-md-4 { + --mdb-gutter-x: 1.5rem + } + + .g-md-4,.gy-md-4 { + --mdb-gutter-y: 1.5rem + } + + .g-md-5,.gx-md-5 { + --mdb-gutter-x: 3rem + } + + .g-md-5,.gy-md-5 { + --mdb-gutter-y: 3rem + } +} + +@media(min-width: 992px) { + .col-lg { + flex:1 0 0% + } + + .row-cols-lg-auto>* { + flex: 0 0 auto; + width: auto + } + + .row-cols-lg-1>* { + flex: 0 0 auto; + width: 100% + } + + .row-cols-lg-2>* { + flex: 0 0 auto; + width: 50% + } + + .row-cols-lg-3>* { + flex: 0 0 auto; + width: 33.3333333333% + } + + .row-cols-lg-4>* { + flex: 0 0 auto; + width: 25% + } + + .row-cols-lg-5>* { + flex: 0 0 auto; + width: 20% + } + + .row-cols-lg-6>* { + flex: 0 0 auto; + width: 16.6666666667% + } + + .col-lg-auto { + flex: 0 0 auto; + width: auto + } + + .col-lg-1 { + flex: 0 0 auto; + width: 8.33333333% + } + + .col-lg-2 { + flex: 0 0 auto; + width: 16.66666667% + } + + .col-lg-3 { + flex: 0 0 auto; + width: 25% + } + + .col-lg-4 { + flex: 0 0 auto; + width: 33.33333333% + } + + .col-lg-5 { + flex: 0 0 auto; + width: 41.66666667% + } + + .col-lg-6 { + flex: 0 0 auto; + width: 50% + } + + .col-lg-7 { + flex: 0 0 auto; + width: 58.33333333% + } + + .col-lg-8 { + flex: 0 0 auto; + width: 66.66666667% + } + + .col-lg-9 { + flex: 0 0 auto; + width: 75% + } + + .col-lg-10 { + flex: 0 0 auto; + width: 83.33333333% + } + + .col-lg-11 { + flex: 0 0 auto; + width: 91.66666667% + } + + .col-lg-12 { + flex: 0 0 auto; + width: 100% + } + + .offset-lg-0 { + margin-left: 0 + } + + .offset-lg-1 { + margin-left: 8.33333333% + } + + .offset-lg-2 { + margin-left: 16.66666667% + } + + .offset-lg-3 { + margin-left: 25% + } + + .offset-lg-4 { + margin-left: 33.33333333% + } + + .offset-lg-5 { + margin-left: 41.66666667% + } + + .offset-lg-6 { + margin-left: 50% + } + + .offset-lg-7 { + margin-left: 58.33333333% + } + + .offset-lg-8 { + margin-left: 66.66666667% + } + + .offset-lg-9 { + margin-left: 75% + } + + .offset-lg-10 { + margin-left: 83.33333333% + } + + .offset-lg-11 { + margin-left: 91.66666667% + } + + .g-lg-0,.gx-lg-0 { + --mdb-gutter-x: 0 + } + + .g-lg-0,.gy-lg-0 { + --mdb-gutter-y: 0 + } + + .g-lg-1,.gx-lg-1 { + --mdb-gutter-x: 0.25rem + } + + .g-lg-1,.gy-lg-1 { + --mdb-gutter-y: 0.25rem + } + + .g-lg-2,.gx-lg-2 { + --mdb-gutter-x: 0.5rem + } + + .g-lg-2,.gy-lg-2 { + --mdb-gutter-y: 0.5rem + } + + .g-lg-3,.gx-lg-3 { + --mdb-gutter-x: 1rem + } + + .g-lg-3,.gy-lg-3 { + --mdb-gutter-y: 1rem + } + + .g-lg-4,.gx-lg-4 { + --mdb-gutter-x: 1.5rem + } + + .g-lg-4,.gy-lg-4 { + --mdb-gutter-y: 1.5rem + } + + .g-lg-5,.gx-lg-5 { + --mdb-gutter-x: 3rem + } + + .g-lg-5,.gy-lg-5 { + --mdb-gutter-y: 3rem + } +} + +@media(min-width: 1200px) { + .col-xl { + flex:1 0 0% + } + + .row-cols-xl-auto>* { + flex: 0 0 auto; + width: auto + } + + .row-cols-xl-1>* { + flex: 0 0 auto; + width: 100% + } + + .row-cols-xl-2>* { + flex: 0 0 auto; + width: 50% + } + + .row-cols-xl-3>* { + flex: 0 0 auto; + width: 33.3333333333% + } + + .row-cols-xl-4>* { + flex: 0 0 auto; + width: 25% + } + + .row-cols-xl-5>* { + flex: 0 0 auto; + width: 20% + } + + .row-cols-xl-6>* { + flex: 0 0 auto; + width: 16.6666666667% + } + + .col-xl-auto { + flex: 0 0 auto; + width: auto + } + + .col-xl-1 { + flex: 0 0 auto; + width: 8.33333333% + } + + .col-xl-2 { + flex: 0 0 auto; + width: 16.66666667% + } + + .col-xl-3 { + flex: 0 0 auto; + width: 25% + } + + .col-xl-4 { + flex: 0 0 auto; + width: 33.33333333% + } + + .col-xl-5 { + flex: 0 0 auto; + width: 41.66666667% + } + + .col-xl-6 { + flex: 0 0 auto; + width: 50% + } + + .col-xl-7 { + flex: 0 0 auto; + width: 58.33333333% + } + + .col-xl-8 { + flex: 0 0 auto; + width: 66.66666667% + } + + .col-xl-9 { + flex: 0 0 auto; + width: 75% + } + + .col-xl-10 { + flex: 0 0 auto; + width: 83.33333333% + } + + .col-xl-11 { + flex: 0 0 auto; + width: 91.66666667% + } + + .col-xl-12 { + flex: 0 0 auto; + width: 100% + } + + .offset-xl-0 { + margin-left: 0 + } + + .offset-xl-1 { + margin-left: 8.33333333% + } + + .offset-xl-2 { + margin-left: 16.66666667% + } + + .offset-xl-3 { + margin-left: 25% + } + + .offset-xl-4 { + margin-left: 33.33333333% + } + + .offset-xl-5 { + margin-left: 41.66666667% + } + + .offset-xl-6 { + margin-left: 50% + } + + .offset-xl-7 { + margin-left: 58.33333333% + } + + .offset-xl-8 { + margin-left: 66.66666667% + } + + .offset-xl-9 { + margin-left: 75% + } + + .offset-xl-10 { + margin-left: 83.33333333% + } + + .offset-xl-11 { + margin-left: 91.66666667% + } + + .g-xl-0,.gx-xl-0 { + --mdb-gutter-x: 0 + } + + .g-xl-0,.gy-xl-0 { + --mdb-gutter-y: 0 + } + + .g-xl-1,.gx-xl-1 { + --mdb-gutter-x: 0.25rem + } + + .g-xl-1,.gy-xl-1 { + --mdb-gutter-y: 0.25rem + } + + .g-xl-2,.gx-xl-2 { + --mdb-gutter-x: 0.5rem + } + + .g-xl-2,.gy-xl-2 { + --mdb-gutter-y: 0.5rem + } + + .g-xl-3,.gx-xl-3 { + --mdb-gutter-x: 1rem + } + + .g-xl-3,.gy-xl-3 { + --mdb-gutter-y: 1rem + } + + .g-xl-4,.gx-xl-4 { + --mdb-gutter-x: 1.5rem + } + + .g-xl-4,.gy-xl-4 { + --mdb-gutter-y: 1.5rem + } + + .g-xl-5,.gx-xl-5 { + --mdb-gutter-x: 3rem + } + + .g-xl-5,.gy-xl-5 { + --mdb-gutter-y: 3rem + } +} + +@media(min-width: 1400px) { + .col-xxl { + flex:1 0 0% + } + + .row-cols-xxl-auto>* { + flex: 0 0 auto; + width: auto + } + + .row-cols-xxl-1>* { + flex: 0 0 auto; + width: 100% + } + + .row-cols-xxl-2>* { + flex: 0 0 auto; + width: 50% + } + + .row-cols-xxl-3>* { + flex: 0 0 auto; + width: 33.3333333333% + } + + .row-cols-xxl-4>* { + flex: 0 0 auto; + width: 25% + } + + .row-cols-xxl-5>* { + flex: 0 0 auto; + width: 20% + } + + .row-cols-xxl-6>* { + flex: 0 0 auto; + width: 16.6666666667% + } + + .col-xxl-auto { + flex: 0 0 auto; + width: auto + } + + .col-xxl-1 { + flex: 0 0 auto; + width: 8.33333333% + } + + .col-xxl-2 { + flex: 0 0 auto; + width: 16.66666667% + } + + .col-xxl-3 { + flex: 0 0 auto; + width: 25% + } + + .col-xxl-4 { + flex: 0 0 auto; + width: 33.33333333% + } + + .col-xxl-5 { + flex: 0 0 auto; + width: 41.66666667% + } + + .col-xxl-6 { + flex: 0 0 auto; + width: 50% + } + + .col-xxl-7 { + flex: 0 0 auto; + width: 58.33333333% + } + + .col-xxl-8 { + flex: 0 0 auto; + width: 66.66666667% + } + + .col-xxl-9 { + flex: 0 0 auto; + width: 75% + } + + .col-xxl-10 { + flex: 0 0 auto; + width: 83.33333333% + } + + .col-xxl-11 { + flex: 0 0 auto; + width: 91.66666667% + } + + .col-xxl-12 { + flex: 0 0 auto; + width: 100% + } + + .offset-xxl-0 { + margin-left: 0 + } + + .offset-xxl-1 { + margin-left: 8.33333333% + } + + .offset-xxl-2 { + margin-left: 16.66666667% + } + + .offset-xxl-3 { + margin-left: 25% + } + + .offset-xxl-4 { + margin-left: 33.33333333% + } + + .offset-xxl-5 { + margin-left: 41.66666667% + } + + .offset-xxl-6 { + margin-left: 50% + } + + .offset-xxl-7 { + margin-left: 58.33333333% + } + + .offset-xxl-8 { + margin-left: 66.66666667% + } + + .offset-xxl-9 { + margin-left: 75% + } + + .offset-xxl-10 { + margin-left: 83.33333333% + } + + .offset-xxl-11 { + margin-left: 91.66666667% + } + + .g-xxl-0,.gx-xxl-0 { + --mdb-gutter-x: 0 + } + + .g-xxl-0,.gy-xxl-0 { + --mdb-gutter-y: 0 + } + + .g-xxl-1,.gx-xxl-1 { + --mdb-gutter-x: 0.25rem + } + + .g-xxl-1,.gy-xxl-1 { + --mdb-gutter-y: 0.25rem + } + + .g-xxl-2,.gx-xxl-2 { + --mdb-gutter-x: 0.5rem + } + + .g-xxl-2,.gy-xxl-2 { + --mdb-gutter-y: 0.5rem + } + + .g-xxl-3,.gx-xxl-3 { + --mdb-gutter-x: 1rem + } + + .g-xxl-3,.gy-xxl-3 { + --mdb-gutter-y: 1rem + } + + .g-xxl-4,.gx-xxl-4 { + --mdb-gutter-x: 1.5rem + } + + .g-xxl-4,.gy-xxl-4 { + --mdb-gutter-y: 1.5rem + } + + .g-xxl-5,.gx-xxl-5 { + --mdb-gutter-x: 3rem + } + + .g-xxl-5,.gy-xxl-5 { + --mdb-gutter-y: 3rem + } +} + +.table { + --mdb-table-color: var(--mdb-body-color); + --mdb-table-bg: transparent; + --mdb-table-border-color: var(--mdb-border-color); + --mdb-table-accent-bg: transparent; + --mdb-table-striped-color: var(--mdb-body-color); + --mdb-table-striped-bg: rgba(0,0,0,0.02); + --mdb-table-active-color: var(--mdb-body-color); + --mdb-table-active-bg: rgba(0,0,0,0.1); + --mdb-table-hover-color: var(--mdb-body-color); + --mdb-table-hover-bg: rgba(0,0,0,0.025); + width: 100%; + margin-bottom: 1rem; + color: var(--mdb-table-color); + vertical-align: top; + border-color: var(--mdb-table-border-color) +} + +.table>:not(caption)>*>* { + padding: 1rem 1.4rem; + background-color: var(--mdb-table-bg); + border-bottom-width: 1px; + box-shadow: inset 0 0 0 9999px var(--mdb-table-accent-bg) +} + +.table>tbody { + vertical-align: inherit +} + +.table>thead { + vertical-align: bottom +} + +.table-group-divider { + border-top: 2px solid inherit +} + +.caption-top { + caption-side: top +} + +.table-sm>:not(caption)>*>* { + padding: .5rem +} + +.table-bordered>:not(caption)>* { + border-width: 1px 0 +} + +.table-bordered>:not(caption)>*>* { + border-width: 0 1px +} + +.table-borderless>:not(caption)>*>* { + border-bottom-width: 0 +} + +.table-borderless>:not(:first-child) { + border-top-width: 0 +} + +.table-striped-columns>:not(caption)>tr>:nth-child(2n),.table-striped>tbody>tr:nth-of-type(odd)>* { + --mdb-table-accent-bg: var(--mdb-table-striped-bg); + color: var(--mdb-table-striped-color) +} + +.table-active { + --mdb-table-accent-bg: var(--mdb-table-active-bg); + color: var(--mdb-table-active-color) +} + +.table-hover>tbody>tr:hover>* { + --mdb-table-accent-bg: var(--mdb-table-hover-bg); + color: var(--mdb-table-hover-color) +} + +.table-responsive { + overflow-x: auto; + -webkit-overflow-scrolling: touch +} + +@media(max-width: 575.98px) { + .table-responsive-sm { + overflow-x:auto; + -webkit-overflow-scrolling: touch + } +} + +@media(max-width: 767.98px) { + .table-responsive-md { + overflow-x:auto; + -webkit-overflow-scrolling: touch + } +} + +@media(max-width: 991.98px) { + .table-responsive-lg { + overflow-x:auto; + -webkit-overflow-scrolling: touch + } +} + +@media(max-width: 1199.98px) { + .table-responsive-xl { + overflow-x:auto; + -webkit-overflow-scrolling: touch + } +} + +@media(max-width: 1399.98px) { + .table-responsive-xxl { + overflow-x:auto; + -webkit-overflow-scrolling: touch + } +} + +.form-label { + margin-bottom: .5rem; + color: rgba(0,0,0,.6) +} + +.col-form-label { + padding-top: calc(.375rem + 1px); + padding-bottom: calc(.375rem + 1px); + margin-bottom: 0; + font-size: inherit; + line-height: 1.6; + color: rgba(0,0,0,.6) +} + +.col-form-label-lg { + padding-top: calc(.5rem + 1px); + padding-bottom: calc(.5rem + 1px); + font-size: 1rem +} + +.col-form-label-sm { + padding-top: calc(.25rem + 1px); + padding-bottom: calc(.25rem + 1px); + font-size: .775rem +} + +.form-text { + margin-top: .25rem; + font-size: .875em; + color: #757575 +} + +.form-control { + display: block; + width: 100%; + padding: .375rem .75rem; + font-size: 1rem; + font-weight: 400; + line-height: 1.6; + color: #4f4f4f; + background-color: #fff; + background-clip: padding-box; + border: 1px solid #bdbdbd; + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + border-radius: .25rem; + box-shadow: inset 0 1px 2px rgba(0,0,0,.075); + transition: all .2s linear +} + +@media(prefers-reduced-motion:reduce) { + .form-control { + transition: none + } +} + +.form-control[type=file] { + overflow: hidden +} + +.form-control[type=file]:not(:disabled):not([readonly]) { + cursor: pointer +} + +.form-control:focus { + color: #4f4f4f; + background-color: #fff; + outline: 0; + box-shadow: inset 0 1px 2px rgba(0,0,0,.075),0 0 0 .25rem rgba(59,113,202,.25) +} + +.form-control::-webkit-date-and-time-value { + height: 1.6em +} + +.form-control::-moz-placeholder { + color: #757575; + opacity: 1 +} + +.form-control::placeholder { + color: #757575; + opacity: 1 +} + +.form-control:disabled { + background-color: #eee; + opacity: 1 +} + +.form-control::file-selector-button { + padding: .375rem .75rem; + margin: -.375rem -.75rem; + -webkit-margin-end: .75rem; + margin-inline-end:.75rem;color: #4f4f4f; + background-color: #eee; + pointer-events: none; + border: 0 solid; + border-color: inherit; + border-inline-end-width:1px;border-radius: 0; + transition: color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out +} + +@media(prefers-reduced-motion:reduce) { + .form-control::file-selector-button { + transition: none + } +} + +.form-control:hover:not(:disabled):not([readonly])::file-selector-button { + background-color: #e2e2e2 +} + +.form-control-plaintext { + display: block; + width: 100%; + padding: .375rem 0; + margin-bottom: 0; + line-height: 1.6; + color: #4f4f4f; + background-color: transparent; + border: solid transparent; + border-width: 1px 0 +} + +.form-control-plaintext:focus { + outline: 0 +} + +.form-control-plaintext.form-control-lg,.form-control-plaintext.form-control-sm { + padding-right: 0; + padding-left: 0 +} + +.form-control-sm { + min-height: calc(1.6em + .5rem + 2px); + padding: .25rem .5rem; + font-size: .775rem; + border-radius: .25rem +} + +.form-control-sm::file-selector-button { + padding: .25rem .5rem; + margin: -.25rem -.5rem; + -webkit-margin-end: .5rem; + margin-inline-end:.5rem} + +.form-control-lg { + min-height: calc(1.6em + 1rem + 2px); + padding: .5rem 1rem; + font-size: 1rem; + border-radius: .5rem +} + +.form-control-lg::file-selector-button { + padding: .5rem 1rem; + margin: -.5rem -1rem; + -webkit-margin-end: 1rem; + margin-inline-end:1rem} + +textarea.form-control { + min-height: calc(1.6em + .75rem + 2px) +} + +textarea.form-control-sm { + min-height: calc(1.6em + .5rem + 2px) +} + +textarea.form-control-lg { + min-height: calc(1.6em + 1rem + 2px) +} + +.form-control-color { + width: 3rem; + height: calc(1.6em + .75rem + 2px); + padding: .375rem +} + +.form-control-color:not(:disabled):not([readonly]) { + cursor: pointer +} + +.form-control-color::-moz-color-swatch { + border: 0!important; + border-radius: .25rem +} + +.form-control-color::-webkit-color-swatch { + border-radius: .25rem +} + +.form-control-color.form-control-sm { + height: calc(1.6em + .5rem + 2px) +} + +.form-control-color.form-control-lg { + height: calc(1.6em + 1rem + 2px) +} + +.form-select { + display: block; + width: 100%; + padding: .375rem 2.25rem .375rem .75rem; + -moz-padding-start: calc(.75rem - 3px); + font-size: 1rem; + font-weight: 400; + line-height: 1.6; + color: #4f4f4f; + background-color: #fff; + background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath fill='none' stroke='%234f4f4f' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M2 5l6 6 6-6'/%3E%3C/svg%3E"); + background-repeat: no-repeat; + background-position: right .75rem center; + background-size: 16px 12px; + border: 1px solid #bdbdbd; + border-radius: .25rem; + box-shadow: inset 0 1px 2px rgba(0,0,0,.075); + -webkit-appearance: none; + -moz-appearance: none; + appearance: none +} + +@media(prefers-reduced-motion:reduce) { + .form-select { + transition: none + } +} + +.form-select:focus { + box-shadow: inset 0 1px 2px rgba(0,0,0,.075),0 0 0 .25rem rgba(59,113,202,.25) +} + +.form-select[multiple],.form-select[size]:not([size="1"]) { + padding-right: .75rem; + background-image: none +} + +.form-select:disabled { + background-color: #eee +} + +.form-select:-moz-focusring { + color: transparent; + text-shadow: 0 0 0 #4f4f4f +} + +.form-select-sm { + padding-top: .25rem; + padding-bottom: .25rem; + padding-left: .5rem; + font-size: .775rem; + border-radius: .25rem +} + +.form-select-lg { + padding-top: .5rem; + padding-bottom: .5rem; + padding-left: 1rem; + font-size: 1rem; + border-radius: .5rem +} + +.form-check { + display: block; + min-height: 1.6rem; + padding-left: 1.5em; + margin-bottom: .125rem +} + +.form-check .form-check-input { + float: left; + margin-left: -1.5em +} + +.form-check-reverse { + padding-right: 1.5em; + padding-left: 0; + text-align: right +} + +.form-check-reverse .form-check-input { + float: right; + margin-right: -1.5em; + margin-left: 0 +} + +.form-check-input { + width: 1em; + height: 1em; + margin-top: .3em; + vertical-align: top; + background-repeat: no-repeat; + background-position: 50%; + background-size: contain; + border: 1px solid rgba(0,0,0,.25); + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + print-color-adjust: exact +} + +.form-check-input[type=checkbox] { + border-radius: .25em +} + +.form-check-input:active { + filter: brightness(90%) +} + +.form-check-input:focus { + border-color: #3b71ca; + outline: 0; + box-shadow: 0 0 0 .25rem rgba(59,113,202,.25) +} + +.form-check-input:checked { + background-color: #3b71ca +} + +.form-check-input:checked[type=checkbox] { + background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='M6 10l3 3 6-6'/%3E%3C/svg%3E") +} + +.form-check-input:checked[type=radio] { + background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3E%3Ccircle r='2' fill='%23fff'/%3E%3C/svg%3E") +} + +.form-check-input[type=checkbox]:indeterminate { + background-color: #3b71ca; + border-color: #757575; + background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='M6 10h8'/%3E%3C/svg%3E") +} + +.form-check-input:disabled { + pointer-events: none; + filter: none; + opacity: .5 +} + +.form-check-input:disabled~.form-check-label,.form-check-input[disabled]~.form-check-label { + cursor: default; + opacity: .5 +} + +.form-switch { + padding-left: 2.5em +} + +.form-switch .form-check-input { + width: 2em; + margin-left: -2.5em; + background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3E%3Ccircle r='3' fill='rgba(0, 0, 0, 0.25)'/%3E%3C/svg%3E"); + background-position: 0; + border-radius: 2em; + transition: background-position .15s ease-in-out +} + +@media(prefers-reduced-motion:reduce) { + .form-switch .form-check-input { + transition: none + } +} + +.form-switch .form-check-input:focus { + background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3E%3Ccircle r='3' fill='%233b71ca'/%3E%3C/svg%3E") +} + +.form-switch .form-check-input:checked { + background-position: 100%; + background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3E%3Ccircle r='3' fill='%23fff'/%3E%3C/svg%3E") +} + +.form-switch.form-check-reverse { + padding-right: 2.5em; + padding-left: 0 +} + +.form-switch.form-check-reverse .form-check-input { + margin-right: -2.5em; + margin-left: 0 +} + +.form-check-inline { + display: inline-block; + margin-right: 1rem +} + +.btn-check { + position: absolute; + clip: rect(0,0,0,0); + pointer-events: none +} + +.btn-check:disabled+.btn,.btn-check[disabled]+.btn { + pointer-events: none; + filter: none; + opacity: .65 +} + +.form-range { + width: 100%; + height: 1.5rem; + padding: 0; + background-color: transparent; + -webkit-appearance: none; + -moz-appearance: none; + appearance: none +} + +.form-range:focus { + outline: 0 +} + +.form-range:focus::-webkit-slider-thumb { + box-shadow: 0 0 0 1px #fff,0 0 0 .25rem rgba(59,113,202,.25) +} + +.form-range:focus::-moz-range-thumb { + box-shadow: 0 0 0 1px #fff,0 0 0 .25rem rgba(59,113,202,.25) +} + +.form-range::-webkit-slider-thumb { + width: 1rem; + height: 1rem; + margin-top: -.25rem; + background-color: #3b71ca; + border: 0; + border-radius: 1rem; + box-shadow: 0 .1rem .25rem rgba(0,0,0,.1); + -webkit-transition: background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out; + transition: background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out +} + +@media(prefers-reduced-motion:reduce) { + .form-range::-webkit-slider-thumb { + -webkit-transition: none; + transition: none + } +} + +.form-range::-webkit-slider-thumb:active { + background-color: #c4d4ef +} + +.form-range::-webkit-slider-runnable-track { + width: 100%; + height: .5rem; + color: transparent; + cursor: pointer; + background-color: #e0e0e0; + border-color: transparent; + border-radius: 1rem; + box-shadow: inset 0 1px 2px rgba(0,0,0,.075) +} + +.form-range::-moz-range-thumb { + width: 1rem; + height: 1rem; + background-color: #3b71ca; + border: 0; + border-radius: 1rem; + box-shadow: 0 .1rem .25rem rgba(0,0,0,.1); + -moz-transition: background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out; + transition: background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out +} + +@media(prefers-reduced-motion:reduce) { + .form-range::-moz-range-thumb { + -moz-transition: none; + transition: none + } +} + +.form-range::-moz-range-thumb:active { + background-color: #c4d4ef +} + +.form-range::-moz-range-track { + width: 100%; + height: .5rem; + color: transparent; + cursor: pointer; + background-color: #e0e0e0; + border-color: transparent; + border-radius: 1rem; + box-shadow: inset 0 1px 2px rgba(0,0,0,.075) +} + +.form-range:disabled { + pointer-events: none +} + +.form-range:disabled::-webkit-slider-thumb { + background-color: #9e9e9e +} + +.form-range:disabled::-moz-range-thumb { + background-color: #9e9e9e +} + +.form-floating { + position: relative +} + +.form-floating>.form-control,.form-floating>.form-control-plaintext,.form-floating>.form-select { + height: calc(3.5rem + 2px); + line-height: 1.25 +} + +.form-floating>label { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + padding: 1rem .75rem; + overflow: hidden; + text-align: start; + text-overflow: ellipsis; + white-space: nowrap; + pointer-events: none; + border: 1px solid transparent; + transform-origin: 0 0; + transition: opacity .1s ease-in-out,transform .1s ease-in-out +} + +@media(prefers-reduced-motion:reduce) { + .form-floating>label { + transition: none + } +} + +.form-floating>.form-control,.form-floating>.form-control-plaintext { + padding: 1rem .75rem +} + +.form-floating>.form-control-plaintext::-moz-placeholder,.form-floating>.form-control::-moz-placeholder { + color: transparent +} + +.form-floating>.form-control-plaintext::placeholder,.form-floating>.form-control::placeholder { + color: transparent +} + +.form-floating>.form-control-plaintext:not(:-moz-placeholder-shown),.form-floating>.form-control:not(:-moz-placeholder-shown) { + padding-top: 1.625rem; + padding-bottom: .625rem +} + +.form-floating>.form-control-plaintext:focus,.form-floating>.form-control-plaintext:not(:placeholder-shown),.form-floating>.form-control:focus,.form-floating>.form-control:not(:placeholder-shown) { + padding-top: 1.625rem; + padding-bottom: .625rem +} + +.form-floating>.form-control-plaintext:-webkit-autofill,.form-floating>.form-control:-webkit-autofill { + padding-top: 1.625rem; + padding-bottom: .625rem +} + +.form-floating>.form-select { + padding-top: 1.625rem; + padding-bottom: .625rem +} + +.form-floating>.form-control:not(:-moz-placeholder-shown)~label { + opacity: .65; + transform: scale(.85) translateY(-.5rem) translateX(.15rem) +} + +.form-floating>.form-control-plaintext~label,.form-floating>.form-control:focus~label,.form-floating>.form-control:not(:placeholder-shown)~label,.form-floating>.form-select~label { + opacity: .65; + transform: scale(.85) translateY(-.5rem) translateX(.15rem) +} + +.form-floating>.form-control:-webkit-autofill~label { + opacity: .65; + transform: scale(.85) translateY(-.5rem) translateX(.15rem) +} + +.form-floating>.form-control-plaintext~label { + border-width: 1px 0 +} + +.input-group { + position: relative; + display: flex; + flex-wrap: wrap; + align-items: stretch; + width: 100% +} + +.input-group>.form-control,.input-group>.form-floating,.input-group>.form-select { + position: relative; + flex: 1 1 auto; + width: 1%; + min-width: 0 +} + +.input-group>.form-control:focus,.input-group>.form-floating:focus-within,.input-group>.form-select:focus { + z-index: 5 +} + +.input-group .btn { + position: relative; + z-index: 2 +} + +.input-group .btn:focus { + z-index: 5 +} + +.input-group-text { + display: flex; + align-items: center; + padding: .375rem .75rem; + font-size: 1rem; + font-weight: 400; + line-height: 1.6; + color: #4f4f4f; + text-align: center; + white-space: nowrap; + background-color: #eee; + border: 1px solid #bdbdbd; + border-radius: .25rem +} + +.input-group-lg>.btn,.input-group-lg>.form-control,.input-group-lg>.form-select,.input-group-lg>.input-group-text { + padding: .5rem 1rem; + font-size: 1rem; + border-radius: .5rem +} + +.input-group-sm>.btn,.input-group-sm>.form-control,.input-group-sm>.form-select,.input-group-sm>.input-group-text { + padding: .25rem .5rem; + font-size: .775rem; + border-radius: .25rem +} + +.input-group-lg>.form-select,.input-group-sm>.form-select { + padding-right: 3rem +} + +.input-group.has-validation>.dropdown-toggle:nth-last-child(n+4),.input-group.has-validation>.form-floating:nth-last-child(n+3)>.form-control,.input-group.has-validation>.form-floating:nth-last-child(n+3)>.form-select,.input-group.has-validation>:nth-last-child(n+3):not(.dropdown-toggle):not(.dropdown-menu):not(.form-floating),.input-group:not(.has-validation)>.dropdown-toggle:nth-last-child(n+3),.input-group:not(.has-validation)>.form-floating:not(:last-child)>.form-control,.input-group:not(.has-validation)>.form-floating:not(:last-child)>.form-select,.input-group:not(.has-validation)>:not(:last-child):not(.dropdown-toggle):not(.dropdown-menu):not(.form-floating) { + border-top-right-radius: 0; + border-bottom-right-radius: 0 +} + +.input-group>:not(:first-child):not(.dropdown-menu):not(.valid-tooltip):not(.valid-feedback):not(.invalid-tooltip):not(.invalid-feedback) { + margin-left: -1px; + border-top-left-radius: 0; + border-bottom-left-radius: 0 +} + +.input-group>.form-floating:not(:first-child)>.form-control,.input-group>.form-floating:not(:first-child)>.form-select { + border-top-left-radius: 0; + border-bottom-left-radius: 0 +} + +.valid-feedback { + width: 100%; + margin-top: .25rem; + font-size: .875em +} + +.valid-tooltip { + color: #000; + border-radius: .25rem +} + +.form-control.is-valid,.was-validated .form-control:valid { + padding-right: calc(1.6em + .75rem); + background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3E%3Cpath fill='%2314a44d' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3E%3C/svg%3E"); + background-repeat: no-repeat; + background-position: right calc(.4em + .1875rem) center; + background-size: calc(.8em + .375rem) calc(.8em + .375rem) +} + +.was-validated textarea.form-control:valid,textarea.form-control.is-valid { + padding-right: calc(1.6em + .75rem); + background-position: top calc(.4em + .1875rem) right calc(.4em + .1875rem) +} + +.form-select.is-valid:not([multiple]):not([size]),.form-select.is-valid:not([multiple])[size="1"],.was-validated .form-select:valid:not([multiple]):not([size]),.was-validated .form-select:valid:not([multiple])[size="1"] { + padding-right: 4.125rem; + background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath fill='none' stroke='%234f4f4f' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M2 5l6 6 6-6'/%3E%3C/svg%3E"),url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3E%3Cpath fill='%2314a44d' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3E%3C/svg%3E"); + background-position: right .75rem center,center right 2.25rem; + background-size: 16px 12px,calc(.8em + .375rem) calc(.8em + .375rem) +} + +.form-control-color.is-valid,.was-validated .form-control-color:valid { + width: calc(3.75rem + 1.6em) +} + +.form-check-input.is-valid:focus,.was-validated .form-check-input:valid:focus { + box-shadow: 0 0 0 .25rem rgba(20,164,77,.25) +} + +.input-group>.form-control:not(:focus).is-valid,.input-group>.form-floating:not(:focus-within).is-valid,.input-group>.form-select:not(:focus).is-valid,.was-validated .input-group>.form-control:not(:focus):valid,.was-validated .input-group>.form-floating:not(:focus-within):valid,.was-validated .input-group>.form-select:not(:focus):valid { + z-index: 3 +} + +.invalid-feedback { + width: 100%; + margin-top: .25rem; + font-size: .875em +} + +.invalid-tooltip { + color: #000; + border-radius: .25rem +} + +.form-control.is-invalid,.was-validated .form-control:invalid { + padding-right: calc(1.6em + .75rem); + background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23dc4c64'%3E%3Ccircle cx='6' cy='6' r='4.5'/%3E%3Cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3E%3Ccircle cx='6' cy='8.2' r='.6' fill='%23dc4c64' stroke='none'/%3E%3C/svg%3E"); + background-repeat: no-repeat; + background-position: right calc(.4em + .1875rem) center; + background-size: calc(.8em + .375rem) calc(.8em + .375rem) +} + +.was-validated textarea.form-control:invalid,textarea.form-control.is-invalid { + padding-right: calc(1.6em + .75rem); + background-position: top calc(.4em + .1875rem) right calc(.4em + .1875rem) +} + +.form-select.is-invalid:not([multiple]):not([size]),.form-select.is-invalid:not([multiple])[size="1"],.was-validated .form-select:invalid:not([multiple]):not([size]),.was-validated .form-select:invalid:not([multiple])[size="1"] { + padding-right: 4.125rem; + background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath fill='none' stroke='%234f4f4f' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M2 5l6 6 6-6'/%3E%3C/svg%3E"),url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23dc4c64'%3E%3Ccircle cx='6' cy='6' r='4.5'/%3E%3Cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3E%3Ccircle cx='6' cy='8.2' r='.6' fill='%23dc4c64' stroke='none'/%3E%3C/svg%3E"); + background-position: right .75rem center,center right 2.25rem; + background-size: 16px 12px,calc(.8em + .375rem) calc(.8em + .375rem) +} + +.form-control-color.is-invalid,.was-validated .form-control-color:invalid { + width: calc(3.75rem + 1.6em) +} + +.form-check-input.is-invalid:focus,.was-validated .form-check-input:invalid:focus { + box-shadow: 0 0 0 .25rem rgba(220,76,100,.25) +} + +.input-group>.form-control:not(:focus).is-invalid,.input-group>.form-floating:not(:focus-within).is-invalid,.input-group>.form-select:not(:focus).is-invalid,.was-validated .input-group>.form-control:not(:focus):invalid,.was-validated .input-group>.form-floating:not(:focus-within):invalid,.was-validated .input-group>.form-select:not(:focus):invalid { + z-index: 4 +} + +.btn { + --mdb-btn-padding-x: 1.5rem; + --mdb-btn-padding-y: 0.375rem; + --mdb-btn-font-size: 0.75rem; + --mdb-btn-font-weight: 500; + --mdb-btn-line-height: 1.5; + --mdb-btn-color: #4f4f4f; + --mdb-btn-bg: transparent; + --mdb-btn-border-width: 2px; + --mdb-btn-border-color: transparent; + --mdb-btn-hover-border-color: transparent; + --mdb-btn-disabled-opacity: 0.65; + --mdb-btn-focus-box-shadow: 0 0 0 0.25rem rgba(var(--mdb-btn-focus-shadow-rgb),0.5); + display: inline-block; + padding: var(--mdb-btn-padding-y) var(--mdb-btn-padding-x); + font-family: var(--mdb-btn-font-family); + font-size: var(--mdb-btn-font-size); + font-weight: var(--mdb-btn-font-weight); + line-height: var(--mdb-btn-line-height); + color: var(--mdb-btn-color); + text-align: center; + vertical-align: middle; + cursor: pointer; + -webkit-user-select: none; + -moz-user-select: none; + user-select: none; + border: var(--mdb-btn-border-width) solid var(--mdb-btn-border-color); + background-color: var(--mdb-btn-bg); + transition: color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out +} + +@media(prefers-reduced-motion:reduce) { + .btn { + transition: none + } +} + +.btn:hover { + color: var(--mdb-btn-hover-color); + background-color: var(--mdb-btn-hover-bg); + border-color: var(--mdb-btn-hover-border-color) +} + +.btn-check+.btn:hover { + color: var(--mdb-btn-color); + background-color: var(--mdb-btn-bg); + border-color: var(--mdb-btn-border-color) +} + +.btn:focus-visible { + color: var(--mdb-btn-hover-color); + background-color: var(--mdb-btn-hover-bg) +} + +.btn-check:focus-visible+.btn,.btn:focus-visible { + border-color: var(--mdb-btn-hover-border-color); + outline: 0; + box-shadow: var(--mdb-btn-box-shadow),var(--mdb-btn-focus-box-shadow) +} + +.btn-check:checked+.btn,.btn.active,.btn.show,.btn:first-child:active,:not(.btn-check)+.btn:active { + color: var(--mdb-btn-active-color); + background-color: var(--mdb-btn-active-bg); + border-color: var(--mdb-btn-active-border-color); + box-shadow: var(--mdb-btn-active-shadow) +} + +.btn-check:checked+.btn:focus-visible,.btn.active:focus-visible,.btn.show:focus-visible,.btn:first-child:active:focus-visible,:not(.btn-check)+.btn:active:focus-visible { + box-shadow: var(--mdb-btn-active-shadow),var(--mdb-btn-focus-box-shadow) +} + +.btn.disabled,.btn:disabled,fieldset:disabled .btn { + color: var(--mdb-btn-disabled-color); + pointer-events: none; + background-color: var(--mdb-btn-disabled-bg); + border-color: var(--mdb-btn-disabled-border-color); + opacity: var(--mdb-btn-disabled-opacity); + box-shadow: none +} + +.btn-primary { + --mdb-btn-border-color: #3b71ca; + --mdb-btn-hover-border-color: #2f5aa2; + --mdb-btn-focus-shadow-rgb: 88,134,210; + --mdb-btn-active-border-color: #2c5598; + --mdb-btn-active-shadow: 0 8px 9px -4px rgba(0,0,0,0.15),0 4px 18px 0 rgba(0,0,0,0.1); + --mdb-btn-disabled-color: #fff; + --mdb-btn-disabled-bg: #3b71ca; + --mdb-btn-disabled-border-color: #3b71ca +} + +.btn-secondary { + --mdb-btn-color: #000; + --mdb-btn-bg: #9fa6b2; + --mdb-btn-border-color: #9fa6b2; + --mdb-btn-hover-color: #000; + --mdb-btn-hover-bg: #adb3be; + --mdb-btn-hover-border-color: #a9afba; + --mdb-btn-focus-shadow-rgb: 135,141,151; + --mdb-btn-active-color: #000; + --mdb-btn-active-bg: #b2b8c1; + --mdb-btn-active-border-color: #a9afba; + --mdb-btn-active-shadow: 0 8px 9px -4px rgba(0,0,0,0.15),0 4px 18px 0 rgba(0,0,0,0.1); + --mdb-btn-disabled-color: #000; + --mdb-btn-disabled-bg: #9fa6b2; + --mdb-btn-disabled-border-color: #9fa6b2 +} + +.btn-success { + --mdb-btn-color: #000; + --mdb-btn-border-color: #14a44d; + --mdb-btn-hover-color: #000; + --mdb-btn-hover-bg: #37b268; + --mdb-btn-hover-border-color: #2cad5f; + --mdb-btn-focus-shadow-rgb: 17,139,65; + --mdb-btn-active-color: #000; + --mdb-btn-active-bg: #43b671; + --mdb-btn-active-border-color: #2cad5f; + --mdb-btn-active-shadow: 0 8px 9px -4px rgba(0,0,0,0.15),0 4px 18px 0 rgba(0,0,0,0.1); + --mdb-btn-disabled-color: #000; + --mdb-btn-disabled-bg: #14a44d; + --mdb-btn-disabled-border-color: #14a44d +} + +.btn-danger { + --mdb-btn-color: #000; + --mdb-btn-border-color: #dc4c64; + --mdb-btn-hover-color: #000; + --mdb-btn-hover-bg: #e1677b; + --mdb-btn-hover-border-color: #e05e74; + --mdb-btn-focus-shadow-rgb: 187,65,85; + --mdb-btn-active-color: #000; + --mdb-btn-active-bg: #e37083; + --mdb-btn-active-border-color: #e05e74; + --mdb-btn-active-shadow: 0 8px 9px -4px rgba(0,0,0,0.15),0 4px 18px 0 rgba(0,0,0,0.1); + --mdb-btn-disabled-color: #000; + --mdb-btn-disabled-bg: #dc4c64; + --mdb-btn-disabled-border-color: #dc4c64 +} + +.btn-warning { + --mdb-btn-color: #000; + --mdb-btn-border-color: #e4a11b; + --mdb-btn-hover-color: #000; + --mdb-btn-hover-bg: #e8af3d; + --mdb-btn-hover-border-color: #e7aa32; + --mdb-btn-focus-shadow-rgb: 194,137,23; + --mdb-btn-active-color: #000; + --mdb-btn-active-bg: #e9b449; + --mdb-btn-active-border-color: #e7aa32; + --mdb-btn-active-shadow: 0 8px 9px -4px rgba(0,0,0,0.15),0 4px 18px 0 rgba(0,0,0,0.1); + --mdb-btn-disabled-color: #000; + --mdb-btn-disabled-bg: #e4a11b; + --mdb-btn-disabled-border-color: #e4a11b +} + +.btn-info { + --mdb-btn-color: #000; + --mdb-btn-border-color: #54b4d3; + --mdb-btn-hover-color: #000; + --mdb-btn-hover-bg: #6ebfda; + --mdb-btn-hover-border-color: #65bcd7; + --mdb-btn-focus-shadow-rgb: 71,153,179; + --mdb-btn-active-color: #000; + --mdb-btn-active-bg: #76c3dc; + --mdb-btn-active-border-color: #65bcd7; + --mdb-btn-active-shadow: 0 8px 9px -4px rgba(0,0,0,0.15),0 4px 18px 0 rgba(0,0,0,0.1); + --mdb-btn-disabled-color: #000; + --mdb-btn-disabled-bg: #54b4d3; + --mdb-btn-disabled-border-color: #54b4d3 +} + +.btn-light { + --mdb-btn-color: #000; + --mdb-btn-border-color: #fbfbfb; + --mdb-btn-hover-color: #000; + --mdb-btn-hover-border-color: #c9c9c9; + --mdb-btn-focus-shadow-rgb: 213,213,213; + --mdb-btn-active-color: #000; + --mdb-btn-active-border-color: #bcbcbc; + --mdb-btn-active-shadow: 0 8px 9px -4px rgba(0,0,0,0.15),0 4px 18px 0 rgba(0,0,0,0.1); + --mdb-btn-disabled-color: #000; + --mdb-btn-disabled-bg: #fbfbfb; + --mdb-btn-disabled-border-color: #fbfbfb +} + +.btn-dark { + --mdb-btn-border-color: #332d2d; + --mdb-btn-hover-bg: #524d4d; + --mdb-btn-hover-border-color: #474242; + --mdb-btn-focus-shadow-rgb: 82,77,77; + --mdb-btn-active-bg: #5c5757; + --mdb-btn-active-border-color: #474242; + --mdb-btn-active-shadow: 0 8px 9px -4px rgba(0,0,0,0.15),0 4px 18px 0 rgba(0,0,0,0.1); + --mdb-btn-disabled-color: #fff; + --mdb-btn-disabled-bg: #332d2d; + --mdb-btn-disabled-border-color: #332d2d +} + +.btn-outline-primary { + --mdb-btn-hover-color: #fff; + --mdb-btn-hover-bg: #3b71ca; + --mdb-btn-hover-border-color: #3b71ca; + --mdb-btn-focus-shadow-rgb: 59,113,202; + --mdb-btn-active-color: #fff; + --mdb-btn-active-bg: #3b71ca; + --mdb-btn-active-border-color: #3b71ca; + --mdb-btn-active-shadow: 0 8px 9px -4px rgba(0,0,0,0.15),0 4px 18px 0 rgba(0,0,0,0.1); + --mdb-btn-disabled-color: #3b71ca; + --mdb-btn-disabled-bg: transparent; + --mdb-btn-disabled-border-color: #3b71ca; + --mdb-gradient: none +} + +.btn-outline-secondary { + --mdb-btn-color: #9fa6b2; + --mdb-btn-border-color: #9fa6b2; + --mdb-btn-hover-color: #000; + --mdb-btn-hover-bg: #9fa6b2; + --mdb-btn-hover-border-color: #9fa6b2; + --mdb-btn-focus-shadow-rgb: 159,166,178; + --mdb-btn-active-color: #000; + --mdb-btn-active-bg: #9fa6b2; + --mdb-btn-active-border-color: #9fa6b2; + --mdb-btn-active-shadow: 0 8px 9px -4px rgba(0,0,0,0.15),0 4px 18px 0 rgba(0,0,0,0.1); + --mdb-btn-disabled-color: #9fa6b2; + --mdb-btn-disabled-bg: transparent; + --mdb-btn-disabled-border-color: #9fa6b2; + --mdb-gradient: none +} + +.btn-outline-success { + --mdb-btn-hover-color: #000; + --mdb-btn-hover-bg: #14a44d; + --mdb-btn-hover-border-color: #14a44d; + --mdb-btn-focus-shadow-rgb: 20,164,77; + --mdb-btn-active-color: #000; + --mdb-btn-active-bg: #14a44d; + --mdb-btn-active-border-color: #14a44d; + --mdb-btn-active-shadow: 0 8px 9px -4px rgba(0,0,0,0.15),0 4px 18px 0 rgba(0,0,0,0.1); + --mdb-btn-disabled-color: #14a44d; + --mdb-btn-disabled-bg: transparent; + --mdb-btn-disabled-border-color: #14a44d; + --mdb-gradient: none +} + +.btn-outline-danger { + --mdb-btn-hover-color: #000; + --mdb-btn-hover-bg: #dc4c64; + --mdb-btn-hover-border-color: #dc4c64; + --mdb-btn-focus-shadow-rgb: 220,76,100; + --mdb-btn-active-color: #000; + --mdb-btn-active-bg: #dc4c64; + --mdb-btn-active-border-color: #dc4c64; + --mdb-btn-active-shadow: 0 8px 9px -4px rgba(0,0,0,0.15),0 4px 18px 0 rgba(0,0,0,0.1); + --mdb-btn-disabled-color: #dc4c64; + --mdb-btn-disabled-bg: transparent; + --mdb-btn-disabled-border-color: #dc4c64; + --mdb-gradient: none +} + +.btn-outline-warning { + --mdb-btn-hover-color: #000; + --mdb-btn-hover-bg: #e4a11b; + --mdb-btn-hover-border-color: #e4a11b; + --mdb-btn-focus-shadow-rgb: 228,161,27; + --mdb-btn-active-color: #000; + --mdb-btn-active-bg: #e4a11b; + --mdb-btn-active-border-color: #e4a11b; + --mdb-btn-active-shadow: 0 8px 9px -4px rgba(0,0,0,0.15),0 4px 18px 0 rgba(0,0,0,0.1); + --mdb-btn-disabled-color: #e4a11b; + --mdb-btn-disabled-bg: transparent; + --mdb-btn-disabled-border-color: #e4a11b; + --mdb-gradient: none +} + +.btn-outline-info { + --mdb-btn-hover-color: #000; + --mdb-btn-hover-bg: #54b4d3; + --mdb-btn-hover-border-color: #54b4d3; + --mdb-btn-focus-shadow-rgb: 84,180,211; + --mdb-btn-active-color: #000; + --mdb-btn-active-bg: #54b4d3; + --mdb-btn-active-border-color: #54b4d3; + --mdb-btn-active-shadow: 0 8px 9px -4px rgba(0,0,0,0.15),0 4px 18px 0 rgba(0,0,0,0.1); + --mdb-btn-disabled-color: #54b4d3; + --mdb-btn-disabled-bg: transparent; + --mdb-btn-disabled-border-color: #54b4d3; + --mdb-gradient: none +} + +.btn-outline-light { + --mdb-btn-hover-color: #000; + --mdb-btn-hover-bg: #fbfbfb; + --mdb-btn-hover-border-color: #fbfbfb; + --mdb-btn-focus-shadow-rgb: 251,251,251; + --mdb-btn-active-color: #000; + --mdb-btn-active-bg: #fbfbfb; + --mdb-btn-active-border-color: #fbfbfb; + --mdb-btn-active-shadow: 0 8px 9px -4px rgba(0,0,0,0.15),0 4px 18px 0 rgba(0,0,0,0.1); + --mdb-btn-disabled-color: #fbfbfb; + --mdb-btn-disabled-bg: transparent; + --mdb-btn-disabled-border-color: #fbfbfb; + --mdb-gradient: none +} + +.btn-outline-dark { + --mdb-btn-hover-color: #fff; + --mdb-btn-hover-bg: #332d2d; + --mdb-btn-hover-border-color: #332d2d; + --mdb-btn-focus-shadow-rgb: 51,45,45; + --mdb-btn-active-color: #fff; + --mdb-btn-active-bg: #332d2d; + --mdb-btn-active-border-color: #332d2d; + --mdb-btn-active-shadow: 0 8px 9px -4px rgba(0,0,0,0.15),0 4px 18px 0 rgba(0,0,0,0.1); + --mdb-btn-disabled-color: #332d2d; + --mdb-btn-disabled-bg: transparent; + --mdb-btn-disabled-border-color: #332d2d; + --mdb-gradient: none +} + +.btn-link { + --mdb-btn-font-weight: 400; + --mdb-btn-bg: transparent; + --mdb-btn-border-color: transparent; + --mdb-btn-hover-border-color: transparent; + --mdb-btn-active-color: #386bc0; + --mdb-btn-active-border-color: transparent; + --mdb-btn-disabled-border-color: transparent; + --mdb-btn-focus-shadow-rgb: 88,134,210 +} + +.btn-link:focus-visible,.btn-link:hover { + text-decoration: none +} + +.btn-link:focus-visible { + color: var(--mdb-btn-color) +} + +.btn-link:hover { + color: var(--mdb-btn-hover-color) +} + +.btn-group-lg>.btn,.btn-lg { + --mdb-btn-padding-y: 0.5rem; + --mdb-btn-border-radius: 0.5rem +} + +.btn-group-sm>.btn,.btn-sm { + --mdb-btn-padding-y: 0.25rem; + --mdb-btn-border-radius: 0.25rem +} + +.fade { + transition: opacity .15s linear +} + +@media(prefers-reduced-motion:reduce) { + .fade { + transition: none + } +} + +.fade:not(.show) { + opacity: 0 +} + +.collapse:not(.show) { + display: none +} + +.collapsing { + height: 0; + overflow: hidden; + transition: height .35s ease +} + +@media(prefers-reduced-motion:reduce) { + .collapsing { + transition: none + } +} + +.collapsing.collapse-horizontal { + width: 0; + height: auto; + transition: width .35s ease +} + +@media(prefers-reduced-motion:reduce) { + .collapsing.collapse-horizontal { + transition: none + } +} + +.dropdown,.dropdown-center,.dropend,.dropstart,.dropup,.dropup-center { + position: relative +} + +.dropdown-toggle { + white-space: nowrap +} + +.dropdown-toggle:after { + display: inline-block; + margin-left: .255em; + vertical-align: .255em; + content: ""; + border-top: .3em solid; + border-right: .3em solid transparent; + border-bottom: 0; + border-left: .3em solid transparent +} + +.dropdown-toggle:empty:after { + margin-left: 0 +} + +.dropdown-menu { + --mdb-dropdown-zindex: 1000; + --mdb-dropdown-min-width: 10rem; + --mdb-dropdown-padding-x: 0; + --mdb-dropdown-padding-y: 0.5rem; + --mdb-dropdown-spacer: 0.125rem; + --mdb-dropdown-font-size: 0.875rem; + --mdb-dropdown-color: #4f4f4f; + --mdb-dropdown-bg: #fff; + --mdb-dropdown-border-color: var(--mdb-border-color-translucent); + --mdb-dropdown-border-radius: 0.5rem; + --mdb-dropdown-border-width: 1px; + --mdb-dropdown-inner-border-radius: calc(0.5rem - 1px); + --mdb-dropdown-divider-bg: #f5f5f5; + --mdb-dropdown-divider-margin-y: 0.5rem; + --mdb-dropdown-box-shadow: 0 2px 15px -3px rgba(0,0,0,0.07),0 10px 20px -2px rgba(0,0,0,0.04); + --mdb-dropdown-link-color: #262626; + --mdb-dropdown-link-hover-color: #222; + --mdb-dropdown-link-hover-bg: #eee; + --mdb-dropdown-link-active-color: #fff; + --mdb-dropdown-link-active-bg: #3b71ca; + --mdb-dropdown-link-disabled-color: #9e9e9e; + --mdb-dropdown-item-padding-x: 1rem; + --mdb-dropdown-item-padding-y: 0.5rem; + --mdb-dropdown-header-color: #757575; + --mdb-dropdown-header-padding-x: 1rem; + --mdb-dropdown-header-padding-y: 0.5rem; + position: absolute; + z-index: var(--mdb-dropdown-zindex); + display: none; + min-width: var(--mdb-dropdown-min-width); + padding: var(--mdb-dropdown-padding-y) var(--mdb-dropdown-padding-x); + text-align: left; + list-style: none; + background-color: var(--mdb-dropdown-bg); + background-clip: padding-box; + border: var(--mdb-dropdown-border-width) solid var(--mdb-dropdown-border-color); + border-radius: var(--mdb-dropdown-border-radius) +} + +.dropdown-menu[data-mdb-popper] { + top: 100%; + left: 0; + margin-top: var(--mdb-dropdown-spacer) +} + +.dropdown-menu-start { + --mdb-position: start +} + +.dropdown-menu-start[data-mdb-popper] { + right: auto; + left: 0 +} + +.dropdown-menu-end { + --mdb-position: end +} + +.dropdown-menu-end[data-mdb-popper] { + right: 0; + left: auto +} + +@media(min-width: 576px) { + .dropdown-menu-sm-start { + --mdb-position:start + } + + .dropdown-menu-sm-start[data-mdb-popper] { + right: auto; + left: 0 + } + + .dropdown-menu-sm-end { + --mdb-position: end + } + + .dropdown-menu-sm-end[data-mdb-popper] { + right: 0; + left: auto + } +} + +@media(min-width: 768px) { + .dropdown-menu-md-start { + --mdb-position:start + } + + .dropdown-menu-md-start[data-mdb-popper] { + right: auto; + left: 0 + } + + .dropdown-menu-md-end { + --mdb-position: end + } + + .dropdown-menu-md-end[data-mdb-popper] { + right: 0; + left: auto + } +} + +@media(min-width: 992px) { + .dropdown-menu-lg-start { + --mdb-position:start + } + + .dropdown-menu-lg-start[data-mdb-popper] { + right: auto; + left: 0 + } + + .dropdown-menu-lg-end { + --mdb-position: end + } + + .dropdown-menu-lg-end[data-mdb-popper] { + right: 0; + left: auto + } +} + +@media(min-width: 1200px) { + .dropdown-menu-xl-start { + --mdb-position:start + } + + .dropdown-menu-xl-start[data-mdb-popper] { + right: auto; + left: 0 + } + + .dropdown-menu-xl-end { + --mdb-position: end + } + + .dropdown-menu-xl-end[data-mdb-popper] { + right: 0; + left: auto + } +} + +@media(min-width: 1400px) { + .dropdown-menu-xxl-start { + --mdb-position:start + } + + .dropdown-menu-xxl-start[data-mdb-popper] { + right: auto; + left: 0 + } + + .dropdown-menu-xxl-end { + --mdb-position: end + } + + .dropdown-menu-xxl-end[data-mdb-popper] { + right: 0; + left: auto + } +} + +.dropup .dropdown-menu[data-mdb-popper] { + top: auto; + bottom: 100%; + margin-top: 0; + margin-bottom: var(--mdb-dropdown-spacer) +} + +.dropup .dropdown-toggle:after { + display: inline-block; + margin-left: .255em; + vertical-align: .255em; + content: ""; + border-top: 0; + border-right: .3em solid transparent; + border-bottom: .3em solid; + border-left: .3em solid transparent +} + +.dropup .dropdown-toggle:empty:after { + margin-left: 0 +} + +.dropend .dropdown-menu[data-mdb-popper] { + top: 0; + right: auto; + left: 100%; + margin-top: 0; + margin-left: var(--mdb-dropdown-spacer) +} + +.dropend .dropdown-toggle:after { + display: inline-block; + margin-left: .255em; + vertical-align: .255em; + content: ""; + border-top: .3em solid transparent; + border-right: 0; + border-bottom: .3em solid transparent; + border-left: .3em solid +} + +.dropend .dropdown-toggle:empty:after { + margin-left: 0 +} + +.dropend .dropdown-toggle:after { + vertical-align: 0 +} + +.dropstart .dropdown-menu[data-mdb-popper] { + top: 0; + right: 100%; + left: auto; + margin-top: 0; + margin-right: var(--mdb-dropdown-spacer) +} + +.dropstart .dropdown-toggle:after { + display: inline-block; + margin-left: .255em; + vertical-align: .255em; + content: ""; + display: none +} + +.dropstart .dropdown-toggle:before { + display: inline-block; + margin-right: .255em; + vertical-align: .255em; + content: ""; + border-top: .3em solid transparent; + border-right: .3em solid; + border-bottom: .3em solid transparent +} + +.dropstart .dropdown-toggle:empty:after { + margin-left: 0 +} + +.dropstart .dropdown-toggle:before { + vertical-align: 0 +} + +.dropdown-divider { + height: 0; + margin: var(--mdb-dropdown-divider-margin-y) 0; + overflow: hidden; + border-top: 1px solid var(--mdb-dropdown-divider-bg) +} + +.dropdown-item { + display: block; + width: 100%; + clear: both; + font-weight: 400; + color: var(--mdb-dropdown-link-color); + text-align: inherit; + white-space: nowrap; + background-color: transparent; + border: 0 +} + +.dropdown-item:focus,.dropdown-item:hover { + color: var(--mdb-dropdown-link-hover-color); + background-color: var(--mdb-dropdown-link-hover-bg) +} + +.dropdown-item.active,.dropdown-item:active { + color: var(--mdb-dropdown-link-active-color); + text-decoration: none; + background-color: var(--mdb-dropdown-link-active-bg) +} + +.dropdown-item.disabled,.dropdown-item:disabled { + color: var(--mdb-dropdown-link-disabled-color); + pointer-events: none; + background-color: transparent +} + +.dropdown-menu.show { + display: block +} + +.dropdown-header { + display: block; + padding: var(--mdb-dropdown-header-padding-y) var(--mdb-dropdown-header-padding-x); + margin-bottom: 0; + font-size: .875rem; + color: var(--mdb-dropdown-header-color); + white-space: nowrap +} + +.dropdown-item-text { + display: block; + padding: var(--mdb-dropdown-item-padding-y) var(--mdb-dropdown-item-padding-x); + color: var(--mdb-dropdown-link-color) +} + +.dropdown-menu-dark { + --mdb-dropdown-color: #e0e0e0; + --mdb-dropdown-bg: #4f4f4f; + --mdb-dropdown-border-color: var(--mdb-border-color-translucent); + --mdb-dropdown-link-color: #e0e0e0; + --mdb-dropdown-link-hover-color: #fff; + --mdb-dropdown-divider-bg: #f5f5f5; + --mdb-dropdown-link-hover-bg: hsla(0,0%,100%,0.15); + --mdb-dropdown-link-active-color: #fff; + --mdb-dropdown-link-active-bg: #3b71ca; + --mdb-dropdown-link-disabled-color: #9e9e9e; + --mdb-dropdown-header-color: #9e9e9e +} + +.btn-group,.btn-group-vertical { + position: relative; + display: inline-flex; + vertical-align: middle +} + +.btn-group-vertical>.btn,.btn-group>.btn { + position: relative; + flex: 1 1 auto +} + +.btn-group-vertical>.btn-check:checked+.btn,.btn-group-vertical>.btn-check:focus+.btn,.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group-vertical>.btn:hover,.btn-group>.btn-check:checked+.btn,.btn-group>.btn-check:focus+.btn,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus,.btn-group>.btn:hover { + z-index: 1 +} + +.btn-toolbar { + display: flex; + flex-wrap: wrap; + justify-content: flex-start +} + +.btn-toolbar .input-group { + width: auto +} + +.btn-group { + border-radius: .25rem +} + +.btn-group>.btn-group:not(:first-child),.btn-group>:not(.btn-check:first-child)+.btn { + margin-left: -2px +} + +.btn-group>.btn-group:not(:last-child)>.btn,.btn-group>.btn.dropdown-toggle-split:first-child,.btn-group>.btn:not(:last-child):not(.dropdown-toggle) { + border-top-right-radius: 0; + border-bottom-right-radius: 0 +} + +.btn-group>.btn-group:not(:first-child)>.btn,.btn-group>.btn:nth-child(n+3),.btn-group>:not(.btn-check)+.btn { + border-top-left-radius: 0; + border-bottom-left-radius: 0 +} + +.dropdown-toggle-split { + padding-right: 1.125rem; + padding-left: 1.125rem +} + +.dropdown-toggle-split:after,.dropend .dropdown-toggle-split:after,.dropup .dropdown-toggle-split:after { + margin-left: 0 +} + +.dropstart .dropdown-toggle-split:before { + margin-right: 0 +} + +.btn-group-sm>.btn+.dropdown-toggle-split,.btn-sm+.dropdown-toggle-split { + padding-right: .75rem; + padding-left: .75rem +} + +.btn-group-lg>.btn+.dropdown-toggle-split,.btn-lg+.dropdown-toggle-split { + padding-right: 1.265625rem; + padding-left: 1.265625rem +} + +.btn-group.show .dropdown-toggle { + box-shadow: 0 8px 9px -4px rgba(0,0,0,.15),0 4px 18px 0 rgba(0,0,0,.1) +} + +.btn-group.show .dropdown-toggle.btn-link { + box-shadow: none +} + +.btn-group-vertical { + flex-direction: column; + align-items: flex-start; + justify-content: center +} + +.btn-group-vertical>.btn,.btn-group-vertical>.btn-group { + width: 100% +} + +.btn-group-vertical>.btn-group:not(:first-child),.btn-group-vertical>.btn:not(:first-child) { + margin-top: -2px +} + +.btn-group-vertical>.btn-group:not(:last-child)>.btn,.btn-group-vertical>.btn:not(:last-child):not(.dropdown-toggle) { + border-bottom-right-radius: 0; + border-bottom-left-radius: 0 +} + +.btn-group-vertical>.btn-group:not(:first-child)>.btn,.btn-group-vertical>.btn~.btn { + border-top-left-radius: 0; + border-top-right-radius: 0 +} + +.nav { + --mdb-nav-link-padding-x: 1rem; + --mdb-nav-link-padding-y: 0.5rem; + --mdb-nav-link-color: var(--mdb-link-color); + --mdb-nav-link-hover-color: var(--mdb-link-hover-color); + --mdb-nav-link-disabled-color: #757575; + display: flex; + flex-wrap: wrap; + padding-left: 0; + margin-bottom: 0; + list-style: none +} + +.nav-link { + display: block; + padding: var(--mdb-nav-link-padding-y) var(--mdb-nav-link-padding-x); + font-size: var(--mdb-nav-link-font-size); + font-weight: var(--mdb-nav-link-font-weight); + color: var(--mdb-nav-link-color); + transition: color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out +} + +@media(prefers-reduced-motion:reduce) { + .nav-link { + transition: none + } +} + +.nav-link:focus,.nav-link:hover { + color: var(--mdb-nav-link-hover-color) +} + +.nav-link.disabled { + color: var(--mdb-nav-link-disabled-color); + pointer-events: none; + cursor: default +} + +.nav-tabs { + --mdb-nav-tabs-border-width: 1px; + --mdb-nav-tabs-border-color: #e0e0e0; + --mdb-nav-tabs-border-radius: 0.25rem; + --mdb-nav-tabs-link-hover-border-color: #eee #eee #e0e0e0; + --mdb-nav-tabs-link-active-color: #3b71ca; + --mdb-nav-tabs-link-active-bg: #fff; + --mdb-nav-tabs-link-active-border-color: #3b71ca; + border-bottom: var(--mdb-nav-tabs-border-width) solid var(--mdb-nav-tabs-border-color) +} + +.nav-tabs .nav-link { + margin-bottom: calc(var(--mdb-nav-tabs-border-width)*-1); + background: none; + border: var(--mdb-nav-tabs-border-width) solid transparent; + border-top-left-radius: var(--mdb-nav-tabs-border-radius); + border-top-right-radius: var(--mdb-nav-tabs-border-radius) +} + +.nav-tabs .nav-link:focus,.nav-tabs .nav-link:hover { + isolation: isolate; + border-color: var(--mdb-nav-tabs-link-hover-border-color) +} + +.nav-tabs .nav-link.disabled,.nav-tabs .nav-link:disabled { + color: var(--mdb-nav-link-disabled-color); + background-color: transparent; + border-color: transparent +} + +.nav-tabs .nav-item.show .nav-link,.nav-tabs .nav-link.active { + background-color: var(--mdb-nav-tabs-link-active-bg) +} + +.nav-tabs .dropdown-menu { + margin-top: calc(var(--mdb-nav-tabs-border-width)*-1); + border-top-left-radius: 0; + border-top-right-radius: 0 +} + +.nav-pills { + --mdb-nav-pills-border-radius: 0.25rem; + --mdb-nav-pills-link-active-color: #285192; + --mdb-nav-pills-link-active-bg: #e3ebf7 +} + +.nav-pills .nav-link { + background: none; + border: 0; + border-radius: var(--mdb-nav-pills-border-radius) +} + +.nav-pills .nav-link:disabled { + color: var(--mdb-nav-link-disabled-color); + background-color: transparent; + border-color: transparent +} + +.nav-fill .nav-item,.nav-fill>.nav-link { + flex: 1 1 auto; + text-align: center +} + +.nav-justified .nav-item,.nav-justified>.nav-link { + flex-basis: 0; + flex-grow: 1; + text-align: center +} + +.nav-fill .nav-item .nav-link,.nav-justified .nav-item .nav-link { + width: 100% +} + +.tab-content>.tab-pane { + display: none +} + +.tab-content>.active { + display: block +} + +.navbar { + --mdb-navbar-padding-x: 0; + --mdb-navbar-padding-y: 0.5rem; + --mdb-navbar-color: rgba(0,0,0,0.55); + --mdb-navbar-hover-color: rgba(0,0,0,0.7); + --mdb-navbar-disabled-color: rgba(0,0,0,0.3); + --mdb-navbar-active-color: rgba(0,0,0,0.9); + --mdb-navbar-brand-padding-y: 0.3rem; + --mdb-navbar-brand-margin-end: 1rem; + --mdb-navbar-brand-font-size: 1.25rem; + --mdb-navbar-brand-color: rgba(0,0,0,0.9); + --mdb-navbar-brand-hover-color: rgba(0,0,0,0.9); + --mdb-navbar-nav-link-padding-x: 0.5rem; + --mdb-navbar-toggler-padding-y: 0.25rem; + --mdb-navbar-toggler-padding-x: 0.75rem; + --mdb-navbar-toggler-font-size: 1.25rem; + --mdb-navbar-toggler-icon-bg: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3E%3Cpath stroke='rgba(0, 0, 0, 0.55)' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3E%3C/svg%3E"); + --mdb-navbar-toggler-border-color: rgba(0,0,0,0.1); + --mdb-navbar-toggler-border-radius: 0.25rem; + --mdb-navbar-toggler-focus-width: 0.25rem; + --mdb-navbar-toggler-transition: box-shadow 0.15s ease-in-out; + position: relative; + display: flex; + flex-wrap: wrap; + align-items: center; + justify-content: space-between; + padding: var(--mdb-navbar-padding-y) var(--mdb-navbar-padding-x) +} + +.navbar>.container,.navbar>.container-fluid,.navbar>.container-lg,.navbar>.container-md,.navbar>.container-sm,.navbar>.container-xl,.navbar>.container-xxl { + display: flex; + flex-wrap: inherit; + align-items: center; + justify-content: space-between +} + +.navbar-brand { + padding-top: var(--mdb-navbar-brand-padding-y); + padding-bottom: var(--mdb-navbar-brand-padding-y); + margin-right: var(--mdb-navbar-brand-margin-end); + font-size: var(--mdb-navbar-brand-font-size); + color: var(--mdb-navbar-brand-color); + white-space: nowrap +} + +.navbar-brand:focus,.navbar-brand:hover { + color: var(--mdb-navbar-brand-hover-color) +} + +.navbar-nav { + --mdb-nav-link-padding-x: 0; + --mdb-nav-link-padding-y: 0.5rem; + --mdb-nav-link-color: var(--mdb-navbar-color); + --mdb-nav-link-hover-color: var(--mdb-navbar-hover-color); + --mdb-nav-link-disabled-color: var(--mdb-navbar-disabled-color); + display: flex; + flex-direction: column; + padding-left: 0; + margin-bottom: 0; + list-style: none +} + +.navbar-nav .nav-link.active,.navbar-nav .show>.nav-link { + color: var(--mdb-navbar-active-color) +} + +.navbar-nav .dropdown-menu { + position: static +} + +.navbar-text { + padding-top: .5rem; + padding-bottom: .5rem; + color: var(--mdb-navbar-color) +} + +.navbar-text a,.navbar-text a:focus,.navbar-text a:hover { + color: var(--mdb-navbar-active-color) +} + +.navbar-collapse { + flex-basis: 100%; + flex-grow: 1; + align-items: center +} + +.navbar-toggler { + padding: var(--mdb-navbar-toggler-padding-y) var(--mdb-navbar-toggler-padding-x); + font-size: var(--mdb-navbar-toggler-font-size); + line-height: 1; + color: var(--mdb-navbar-color); + background-color: transparent; + border: var(--mdb-border-width) solid var(--mdb-navbar-toggler-border-color); + border-radius: var(--mdb-navbar-toggler-border-radius); + transition: var(--mdb-navbar-toggler-transition) +} + +@media(prefers-reduced-motion:reduce) { + .navbar-toggler { + transition: none + } +} + +.navbar-toggler:hover { + text-decoration: none +} + +.navbar-toggler:focus { + text-decoration: none; + outline: 0; + box-shadow: 0 0 0 var(--mdb-navbar-toggler-focus-width) +} + +.navbar-toggler-icon { + display: inline-block; + width: 1.5em; + height: 1.5em; + vertical-align: middle; + background-image: var(--mdb-navbar-toggler-icon-bg); + background-repeat: no-repeat; + background-position: 50%; + background-size: 100% +} + +.navbar-nav-scroll { + max-height: var(--mdb-scroll-height,75vh); + overflow-y: auto +} + +@media(min-width: 576px) { + .navbar-expand-sm { + flex-wrap:nowrap; + justify-content: flex-start + } + + .navbar-expand-sm .navbar-nav { + flex-direction: row + } + + .navbar-expand-sm .navbar-nav .dropdown-menu { + position: absolute + } + + .navbar-expand-sm .navbar-nav .nav-link { + padding-right: var(--mdb-navbar-nav-link-padding-x); + padding-left: var(--mdb-navbar-nav-link-padding-x) + } + + .navbar-expand-sm .navbar-nav-scroll { + overflow: visible + } + + .navbar-expand-sm .navbar-collapse { + display: flex!important; + flex-basis: auto + } + + .navbar-expand-sm .navbar-toggler { + display: none + } + + .navbar-expand-sm .offcanvas { + position: static; + z-index: auto; + flex-grow: 1; + width: auto!important; + height: auto!important; + visibility: visible!important; + background-color: transparent!important; + border: 0!important; + transform: none!important; + box-shadow: none; + transition: none + } + + .navbar-expand-sm .offcanvas .offcanvas-header { + display: none + } + + .navbar-expand-sm .offcanvas .offcanvas-body { + display: flex; + flex-grow: 0; + padding: 0; + overflow-y: visible + } +} + +@media(min-width: 768px) { + .navbar-expand-md { + flex-wrap:nowrap; + justify-content: flex-start + } + + .navbar-expand-md .navbar-nav { + flex-direction: row + } + + .navbar-expand-md .navbar-nav .dropdown-menu { + position: absolute + } + + .navbar-expand-md .navbar-nav .nav-link { + padding-right: var(--mdb-navbar-nav-link-padding-x); + padding-left: var(--mdb-navbar-nav-link-padding-x) + } + + .navbar-expand-md .navbar-nav-scroll { + overflow: visible + } + + .navbar-expand-md .navbar-collapse { + display: flex!important; + flex-basis: auto + } + + .navbar-expand-md .navbar-toggler { + display: none + } + + .navbar-expand-md .offcanvas { + position: static; + z-index: auto; + flex-grow: 1; + width: auto!important; + height: auto!important; + visibility: visible!important; + background-color: transparent!important; + border: 0!important; + transform: none!important; + box-shadow: none; + transition: none + } + + .navbar-expand-md .offcanvas .offcanvas-header { + display: none + } + + .navbar-expand-md .offcanvas .offcanvas-body { + display: flex; + flex-grow: 0; + padding: 0; + overflow-y: visible + } +} + +@media(min-width: 992px) { + .navbar-expand-lg { + flex-wrap:nowrap; + justify-content: flex-start + } + + .navbar-expand-lg .navbar-nav { + flex-direction: row + } + + .navbar-expand-lg .navbar-nav .dropdown-menu { + position: absolute + } + + .navbar-expand-lg .navbar-nav .nav-link { + padding-right: var(--mdb-navbar-nav-link-padding-x); + padding-left: var(--mdb-navbar-nav-link-padding-x) + } + + .navbar-expand-lg .navbar-nav-scroll { + overflow: visible + } + + .navbar-expand-lg .navbar-collapse { + display: flex!important; + flex-basis: auto + } + + .navbar-expand-lg .navbar-toggler { + display: none + } + + .navbar-expand-lg .offcanvas { + position: static; + z-index: auto; + flex-grow: 1; + width: auto!important; + height: auto!important; + visibility: visible!important; + background-color: transparent!important; + border: 0!important; + transform: none!important; + box-shadow: none; + transition: none + } + + .navbar-expand-lg .offcanvas .offcanvas-header { + display: none + } + + .navbar-expand-lg .offcanvas .offcanvas-body { + display: flex; + flex-grow: 0; + padding: 0; + overflow-y: visible + } +} + +@media(min-width: 1200px) { + .navbar-expand-xl { + flex-wrap:nowrap; + justify-content: flex-start + } + + .navbar-expand-xl .navbar-nav { + flex-direction: row + } + + .navbar-expand-xl .navbar-nav .dropdown-menu { + position: absolute + } + + .navbar-expand-xl .navbar-nav .nav-link { + padding-right: var(--mdb-navbar-nav-link-padding-x); + padding-left: var(--mdb-navbar-nav-link-padding-x) + } + + .navbar-expand-xl .navbar-nav-scroll { + overflow: visible + } + + .navbar-expand-xl .navbar-collapse { + display: flex!important; + flex-basis: auto + } + + .navbar-expand-xl .navbar-toggler { + display: none + } + + .navbar-expand-xl .offcanvas { + position: static; + z-index: auto; + flex-grow: 1; + width: auto!important; + height: auto!important; + visibility: visible!important; + background-color: transparent!important; + border: 0!important; + transform: none!important; + box-shadow: none; + transition: none + } + + .navbar-expand-xl .offcanvas .offcanvas-header { + display: none + } + + .navbar-expand-xl .offcanvas .offcanvas-body { + display: flex; + flex-grow: 0; + padding: 0; + overflow-y: visible + } +} + +@media(min-width: 1400px) { + .navbar-expand-xxl { + flex-wrap:nowrap; + justify-content: flex-start + } + + .navbar-expand-xxl .navbar-nav { + flex-direction: row + } + + .navbar-expand-xxl .navbar-nav .dropdown-menu { + position: absolute + } + + .navbar-expand-xxl .navbar-nav .nav-link { + padding-right: var(--mdb-navbar-nav-link-padding-x); + padding-left: var(--mdb-navbar-nav-link-padding-x) + } + + .navbar-expand-xxl .navbar-nav-scroll { + overflow: visible + } + + .navbar-expand-xxl .navbar-collapse { + display: flex!important; + flex-basis: auto + } + + .navbar-expand-xxl .navbar-toggler { + display: none + } + + .navbar-expand-xxl .offcanvas { + position: static; + z-index: auto; + flex-grow: 1; + width: auto!important; + height: auto!important; + visibility: visible!important; + background-color: transparent!important; + border: 0!important; + transform: none!important; + box-shadow: none; + transition: none + } + + .navbar-expand-xxl .offcanvas .offcanvas-header { + display: none + } + + .navbar-expand-xxl .offcanvas .offcanvas-body { + display: flex; + flex-grow: 0; + padding: 0; + overflow-y: visible + } +} + +.navbar-expand { + flex-wrap: nowrap; + justify-content: flex-start +} + +.navbar-expand .navbar-nav { + flex-direction: row +} + +.navbar-expand .navbar-nav .dropdown-menu { + position: absolute +} + +.navbar-expand .navbar-nav .nav-link { + padding-right: var(--mdb-navbar-nav-link-padding-x); + padding-left: var(--mdb-navbar-nav-link-padding-x) +} + +.navbar-expand .navbar-nav-scroll { + overflow: visible +} + +.navbar-expand .navbar-collapse { + display: flex!important; + flex-basis: auto +} + +.navbar-expand .navbar-toggler { + display: none +} + +.navbar-expand .offcanvas { + position: static; + z-index: auto; + flex-grow: 1; + width: auto!important; + height: auto!important; + visibility: visible!important; + background-color: transparent!important; + border: 0!important; + transform: none!important; + box-shadow: none; + transition: none +} + +.navbar-expand .offcanvas .offcanvas-header { + display: none +} + +.navbar-expand .offcanvas .offcanvas-body { + display: flex; + flex-grow: 0; + padding: 0; + overflow-y: visible +} + +.navbar-dark { + --mdb-navbar-color: hsla(0,0%,100%,0.55); + --mdb-navbar-hover-color: hsla(0,0%,100%,0.75); + --mdb-navbar-disabled-color: hsla(0,0%,100%,0.25); + --mdb-navbar-active-color: #fff; + --mdb-navbar-brand-color: #fff; + --mdb-navbar-brand-hover-color: #fff; + --mdb-navbar-toggler-border-color: hsla(0,0%,100%,0.1); + --mdb-navbar-toggler-icon-bg: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3E%3Cpath stroke='rgba(255, 255, 255, 0.55)' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3E%3C/svg%3E") +} + +.card { + --mdb-card-spacer-y: 1.5rem; + --mdb-card-spacer-x: 1.5rem; + --mdb-card-title-spacer-y: 0.5rem; + --mdb-card-border-width: 1px; + --mdb-card-border-color: var(--mdb-border-color-translucent); + --mdb-card-border-radius: 0.5rem; + --mdb-card-box-shadow: 0 2px 15px -3px rgba(0,0,0,0.07),0 10px 20px -2px rgba(0,0,0,0.04); + --mdb-card-inner-border-radius: calc(0.5rem - 1px); + --mdb-card-cap-padding-y: 0.75rem; + --mdb-card-cap-padding-x: 1.5rem; + --mdb-card-cap-bg: hsla(0,0%,100%,0); + --mdb-card-bg: #fff; + --mdb-card-img-overlay-padding: 1.5rem; + --mdb-card-group-margin: 0.75rem; + position: relative; + display: flex; + flex-direction: column; + min-width: 0; + height: var(--mdb-card-height); + word-wrap: break-word; + background-color: var(--mdb-card-bg); + background-clip: border-box; + border: var(--mdb-card-border-width) solid var(--mdb-card-border-color); + border-radius: var(--mdb-card-border-radius); + box-shadow: var(--mdb-card-box-shadow) +} + +.card>hr { + margin-right: 0; + margin-left: 0 +} + +.card>.list-group { + border-top: inherit; + border-bottom: inherit +} + +.card>.list-group:first-child { + border-top-width: 0; + border-top-left-radius: var(--mdb-card-inner-border-radius); + border-top-right-radius: var(--mdb-card-inner-border-radius) +} + +.card>.list-group:last-child { + border-bottom-width: 0; + border-bottom-right-radius: var(--mdb-card-inner-border-radius); + border-bottom-left-radius: var(--mdb-card-inner-border-radius) +} + +.card>.card-header+.list-group,.card>.list-group+.card-footer { + border-top: 0 +} + +.card-body { + flex: 1 1 auto; + padding: var(--mdb-card-spacer-y) var(--mdb-card-spacer-x); + color: var(--mdb-card-color) +} + +.card-title { + margin-bottom: var(--mdb-card-title-spacer-y) +} + +.card-subtitle { + margin-top: calc(var(--mdb-card-title-spacer-y)*-0.5) +} + +.card-subtitle,.card-text:last-child { + margin-bottom: 0 +} + +.card-link+.card-link { + margin-left: var(--mdb-card-spacer-x) +} + +.card-header { + padding: var(--mdb-card-cap-padding-y) var(--mdb-card-cap-padding-x); + margin-bottom: 0; + color: var(--mdb-card-cap-color); + background-color: var(--mdb-card-cap-bg); + border-bottom: var(--mdb-card-border-width) solid var(--mdb-card-border-color) +} + +.card-header:first-child { + border-radius: var(--mdb-card-inner-border-radius) var(--mdb-card-inner-border-radius) 0 0 +} + +.card-footer { + padding: var(--mdb-card-cap-padding-y) var(--mdb-card-cap-padding-x); + color: var(--mdb-card-cap-color); + background-color: var(--mdb-card-cap-bg); + border-top: var(--mdb-card-border-width) solid var(--mdb-card-border-color) +} + +.card-footer:last-child { + border-radius: 0 0 var(--mdb-card-inner-border-radius) var(--mdb-card-inner-border-radius) +} + +.card-header-tabs { + margin-right: calc(var(--mdb-card-cap-padding-x)*-0.5); + margin-bottom: calc(var(--mdb-card-cap-padding-y)*-1); + margin-left: calc(var(--mdb-card-cap-padding-x)*-0.5); + border-bottom: 0 +} + +.card-header-tabs .nav-link.active { + background-color: var(--mdb-card-bg); + border-bottom-color: var(--mdb-card-bg) +} + +.card-header-pills { + margin-right: calc(var(--mdb-card-cap-padding-x)*-0.5); + margin-left: calc(var(--mdb-card-cap-padding-x)*-0.5) +} + +.card-img-overlay { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + padding: var(--mdb-card-img-overlay-padding); + border-radius: var(--mdb-card-inner-border-radius) +} + +.card-img,.card-img-bottom,.card-img-top { + width: 100% +} + +.card-img,.card-img-top { + border-top-left-radius: var(--mdb-card-inner-border-radius); + border-top-right-radius: var(--mdb-card-inner-border-radius) +} + +.card-img,.card-img-bottom { + border-bottom-right-radius: var(--mdb-card-inner-border-radius); + border-bottom-left-radius: var(--mdb-card-inner-border-radius) +} + +.card-group>.card { + margin-bottom: var(--mdb-card-group-margin) +} + +@media(min-width: 576px) { + .card-group { + display:flex; + flex-flow: row wrap + } + + .card-group>.card { + flex: 1 0 0%; + margin-bottom: 0 + } + + .card-group>.card+.card { + margin-left: 0; + border-left: 0 + } + + .card-group>.card:not(:last-child) { + border-top-right-radius: 0; + border-bottom-right-radius: 0 + } + + .card-group>.card:not(:last-child) .card-header,.card-group>.card:not(:last-child) .card-img-top { + border-top-right-radius: 0 + } + + .card-group>.card:not(:last-child) .card-footer,.card-group>.card:not(:last-child) .card-img-bottom { + border-bottom-right-radius: 0 + } + + .card-group>.card:not(:first-child) { + border-top-left-radius: 0; + border-bottom-left-radius: 0 + } + + .card-group>.card:not(:first-child) .card-header,.card-group>.card:not(:first-child) .card-img-top { + border-top-left-radius: 0 + } + + .card-group>.card:not(:first-child) .card-footer,.card-group>.card:not(:first-child) .card-img-bottom { + border-bottom-left-radius: 0 + } +} + +.breadcrumb { + --mdb-breadcrumb-padding-x: 0; + --mdb-breadcrumb-padding-y: 0; + --mdb-breadcrumb-margin-bottom: 1rem; + --mdb-breadcrumb-divider-color: #757575; + --mdb-breadcrumb-item-padding-x: 0.5rem; + --mdb-breadcrumb-item-active-color: #757575; + display: flex; + flex-wrap: wrap; + padding: var(--mdb-breadcrumb-padding-y) var(--mdb-breadcrumb-padding-x); + margin-bottom: var(--mdb-breadcrumb-margin-bottom); + font-size: var(--mdb-breadcrumb-font-size); + list-style: none; + background-color: var(--mdb-breadcrumb-bg); + border-radius: var(--mdb-breadcrumb-border-radius) +} + +.breadcrumb-item+.breadcrumb-item { + padding-left: var(--mdb-breadcrumb-item-padding-x) +} + +.breadcrumb-item+.breadcrumb-item:before { + float: left; + padding-right: var(--mdb-breadcrumb-item-padding-x); + color: var(--mdb-breadcrumb-divider-color); + content: var(--mdb-breadcrumb-divider,"/") +} + +.breadcrumb-item.active { + color: var(--mdb-breadcrumb-item-active-color) +} + +.pagination { + --mdb-pagination-padding-x: 0.75rem; + --mdb-pagination-padding-y: 0.375rem; + --mdb-pagination-font-size: 0.9rem; + --mdb-pagination-color: #4f4f4f; + --mdb-pagination-bg: #fff; + --mdb-pagination-border-width: 1px; + --mdb-pagination-border-color: #e0e0e0; + --mdb-pagination-hover-color: #4f4f4f; + --mdb-pagination-hover-bg: #eee; + --mdb-pagination-hover-border-color: #e0e0e0; + --mdb-pagination-focus-color: var(--mdb-link-hover-color); + --mdb-pagination-focus-bg: #eee; + --mdb-pagination-focus-box-shadow: 0 0 0 0.25rem rgba(59,113,202,0.25); + --mdb-pagination-active-color: #285192; + --mdb-pagination-active-bg: #e3ebf7; + --mdb-pagination-active-border-color: #e3ebf7; + --mdb-pagination-disabled-color: #757575; + --mdb-pagination-disabled-bg: #fff; + --mdb-pagination-disabled-border-color: #e0e0e0; + display: flex; + padding-left: 0; + list-style: none +} + +.page-link { + position: relative; + display: block; + padding: var(--mdb-pagination-padding-y) var(--mdb-pagination-padding-x); + font-size: var(--mdb-pagination-font-size); + color: var(--mdb-pagination-color); + background-color: var(--mdb-pagination-bg); + border: var(--mdb-pagination-border-width) solid var(--mdb-pagination-border-color); + transition: all .3s linear +} + +@media(prefers-reduced-motion:reduce) { + .page-link { + transition: none + } +} + +.page-link:hover { + z-index: 2; + color: var(--mdb-pagination-hover-color); + background-color: var(--mdb-pagination-hover-bg); + border-color: var(--mdb-pagination-hover-border-color) +} + +.page-link:focus { + z-index: 3; + color: var(--mdb-pagination-focus-color); + background-color: var(--mdb-pagination-focus-bg); + outline: 0; + box-shadow: var(--mdb-pagination-focus-box-shadow) +} + +.active>.page-link,.page-link.active { + z-index: 3; + color: var(--mdb-pagination-active-color); + background-color: var(--mdb-pagination-active-bg); + border-color: var(--mdb-pagination-active-border-color) +} + +.disabled>.page-link,.page-link.disabled { + color: var(--mdb-pagination-disabled-color); + pointer-events: none; + background-color: var(--mdb-pagination-disabled-bg); + border-color: var(--mdb-pagination-disabled-border-color) +} + +.page-item:not(:first-child) .page-link { + margin-left: -1px +} + +.pagination-lg { + --mdb-pagination-padding-x: 1.5rem; + --mdb-pagination-padding-y: 0.75rem; + --mdb-pagination-font-size: 1.25rem; + --mdb-pagination-border-radius: 0.5rem +} + +.pagination-sm { + --mdb-pagination-padding-x: 0.5rem; + --mdb-pagination-padding-y: 0.25rem; + --mdb-pagination-font-size: 0.875rem; + --mdb-pagination-border-radius: 0.25rem +} + +.badge { + --mdb-badge-padding-x: 0.65em; + --mdb-badge-padding-y: 0.35em; + --mdb-badge-font-size: 0.75em; + --mdb-badge-font-weight: 700; + --mdb-badge-color: #fff; + --mdb-badge-border-radius: 0.27rem; + display: inline-block; + padding: var(--mdb-badge-padding-y) var(--mdb-badge-padding-x); + font-size: var(--mdb-badge-font-size); + font-weight: var(--mdb-badge-font-weight); + line-height: 1; + color: var(--mdb-badge-color); + text-align: center; + white-space: nowrap; + vertical-align: baseline; + border-radius: var(--mdb-badge-border-radius) +} + +.badge:empty { + display: none +} + +.btn .badge { + position: relative; + top: -1px +} + +.alert { + --mdb-alert-bg: transparent; + --mdb-alert-padding-x: 1.5rem; + --mdb-alert-padding-y: 1.25rem; + --mdb-alert-margin-bottom: 1rem; + --mdb-alert-color: inherit; + --mdb-alert-border-color: transparent; + --mdb-alert-border: 1px solid var(--mdb-alert-border-color); + --mdb-alert-border-radius: 0.5rem; + position: relative; + padding: var(--mdb-alert-padding-y) var(--mdb-alert-padding-x); + margin-bottom: var(--mdb-alert-margin-bottom); + color: var(--mdb-alert-color); + background-color: var(--mdb-alert-bg); + border: var(--mdb-alert-border); + border-radius: var(--mdb-alert-border-radius) +} + +.alert-heading { + color: inherit +} + +.alert-link { + font-weight: 700 +} + +.alert-dismissible { + padding-right: 4.5rem +} + +.alert-dismissible .btn-close { + position: absolute; + top: 0; + right: 0; + z-index: 2; + padding: 1.5625rem 1.5rem +} + +.alert-primary { + --mdb-alert-color: #234479; + --mdb-alert-bg: #d8e3f4; + --mdb-alert-border-color: #c4d4ef +} + +.alert-primary .alert-link { + color: #1c3661 +} + +.alert-secondary { + --mdb-alert-color: #5f646b; + --mdb-alert-bg: #ecedf0; + --mdb-alert-border-color: #e2e4e8 +} + +.alert-secondary .alert-link { + color: #4c5056 +} + +.alert-success { + --mdb-alert-color: #0c622e; + --mdb-alert-bg: #d0eddb; + --mdb-alert-border-color: #b9e4ca +} + +.alert-success .alert-link { + color: #0a4e25 +} + +.alert-danger { + --mdb-alert-color: #842e3c; + --mdb-alert-bg: #f8dbe0; + --mdb-alert-border-color: #f5c9d1 +} + +.alert-danger .alert-link { + color: #6a2530 +} + +.alert-warning { + --mdb-alert-color: #896110; + --mdb-alert-bg: #faecd1; + --mdb-alert-border-color: #f7e3bb +} + +.alert-warning .alert-link { + color: #6e4e0d +} + +.alert-info { + --mdb-alert-color: #326c7f; + --mdb-alert-bg: #ddf0f6; + --mdb-alert-border-color: #cce9f2 +} + +.alert-info .alert-link { + color: #285666 +} + +.alert-light { + --mdb-alert-color: #646464; + --mdb-alert-bg: #fefefe; + --mdb-alert-border-color: #fefefe +} + +.alert-light .alert-link { + color: #505050 +} + +.alert-dark { + --mdb-alert-color: #1f1b1b; + --mdb-alert-bg: #d6d5d5; + --mdb-alert-border-color: #c2c0c0 +} + +.alert-dark .alert-link { + color: #191616 +} + +.accordion { + --mdb-accordion-color: #4f4f4f; + --mdb-accordion-bg: #fff; + --mdb-accordion-transition: color 0.15s ease-in-out,background-color 0.15s ease-in-out,border-color 0.15s ease-in-out,box-shadow 0.15s ease-in-out,border-radius 0.15s ease; + --mdb-accordion-border-color: var(--mdb-border-color); + --mdb-accordion-border-width: 1px; + --mdb-accordion-border-radius: 0.5rem; + --mdb-accordion-inner-border-radius: calc(0.5rem - 1px); + --mdb-accordion-btn-padding-x: 1.5rem; + --mdb-accordion-btn-padding-y: 1.15rem; + --mdb-accordion-btn-color: #4f4f4f; + --mdb-accordion-btn-bg: var(--mdb-accordion-bg); + --mdb-accordion-btn-icon: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%234f4f4f'%3E%3Cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 01.708 0L8 10.293l5.646-5.647a.5.5 0 01.708.708l-6 6a.5.5 0 01-.708 0l-6-6a.5.5 0 010-.708z'/%3E%3C/svg%3E"); + --mdb-accordion-btn-icon-width: 1.25rem; + --mdb-accordion-btn-icon-transform: rotate(-180deg); + --mdb-accordion-btn-icon-transition: transform 0.2s ease-in-out; + --mdb-accordion-btn-active-icon: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%233b71ca'%3E%3Cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 01.708 0L8 10.293l5.646-5.647a.5.5 0 01.708.708l-6 6a.5.5 0 01-.708 0l-6-6a.5.5 0 010-.708z'/%3E%3C/svg%3E"); + --mdb-accordion-btn-focus-border-color: #3b71ca; + --mdb-accordion-btn-focus-box-shadow: inset 0 -1px 0 rgba(0,0,0,0.125); + --mdb-accordion-body-padding-x: 1.5rem; + --mdb-accordion-body-padding-y: 1.15rem; + --mdb-accordion-active-color: #3b71ca; + --mdb-accordion-active-bg: #fff +} + +.accordion-button { + position: relative; + display: flex; + align-items: center; + width: 100%; + padding: var(--mdb-accordion-btn-padding-y) var(--mdb-accordion-btn-padding-x); + font-size: 1rem; + color: var(--mdb-accordion-btn-color); + text-align: left; + background-color: var(--mdb-accordion-btn-bg); + border: 0; + border-radius: 0; + overflow-anchor: none; + transition: var(--mdb-accordion-transition) +} + +@media(prefers-reduced-motion:reduce) { + .accordion-button { + transition: none + } +} + +.accordion-button:not(.collapsed) { + color: var(--mdb-accordion-active-color); + background-color: var(--mdb-accordion-active-bg); + box-shadow: inset 0 calc(var(--mdb-accordion-border-width)*-1) 0 var(--mdb-accordion-border-color) +} + +.accordion-button:not(.collapsed):after { + background-image: var(--mdb-accordion-btn-active-icon); + transform: var(--mdb-accordion-btn-icon-transform) +} + +.accordion-button:after { + flex-shrink: 0; + width: var(--mdb-accordion-btn-icon-width); + height: var(--mdb-accordion-btn-icon-width); + margin-left: auto; + content: ""; + background-image: var(--mdb-accordion-btn-icon); + background-repeat: no-repeat; + background-size: var(--mdb-accordion-btn-icon-width); + transition: var(--mdb-accordion-btn-icon-transition) +} + +@media(prefers-reduced-motion:reduce) { + .accordion-button:after { + transition: none + } +} + +.accordion-button:hover { + z-index: 2 +} + +.accordion-button:focus { + z-index: 3; + box-shadow: var(--mdb-accordion-btn-focus-box-shadow) +} + +.accordion-header { + margin-bottom: 0 +} + +.accordion-item { + color: var(--mdb-accordion-color); + background-color: var(--mdb-accordion-bg); + border: var(--mdb-accordion-border-width) solid var(--mdb-accordion-border-color) +} + +.accordion-item:first-of-type { + border-top-left-radius: var(--mdb-accordion-border-radius); + border-top-right-radius: var(--mdb-accordion-border-radius) +} + +.accordion-item:first-of-type .accordion-button { + border-top-left-radius: var(--mdb-accordion-inner-border-radius); + border-top-right-radius: var(--mdb-accordion-inner-border-radius) +} + +.accordion-item:not(:first-of-type) { + border-top: 0 +} + +.accordion-item:last-of-type { + border-bottom-right-radius: var(--mdb-accordion-border-radius); + border-bottom-left-radius: var(--mdb-accordion-border-radius) +} + +.accordion-item:last-of-type .accordion-button.collapsed { + border-bottom-right-radius: var(--mdb-accordion-inner-border-radius); + border-bottom-left-radius: var(--mdb-accordion-inner-border-radius) +} + +.accordion-item:last-of-type .accordion-collapse { + border-bottom-right-radius: var(--mdb-accordion-border-radius); + border-bottom-left-radius: var(--mdb-accordion-border-radius) +} + +.accordion-body { + padding: var(--mdb-accordion-body-padding-y) var(--mdb-accordion-body-padding-x) +} + +.accordion-flush .accordion-collapse { + border-width: 0 +} + +.accordion-flush .accordion-item { + border-right: 0; + border-left: 0; + border-radius: 0 +} + +.accordion-flush .accordion-item:first-child { + border-top: 0 +} + +.accordion-flush .accordion-item:last-child { + border-bottom: 0 +} + +.accordion-flush .accordion-item .accordion-button,.accordion-flush .accordion-item .accordion-button.collapsed { + border-radius: 0 +} + +@keyframes progress-bar-stripes { + 0% { + background-position-x: 4px + } +} + +.progress { + --mdb-progress-height: 4px; + --mdb-progress-font-size: 0.75rem; + --mdb-progress-bg: #eee; + --mdb-progress-border-radius: 0.25rem; + --mdb-progress-box-shadow: inset 0 1px 2px rgba(0,0,0,0.075); + --mdb-progress-bar-color: #fff; + --mdb-progress-bar-bg: #3b71ca; + --mdb-progress-bar-transition: width 0.6s ease; + height: var(--mdb-progress-height); + font-size: var(--mdb-progress-font-size); + background-color: var(--mdb-progress-bg); + border-radius: var(--mdb-progress-border-radius); + box-shadow: var(--mdb-progress-box-shadow) +} + +.progress,.progress-bar { + display: flex; + overflow: hidden +} + +.progress-bar { + flex-direction: column; + justify-content: center; + color: var(--mdb-progress-bar-color); + text-align: center; + white-space: nowrap; + background-color: var(--mdb-progress-bar-bg); + transition: var(--mdb-progress-bar-transition) +} + +@media(prefers-reduced-motion:reduce) { + .progress-bar { + transition: none + } +} + +.progress-bar-striped { + background-image: linear-gradient(45deg,hsla(0,0%,100%,.15) 25%,transparent 0,transparent 50%,hsla(0,0%,100%,.15) 0,hsla(0,0%,100%,.15) 75%,transparent 0,transparent); + background-size: var(--mdb-progress-height) var(--mdb-progress-height) +} + +.progress-bar-animated { + animation: progress-bar-stripes 1s linear infinite +} + +@media(prefers-reduced-motion:reduce) { + .progress-bar-animated { + animation: none + } +} + +.placeholder { + display: inline-block; + min-height: 1em; + vertical-align: middle; + cursor: wait; + background-color: currentcolor; + opacity: .5 +} + +.placeholder.btn:before { + display: inline-block; + content: "" +} + +.placeholder-xs { + min-height: .6em +} + +.placeholder-sm { + min-height: .8em +} + +.placeholder-lg { + min-height: 1.2em +} + +.placeholder-glow .placeholder { + animation: placeholder-glow 2s ease-in-out infinite +} + +@keyframes placeholder-glow { + 50% { + opacity: .2 + } +} + +.placeholder-wave { + -webkit-mask-image: linear-gradient(130deg,#000 55%,rgba(0,0,0,.8) 75%,#000 95%); + mask-image: linear-gradient(130deg,#000 55%,rgba(0,0,0,.8) 75%,#000 95%); + -webkit-mask-size: 200% 100%; + mask-size: 200% 100%; + animation: placeholder-wave 2s linear infinite +} + +@keyframes placeholder-wave { + to { + -webkit-mask-position: -200% 0; + mask-position: -200% 0 + } +} + +.list-group { + --mdb-list-group-color: #4f4f4f; + --mdb-list-group-bg: #fff; + --mdb-list-group-border-color: rgba(0,0,0,0.125); + --mdb-list-group-border-width: 1px; + --mdb-list-group-border-radius: 0.5rem; + --mdb-list-group-item-padding-x: 1.5rem; + --mdb-list-group-item-padding-y: 0.5rem; + --mdb-list-group-action-color: #616161; + --mdb-list-group-action-hover-color: #616161; + --mdb-list-group-action-hover-bg: #f5f5f5; + --mdb-list-group-action-active-color: #4f4f4f; + --mdb-list-group-action-active-bg: #eee; + --mdb-list-group-disabled-color: #757575; + --mdb-list-group-disabled-bg: #fff; + --mdb-list-group-active-color: #2c58a0; + --mdb-list-group-active-bg: #dfe7f6; + --mdb-list-group-active-border-color: #dfe7f6; + display: flex; + flex-direction: column; + padding-left: 0; + margin-bottom: 0; + border-radius: var(--mdb-list-group-border-radius) +} + +.list-group-numbered { + list-style-type: none; + counter-reset: section +} + +.list-group-numbered>.list-group-item:before { + content: counters(section,".") ". "; + counter-increment: section +} + +.list-group-item-action { + width: 100%; + color: var(--mdb-list-group-action-color); + text-align: inherit +} + +.list-group-item-action:focus,.list-group-item-action:hover { + z-index: 1; + color: var(--mdb-list-group-action-hover-color); + text-decoration: none; + background-color: var(--mdb-list-group-action-hover-bg) +} + +.list-group-item-action:active { + color: var(--mdb-list-group-action-active-color); + background-color: var(--mdb-list-group-action-active-bg) +} + +.list-group-item { + position: relative; + display: block; + padding: var(--mdb-list-group-item-padding-y) var(--mdb-list-group-item-padding-x); + color: var(--mdb-list-group-color); + background-color: var(--mdb-list-group-bg); + border: var(--mdb-list-group-border-width) solid var(--mdb-list-group-border-color) +} + +.list-group-item:first-child { + border-top-left-radius: inherit; + border-top-right-radius: inherit +} + +.list-group-item:last-child { + border-bottom-right-radius: inherit; + border-bottom-left-radius: inherit +} + +.list-group-item.disabled,.list-group-item:disabled { + color: var(--mdb-list-group-disabled-color); + pointer-events: none; + background-color: var(--mdb-list-group-disabled-bg) +} + +.list-group-item.active { + z-index: 2; + color: var(--mdb-list-group-active-color); + background-color: var(--mdb-list-group-active-bg); + border-color: var(--mdb-list-group-active-border-color) +} + +.list-group-item+.list-group-item { + border-top-width: 0 +} + +.list-group-item+.list-group-item.active { + margin-top: calc(var(--mdb-list-group-border-width)*-1); + border-top-width: var(--mdb-list-group-border-width) +} + +.list-group-horizontal { + flex-direction: row +} + +.list-group-horizontal>.list-group-item:first-child:not(:last-child) { + border-bottom-left-radius: var(--mdb-list-group-border-radius); + border-top-right-radius: 0 +} + +.list-group-horizontal>.list-group-item:last-child:not(:first-child) { + border-top-right-radius: var(--mdb-list-group-border-radius); + border-bottom-left-radius: 0 +} + +.list-group-horizontal>.list-group-item.active { + margin-top: 0 +} + +.list-group-horizontal>.list-group-item+.list-group-item { + border-top-width: var(--mdb-list-group-border-width); + border-left-width: 0 +} + +.list-group-horizontal>.list-group-item+.list-group-item.active { + margin-left: calc(var(--mdb-list-group-border-width)*-1); + border-left-width: var(--mdb-list-group-border-width) +} + +@media(min-width: 576px) { + .list-group-horizontal-sm { + flex-direction:row + } + + .list-group-horizontal-sm>.list-group-item:first-child:not(:last-child) { + border-bottom-left-radius: var(--mdb-list-group-border-radius); + border-top-right-radius: 0 + } + + .list-group-horizontal-sm>.list-group-item:last-child:not(:first-child) { + border-top-right-radius: var(--mdb-list-group-border-radius); + border-bottom-left-radius: 0 + } + + .list-group-horizontal-sm>.list-group-item.active { + margin-top: 0 + } + + .list-group-horizontal-sm>.list-group-item+.list-group-item { + border-top-width: var(--mdb-list-group-border-width); + border-left-width: 0 + } + + .list-group-horizontal-sm>.list-group-item+.list-group-item.active { + margin-left: calc(var(--mdb-list-group-border-width)*-1); + border-left-width: var(--mdb-list-group-border-width) + } +} + +@media(min-width: 768px) { + .list-group-horizontal-md { + flex-direction:row + } + + .list-group-horizontal-md>.list-group-item:first-child:not(:last-child) { + border-bottom-left-radius: var(--mdb-list-group-border-radius); + border-top-right-radius: 0 + } + + .list-group-horizontal-md>.list-group-item:last-child:not(:first-child) { + border-top-right-radius: var(--mdb-list-group-border-radius); + border-bottom-left-radius: 0 + } + + .list-group-horizontal-md>.list-group-item.active { + margin-top: 0 + } + + .list-group-horizontal-md>.list-group-item+.list-group-item { + border-top-width: var(--mdb-list-group-border-width); + border-left-width: 0 + } + + .list-group-horizontal-md>.list-group-item+.list-group-item.active { + margin-left: calc(var(--mdb-list-group-border-width)*-1); + border-left-width: var(--mdb-list-group-border-width) + } +} + +@media(min-width: 992px) { + .list-group-horizontal-lg { + flex-direction:row + } + + .list-group-horizontal-lg>.list-group-item:first-child:not(:last-child) { + border-bottom-left-radius: var(--mdb-list-group-border-radius); + border-top-right-radius: 0 + } + + .list-group-horizontal-lg>.list-group-item:last-child:not(:first-child) { + border-top-right-radius: var(--mdb-list-group-border-radius); + border-bottom-left-radius: 0 + } + + .list-group-horizontal-lg>.list-group-item.active { + margin-top: 0 + } + + .list-group-horizontal-lg>.list-group-item+.list-group-item { + border-top-width: var(--mdb-list-group-border-width); + border-left-width: 0 + } + + .list-group-horizontal-lg>.list-group-item+.list-group-item.active { + margin-left: calc(var(--mdb-list-group-border-width)*-1); + border-left-width: var(--mdb-list-group-border-width) + } +} + +@media(min-width: 1200px) { + .list-group-horizontal-xl { + flex-direction:row + } + + .list-group-horizontal-xl>.list-group-item:first-child:not(:last-child) { + border-bottom-left-radius: var(--mdb-list-group-border-radius); + border-top-right-radius: 0 + } + + .list-group-horizontal-xl>.list-group-item:last-child:not(:first-child) { + border-top-right-radius: var(--mdb-list-group-border-radius); + border-bottom-left-radius: 0 + } + + .list-group-horizontal-xl>.list-group-item.active { + margin-top: 0 + } + + .list-group-horizontal-xl>.list-group-item+.list-group-item { + border-top-width: var(--mdb-list-group-border-width); + border-left-width: 0 + } + + .list-group-horizontal-xl>.list-group-item+.list-group-item.active { + margin-left: calc(var(--mdb-list-group-border-width)*-1); + border-left-width: var(--mdb-list-group-border-width) + } +} + +@media(min-width: 1400px) { + .list-group-horizontal-xxl { + flex-direction:row + } + + .list-group-horizontal-xxl>.list-group-item:first-child:not(:last-child) { + border-bottom-left-radius: var(--mdb-list-group-border-radius); + border-top-right-radius: 0 + } + + .list-group-horizontal-xxl>.list-group-item:last-child:not(:first-child) { + border-top-right-radius: var(--mdb-list-group-border-radius); + border-bottom-left-radius: 0 + } + + .list-group-horizontal-xxl>.list-group-item.active { + margin-top: 0 + } + + .list-group-horizontal-xxl>.list-group-item+.list-group-item { + border-top-width: var(--mdb-list-group-border-width); + border-left-width: 0 + } + + .list-group-horizontal-xxl>.list-group-item+.list-group-item.active { + margin-left: calc(var(--mdb-list-group-border-width)*-1); + border-left-width: var(--mdb-list-group-border-width) + } +} + +.list-group-flush { + border-radius: 0 +} + +.list-group-flush>.list-group-item { + border-left-width: 0; + border-bottom-width: var(--mdb-list-group-border-width); + border-right-width: 0; + border-top-width: 0 +} + +.list-group-flush>.list-group-item:last-child { + border-bottom-width: 0 +} + +.list-group-item-primary { + color: #234479; + background-color: #d8e3f4 +} + +.list-group-item-primary.list-group-item-action:focus,.list-group-item-primary.list-group-item-action:hover { + color: #234479; + background-color: #c2ccdc +} + +.list-group-item-primary.list-group-item-action.active { + color: #fff; + background-color: #234479; + border-color: #234479 +} + +.list-group-item-secondary { + color: #5f646b; + background-color: #ecedf0 +} + +.list-group-item-secondary.list-group-item-action:focus,.list-group-item-secondary.list-group-item-action:hover { + color: #5f646b; + background-color: #d4d5d8 +} + +.list-group-item-secondary.list-group-item-action.active { + color: #fff; + background-color: #5f646b; + border-color: #5f646b +} + +.list-group-item-success { + color: #0c622e; + background-color: #d0eddb +} + +.list-group-item-success.list-group-item-action:focus,.list-group-item-success.list-group-item-action:hover { + color: #0c622e; + background-color: #bbd5c5 +} + +.list-group-item-success.list-group-item-action.active { + color: #fff; + background-color: #0c622e; + border-color: #0c622e +} + +.list-group-item-danger { + color: #842e3c; + background-color: #f8dbe0 +} + +.list-group-item-danger.list-group-item-action:focus,.list-group-item-danger.list-group-item-action:hover { + color: #842e3c; + background-color: #dfc5ca +} + +.list-group-item-danger.list-group-item-action.active { + color: #fff; + background-color: #842e3c; + border-color: #842e3c +} + +.list-group-item-warning { + color: #896110; + background-color: #faecd1 +} + +.list-group-item-warning.list-group-item-action:focus,.list-group-item-warning.list-group-item-action:hover { + color: #896110; + background-color: #e1d4bc +} + +.list-group-item-warning.list-group-item-action.active { + color: #fff; + background-color: #896110; + border-color: #896110 +} + +.list-group-item-info { + color: #326c7f; + background-color: #ddf0f6 +} + +.list-group-item-info.list-group-item-action:focus,.list-group-item-info.list-group-item-action:hover { + color: #326c7f; + background-color: #c7d8dd +} + +.list-group-item-info.list-group-item-action.active { + color: #fff; + background-color: #326c7f; + border-color: #326c7f +} + +.list-group-item-light { + color: #646464; + background-color: #fefefe +} + +.list-group-item-light.list-group-item-action:focus,.list-group-item-light.list-group-item-action:hover { + color: #646464; + background-color: #e5e5e5 +} + +.list-group-item-light.list-group-item-action.active { + color: #fff; + background-color: #646464; + border-color: #646464 +} + +.list-group-item-dark { + color: #1f1b1b; + background-color: #d6d5d5 +} + +.list-group-item-dark.list-group-item-action:focus,.list-group-item-dark.list-group-item-action:hover { + color: #1f1b1b; + background-color: #c1c0c0 +} + +.list-group-item-dark.list-group-item-action.active { + color: #fff; + background-color: #1f1b1b; + border-color: #1f1b1b +} + +.btn-close { + box-sizing: content-box; + width: 1em; + height: 1em; + padding: .25em; + color: #000; + background: transparent url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M.293.293a1 1 0 011.414 0L8 6.586 14.293.293a1 1 0 111.414 1.414L9.414 8l6.293 6.293a1 1 0 01-1.414 1.414L8 9.414l-6.293 6.293a1 1 0 01-1.414-1.414L6.586 8 .293 1.707a1 1 0 010-1.414z'/%3E%3C/svg%3E") 50%/1em auto no-repeat; + border: 0; + border-radius: .25rem; + opacity: .5 +} + +.btn-close:hover { + color: #000; + text-decoration: none; + opacity: .75 +} + +.btn-close:focus { + outline: 0; + box-shadow: 0 0 0 .25rem rgba(59,113,202,.25); + opacity: 1 +} + +.btn-close.disabled,.btn-close:disabled { + pointer-events: none; + -webkit-user-select: none; + -moz-user-select: none; + user-select: none; + opacity: .25 +} + +.btn-close-white { + filter: invert(1) grayscale(100%) brightness(200%) +} + +.toast { + --mdb-toast-zindex: 1060; + --mdb-toast-padding-x: 1rem; + --mdb-toast-padding-y: 0.65rem; + --mdb-toast-spacing: 1.5rem; + --mdb-toast-max-width: 350px; + --mdb-toast-font-size: 0.875rem; + --mdb-toast-bg: #fff; + --mdb-toast-border-width: 1px; + --mdb-toast-border-color: var(--mdb-border-color-translucent); + --mdb-toast-border-radius: 0.5rem; + --mdb-toast-box-shadow: 0 2px 15px -3px rgba(0,0,0,0.07),0 10px 20px -2px rgba(0,0,0,0.04); + --mdb-toast-header-color: #757575; + --mdb-toast-header-bg: #fff; + --mdb-toast-header-border-color: rgba(0,0,0,0.05); + width: var(--mdb-toast-max-width); + max-width: 100%; + font-size: var(--mdb-toast-font-size); + color: var(--mdb-toast-color); + pointer-events: auto; + background-color: var(--mdb-toast-bg); + background-clip: padding-box; + border: var(--mdb-toast-border-width) solid var(--mdb-toast-border-color); + box-shadow: var(--mdb-toast-box-shadow); + border-radius: var(--mdb-toast-border-radius) +} + +.toast.showing { + opacity: 0 +} + +.toast:not(.show) { + display: none +} + +.toast-container { + --mdb-toast-zindex: 1060; + position: absolute; + z-index: var(--mdb-toast-zindex); + width: -webkit-max-content; + width: -moz-max-content; + width: max-content; + max-width: 100%; + pointer-events: none +} + +.toast-container>:not(:last-child) { + margin-bottom: var(--mdb-toast-spacing) +} + +.toast-header { + display: flex; + align-items: center; + padding: var(--mdb-toast-padding-y) var(--mdb-toast-padding-x); + color: var(--mdb-toast-header-color); + background-color: var(--mdb-toast-header-bg); + background-clip: padding-box; + border-bottom: var(--mdb-toast-border-width) solid var(--mdb-toast-header-border-color); + border-top-left-radius: calc(var(--mdb-toast-border-radius) - var(--mdb-toast-border-width)); + border-top-right-radius: calc(var(--mdb-toast-border-radius) - var(--mdb-toast-border-width)) +} + +.toast-header .btn-close { + margin-right: calc(var(--mdb-toast-padding-x)*-0.5); + margin-left: var(--mdb-toast-padding-x) +} + +.toast-body { + padding: var(--mdb-toast-padding-x); + word-wrap: break-word +} + +.modal { + --mdb-modal-zindex: 1055; + --mdb-modal-width: 500px; + --mdb-modal-padding: 1rem; + --mdb-modal-margin: 0.5rem; + --mdb-modal-bg: #fff; + --mdb-modal-border-color: var(--mdb-border-color-translucent); + --mdb-modal-border-width: 1px; + --mdb-modal-border-radius: 0.5rem; + --mdb-modal-box-shadow: 0 0.125rem 0.25rem rgba(0,0,0,0.075); + --mdb-modal-inner-border-radius: calc(0.5rem - 1px); + --mdb-modal-header-padding-x: 1rem; + --mdb-modal-header-padding-y: 1rem; + --mdb-modal-header-padding: 1rem 1rem; + --mdb-modal-header-border-color: #f5f5f5; + --mdb-modal-header-border-width: 2px; + --mdb-modal-title-line-height: 1.6; + --mdb-modal-footer-gap: 0.5rem; + --mdb-modal-footer-border-color: #f5f5f5; + --mdb-modal-footer-border-width: 2px; + position: fixed; + top: 0; + left: 0; + z-index: var(--mdb-modal-zindex); + display: none; + width: 100%; + height: 100%; + overflow-x: hidden; + overflow-y: auto; + outline: 0 +} + +.modal-dialog { + position: relative; + width: auto; + margin: var(--mdb-modal-margin); + pointer-events: none +} + +.modal.fade .modal-dialog { + transition: transform .3s ease-out; + transform: translateY(-50px) +} + +@media(prefers-reduced-motion:reduce) { + .modal.fade .modal-dialog { + transition: none + } +} + +.modal.show .modal-dialog { + transform: none +} + +.modal.modal-static .modal-dialog { + transform: scale(1.02) +} + +.modal-dialog-scrollable { + height: calc(100% - var(--mdb-modal-margin)*2) +} + +.modal-dialog-scrollable .modal-content { + max-height: 100%; + overflow: hidden +} + +.modal-dialog-scrollable .modal-body { + overflow-y: auto +} + +.modal-dialog-centered { + display: flex; + align-items: center; + min-height: calc(100% - var(--mdb-modal-margin)*2) +} + +.modal-content { + position: relative; + display: flex; + flex-direction: column; + width: 100%; + color: var(--mdb-modal-color); + pointer-events: auto; + background-color: var(--mdb-modal-bg); + background-clip: padding-box; + border: var(--mdb-modal-border-width) solid var(--mdb-modal-border-color); + border-radius: var(--mdb-modal-border-radius); + outline: 0 +} + +.modal-backdrop { + --mdb-backdrop-zindex: 1050; + --mdb-backdrop-bg: #000; + --mdb-backdrop-opacity: 0.5; + position: fixed; + top: 0; + left: 0; + z-index: var(--mdb-backdrop-zindex); + width: 100vw; + height: 100vh; + background-color: var(--mdb-backdrop-bg) +} + +.modal-backdrop.fade { + opacity: 0 +} + +.modal-backdrop.show { + opacity: var(--mdb-backdrop-opacity) +} + +.modal-header { + display: flex; + flex-shrink: 0; + align-items: center; + justify-content: space-between; + padding: var(--mdb-modal-header-padding); + border-bottom: var(--mdb-modal-header-border-width) solid var(--mdb-modal-header-border-color); + border-top-left-radius: var(--mdb-modal-inner-border-radius); + border-top-right-radius: var(--mdb-modal-inner-border-radius) +} + +.modal-header .btn-close { + padding: calc(var(--mdb-modal-header-padding-y)*0.5) calc(var(--mdb-modal-header-padding-x)*0.5); + margin: calc(var(--mdb-modal-header-padding-y)*-0.5) calc(var(--mdb-modal-header-padding-x)*-0.5) calc(var(--mdb-modal-header-padding-y)*-0.5) auto +} + +.modal-title { + margin-bottom: 0; + line-height: var(--mdb-modal-title-line-height) +} + +.modal-body { + position: relative; + flex: 1 1 auto; + padding: var(--mdb-modal-padding) +} + +.modal-footer { + display: flex; + flex-shrink: 0; + flex-wrap: wrap; + align-items: center; + justify-content: flex-end; + padding: calc(var(--mdb-modal-padding) - var(--mdb-modal-footer-gap)*0.5); + background-color: var(--mdb-modal-footer-bg); + border-top: var(--mdb-modal-footer-border-width) solid var(--mdb-modal-footer-border-color); + border-bottom-right-radius: var(--mdb-modal-inner-border-radius); + border-bottom-left-radius: var(--mdb-modal-inner-border-radius) +} + +.modal-footer>* { + margin: calc(var(--mdb-modal-footer-gap)*0.5) +} + +@media(min-width: 576px) { + .modal { + --mdb-modal-margin:1.75rem; + --mdb-modal-box-shadow: 0 0.5rem 1rem rgba(0,0,0,0.15) + } + + .modal-dialog { + max-width: var(--mdb-modal-width); + margin-right: auto; + margin-left: auto + } + + .modal-sm { + --mdb-modal-width: 300px + } +} + +@media(min-width: 992px) { + .modal-lg,.modal-xl { + --mdb-modal-width:800px + } +} + +@media(min-width: 1200px) { + .modal-xl { + --mdb-modal-width:1140px + } +} + +.modal-fullscreen { + width: 100vw; + max-width: none; + height: 100%; + margin: 0 +} + +.modal-fullscreen .modal-content { + height: 100%; + border: 0; + border-radius: 0 +} + +.modal-fullscreen .modal-footer,.modal-fullscreen .modal-header { + border-radius: 0 +} + +.modal-fullscreen .modal-body { + overflow-y: auto +} + +@media(max-width: 575.98px) { + .modal-fullscreen-sm-down { + width:100vw; + max-width: none; + height: 100%; + margin: 0 + } + + .modal-fullscreen-sm-down .modal-content { + height: 100%; + border: 0; + border-radius: 0 + } + + .modal-fullscreen-sm-down .modal-footer,.modal-fullscreen-sm-down .modal-header { + border-radius: 0 + } + + .modal-fullscreen-sm-down .modal-body { + overflow-y: auto + } +} + +@media(max-width: 767.98px) { + .modal-fullscreen-md-down { + width:100vw; + max-width: none; + height: 100%; + margin: 0 + } + + .modal-fullscreen-md-down .modal-content { + height: 100%; + border: 0; + border-radius: 0 + } + + .modal-fullscreen-md-down .modal-footer,.modal-fullscreen-md-down .modal-header { + border-radius: 0 + } + + .modal-fullscreen-md-down .modal-body { + overflow-y: auto + } +} + +@media(max-width: 991.98px) { + .modal-fullscreen-lg-down { + width:100vw; + max-width: none; + height: 100%; + margin: 0 + } + + .modal-fullscreen-lg-down .modal-content { + height: 100%; + border: 0; + border-radius: 0 + } + + .modal-fullscreen-lg-down .modal-footer,.modal-fullscreen-lg-down .modal-header { + border-radius: 0 + } + + .modal-fullscreen-lg-down .modal-body { + overflow-y: auto + } +} + +@media(max-width: 1199.98px) { + .modal-fullscreen-xl-down { + width:100vw; + max-width: none; + height: 100%; + margin: 0 + } + + .modal-fullscreen-xl-down .modal-content { + height: 100%; + border: 0; + border-radius: 0 + } + + .modal-fullscreen-xl-down .modal-footer,.modal-fullscreen-xl-down .modal-header { + border-radius: 0 + } + + .modal-fullscreen-xl-down .modal-body { + overflow-y: auto + } +} + +@media(max-width: 1399.98px) { + .modal-fullscreen-xxl-down { + width:100vw; + max-width: none; + height: 100%; + margin: 0 + } + + .modal-fullscreen-xxl-down .modal-content { + height: 100%; + border: 0; + border-radius: 0 + } + + .modal-fullscreen-xxl-down .modal-footer,.modal-fullscreen-xxl-down .modal-header { + border-radius: 0 + } + + .modal-fullscreen-xxl-down .modal-body { + overflow-y: auto + } +} + +.popover { + --mdb-popover-zindex: 1080; + --mdb-popover-max-width: 276px; + --mdb-popover-font-size: 0.875rem; + --mdb-popover-bg: #fff; + --mdb-popover-border-width: 1px; + --mdb-popover-border-color: #f5f5f5; + --mdb-popover-border-radius: 0.5rem; + --mdb-popover-inner-border-radius: calc(0.5rem - 1px); + --mdb-popover-box-shadow: 0 0px 3px 0 rgba(0,0,0,0.07),0 2px 2px 0 rgba(0,0,0,0.04); + --mdb-popover-header-padding-x: 1rem; + --mdb-popover-header-padding-y: 0.5rem; + --mdb-popover-header-font-size: 1rem; + --mdb-popover-header-bg: #fff; + --mdb-popover-body-padding-x: 1rem; + --mdb-popover-body-padding-y: 1rem; + --mdb-popover-body-color: #4f4f4f; + --mdb-popover-arrow-width: 1rem; + --mdb-popover-arrow-height: 0.5rem; + --mdb-popover-arrow-border: var(--mdb-popover-border-color); + z-index: var(--mdb-popover-zindex); + display: block; + max-width: var(--mdb-popover-max-width); + font-family: var(--mdb-font-roboto); + font-style: normal; + font-weight: 400; + line-height: 1.6; + text-align: left; + text-align: start; + text-decoration: none; + text-shadow: none; + text-transform: none; + letter-spacing: normal; + word-break: normal; + white-space: normal; + word-spacing: normal; + line-break: auto; + font-size: var(--mdb-popover-font-size); + word-wrap: break-word; + background-color: var(--mdb-popover-bg); + background-clip: padding-box; + border: var(--mdb-popover-border-width) solid var(--mdb-popover-border-color); + border-radius: var(--mdb-popover-border-radius); + box-shadow: var(--mdb-popover-box-shadow) +} + +.popover .popover-arrow { + display: block; + width: var(--mdb-popover-arrow-width); + height: var(--mdb-popover-arrow-height) +} + +.popover .popover-arrow:after,.popover .popover-arrow:before { + position: absolute; + display: block; + content: ""; + border: 0 solid transparent +} + +.bs-popover-auto[data-popper-placement^=top]>.popover-arrow,.bs-popover-top>.popover-arrow { + bottom: calc(var(--mdb-popover-arrow-height)*-1 - var(--mdb-popover-border-width)) +} + +.bs-popover-auto[data-popper-placement^=top]>.popover-arrow:after,.bs-popover-auto[data-popper-placement^=top]>.popover-arrow:before,.bs-popover-top>.popover-arrow:after,.bs-popover-top>.popover-arrow:before { + border-left-width: calc(var(--mdb-popover-arrow-width)*0.5); + border-bottom-width: 0; + border-right-width: calc(var(--mdb-popover-arrow-width)*0.5); + border-top-width: var(--mdb-popover-arrow-height) +} + +.bs-popover-auto[data-popper-placement^=top]>.popover-arrow:before,.bs-popover-top>.popover-arrow:before { + bottom: 0; + border-top-color: var(--mdb-popover-arrow-border) +} + +.bs-popover-auto[data-popper-placement^=top]>.popover-arrow:after,.bs-popover-top>.popover-arrow:after { + bottom: var(--mdb-popover-border-width); + border-top-color: var(--mdb-popover-bg) +} + +/*!rtl:begin:ignore*/ +.bs-popover-auto[data-popper-placement^=right]>.popover-arrow,.bs-popover-end>.popover-arrow { + left: calc(var(--mdb-popover-arrow-height)*-1 - var(--mdb-popover-border-width)); + width: var(--mdb-popover-arrow-height); + height: var(--mdb-popover-arrow-width) +} + +.bs-popover-auto[data-popper-placement^=right]>.popover-arrow:after,.bs-popover-auto[data-popper-placement^=right]>.popover-arrow:before,.bs-popover-end>.popover-arrow:after,.bs-popover-end>.popover-arrow:before { + border-left-width: 0; + border-bottom-width: calc(var(--mdb-popover-arrow-width)*0.5); + border-right-width: var(--mdb-popover-arrow-height); + border-top-width: calc(var(--mdb-popover-arrow-width)*0.5) +} + +.bs-popover-auto[data-popper-placement^=right]>.popover-arrow:before,.bs-popover-end>.popover-arrow:before { + left: 0; + border-right-color: var(--mdb-popover-arrow-border) +} + +.bs-popover-auto[data-popper-placement^=right]>.popover-arrow:after,.bs-popover-end>.popover-arrow:after { + left: var(--mdb-popover-border-width); + border-right-color: var(--mdb-popover-bg) +} + +/*!rtl:end:ignore*/ +.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow,.bs-popover-bottom>.popover-arrow { + top: calc(var(--mdb-popover-arrow-height)*-1 - var(--mdb-popover-border-width)) +} + +.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow:after,.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow:before,.bs-popover-bottom>.popover-arrow:after,.bs-popover-bottom>.popover-arrow:before { + border-left-width: calc(var(--mdb-popover-arrow-width)*0.5); + border-bottom-width: var(--mdb-popover-arrow-height); + border-right-width: calc(var(--mdb-popover-arrow-width)*0.5); + border-top-width: 0 +} + +.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow:before,.bs-popover-bottom>.popover-arrow:before { + top: 0; + border-bottom-color: var(--mdb-popover-arrow-border) +} + +.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow:after,.bs-popover-bottom>.popover-arrow:after { + top: var(--mdb-popover-border-width); + border-bottom-color: var(--mdb-popover-bg) +} + +.bs-popover-auto[data-popper-placement^=bottom] .popover-header:before,.bs-popover-bottom .popover-header:before { + position: absolute; + top: 0; + left: 50%; + display: block; + width: var(--mdb-popover-arrow-width); + margin-left: calc(var(--mdb-popover-arrow-width)*-0.5); + content: ""; + border-bottom: var(--mdb-popover-border-width) solid var(--mdb-popover-header-bg) +} + +/*!rtl:begin:ignore*/ +.bs-popover-auto[data-popper-placement^=left]>.popover-arrow,.bs-popover-start>.popover-arrow { + right: calc(var(--mdb-popover-arrow-height)*-1 - var(--mdb-popover-border-width)); + width: var(--mdb-popover-arrow-height); + height: var(--mdb-popover-arrow-width) +} + +.bs-popover-auto[data-popper-placement^=left]>.popover-arrow:after,.bs-popover-auto[data-popper-placement^=left]>.popover-arrow:before,.bs-popover-start>.popover-arrow:after,.bs-popover-start>.popover-arrow:before { + border-left-width: var(--mdb-popover-arrow-height); + border-bottom-width: calc(var(--mdb-popover-arrow-width)*0.5); + border-right-width: 0; + border-top-width: calc(var(--mdb-popover-arrow-width)*0.5) +} + +.bs-popover-auto[data-popper-placement^=left]>.popover-arrow:before,.bs-popover-start>.popover-arrow:before { + right: 0; + border-left-color: var(--mdb-popover-arrow-border) +} + +.bs-popover-auto[data-popper-placement^=left]>.popover-arrow:after,.bs-popover-start>.popover-arrow:after { + right: var(--mdb-popover-border-width); + border-left-color: var(--mdb-popover-bg) +} + +/*!rtl:end:ignore*/ +.popover-header { + padding: var(--mdb-popover-header-padding-y) var(--mdb-popover-header-padding-x); + margin-bottom: 0; + font-size: var(--mdb-popover-header-font-size); + color: var(--mdb-popover-header-color); + background-color: var(--mdb-popover-header-bg); + border-bottom: var(--mdb-popover-border-width) solid var(--mdb-popover-border-color); + border-top-left-radius: var(--mdb-popover-inner-border-radius); + border-top-right-radius: var(--mdb-popover-inner-border-radius) +} + +.popover-header:empty { + display: none +} + +.popover-body { + padding: var(--mdb-popover-body-padding-y) var(--mdb-popover-body-padding-x); + color: var(--mdb-popover-body-color) +} + +.spinner-border,.spinner-grow { + display: inline-block; + width: var(--mdb-spinner-width); + height: var(--mdb-spinner-height); + vertical-align: var(--mdb-spinner-vertical-align); + border-radius: 50%; + animation: var(--mdb-spinner-animation-speed) linear infinite var(--mdb-spinner-animation-name) +} + +@keyframes spinner-border { + to { + transform: rotate(1turn) + } +} + +.spinner-border { + --mdb-spinner-width: 2rem; + --mdb-spinner-height: 2rem; + --mdb-spinner-vertical-align: -0.125em; + --mdb-spinner-border-width: 0.25em; + --mdb-spinner-animation-speed: 0.75s; + --mdb-spinner-animation-name: spinner-border; + border: var(--mdb-spinner-border-width) solid; + border-right-color: transparent +} + +.spinner-border-sm { + --mdb-spinner-width: 1rem; + --mdb-spinner-height: 1rem; + --mdb-spinner-border-width: 0.2em +} + +@keyframes spinner-grow { + 0% { + transform: scale(0) + } + + 50% { + opacity: 1; + transform: none + } +} + +.spinner-grow { + --mdb-spinner-width: 2rem; + --mdb-spinner-height: 2rem; + --mdb-spinner-vertical-align: -0.125em; + --mdb-spinner-animation-speed: 0.75s; + --mdb-spinner-animation-name: spinner-grow; + background-color: currentcolor; + opacity: 0 +} + +.spinner-grow-sm { + --mdb-spinner-width: 1rem; + --mdb-spinner-height: 1rem +} + +@media(prefers-reduced-motion:reduce) { + .spinner-border,.spinner-grow { + --mdb-spinner-animation-speed: 1.5s + } +} + +.tooltip { + --mdb-tooltip-zindex: 1090; + --mdb-tooltip-max-width: 200px; + --mdb-tooltip-padding-x: 16px; + --mdb-tooltip-padding-y: 6px; + --mdb-tooltip-font-size: 0.875rem; + --mdb-tooltip-color: #fff; + --mdb-tooltip-bg: #6d6d6d; + --mdb-tooltip-border-radius: 0.25rem; + --mdb-tooltip-opacity: 0.9; + --mdb-tooltip-arrow-width: 0.8rem; + --mdb-tooltip-arrow-height: 0.4rem; + z-index: var(--mdb-tooltip-zindex); + display: block; + padding: var(--mdb-tooltip-arrow-height); + margin: var(--mdb-tooltip-margin); + font-family: var(--mdb-font-roboto); + font-style: normal; + font-weight: 400; + line-height: 1.6; + text-align: left; + text-align: start; + text-decoration: none; + text-shadow: none; + text-transform: none; + letter-spacing: normal; + word-break: normal; + white-space: normal; + word-spacing: normal; + line-break: auto; + font-size: var(--mdb-tooltip-font-size); + word-wrap: break-word; + opacity: 0 +} + +.tooltip.show { + opacity: var(--mdb-tooltip-opacity) +} + +.tooltip .tooltip-arrow { + display: block; + width: var(--mdb-tooltip-arrow-width); + height: var(--mdb-tooltip-arrow-height) +} + +.tooltip .tooltip-arrow:before { + position: absolute; + content: ""; + border-color: transparent; + border-style: solid +} + +.bs-tooltip-auto[data-popper-placement^=top] .tooltip-arrow,.bs-tooltip-top .tooltip-arrow { + bottom: 0 +} + +.bs-tooltip-auto[data-popper-placement^=top] .tooltip-arrow:before,.bs-tooltip-top .tooltip-arrow:before { + top: -1px; + border-left-width: calc(var(--mdb-tooltip-arrow-width)*0.5); + border-bottom-width: 0; + border-right-width: calc(var(--mdb-tooltip-arrow-width)*0.5); + border-top-width: var(--mdb-tooltip-arrow-height); + border-top-color: var(--mdb-tooltip-bg) +} + +/*!rtl:begin:ignore*/ +.bs-tooltip-auto[data-popper-placement^=right] .tooltip-arrow,.bs-tooltip-end .tooltip-arrow { + left: 0; + width: var(--mdb-tooltip-arrow-height); + height: var(--mdb-tooltip-arrow-width) +} + +.bs-tooltip-auto[data-popper-placement^=right] .tooltip-arrow:before,.bs-tooltip-end .tooltip-arrow:before { + right: -1px; + border-left-width: 0; + border-bottom-width: calc(var(--mdb-tooltip-arrow-width)*0.5); + border-right-width: var(--mdb-tooltip-arrow-height); + border-top-width: calc(var(--mdb-tooltip-arrow-width)*0.5); + border-right-color: var(--mdb-tooltip-bg) +} + +/*!rtl:end:ignore*/ +.bs-tooltip-auto[data-popper-placement^=bottom] .tooltip-arrow,.bs-tooltip-bottom .tooltip-arrow { + top: 0 +} + +.bs-tooltip-auto[data-popper-placement^=bottom] .tooltip-arrow:before,.bs-tooltip-bottom .tooltip-arrow:before { + bottom: -1px; + border-left-width: calc(var(--mdb-tooltip-arrow-width)*0.5); + border-bottom-width: var(--mdb-tooltip-arrow-height); + border-right-width: calc(var(--mdb-tooltip-arrow-width)*0.5); + border-top-width: 0; + border-bottom-color: var(--mdb-tooltip-bg) +} + +/*!rtl:begin:ignore*/ +.bs-tooltip-auto[data-popper-placement^=left] .tooltip-arrow,.bs-tooltip-start .tooltip-arrow { + right: 0; + width: var(--mdb-tooltip-arrow-height); + height: var(--mdb-tooltip-arrow-width) +} + +.bs-tooltip-auto[data-popper-placement^=left] .tooltip-arrow:before,.bs-tooltip-start .tooltip-arrow:before { + left: -1px; + border-left-width: var(--mdb-tooltip-arrow-height); + border-bottom-width: calc(var(--mdb-tooltip-arrow-width)*0.5); + border-right-width: 0; + border-top-width: calc(var(--mdb-tooltip-arrow-width)*0.5); + border-left-color: var(--mdb-tooltip-bg) +} + +/*!rtl:end:ignore*/ +.tooltip-inner { + max-width: var(--mdb-tooltip-max-width); + padding: var(--mdb-tooltip-padding-y) var(--mdb-tooltip-padding-x); + color: var(--mdb-tooltip-color); + text-align: center; + background-color: var(--mdb-tooltip-bg); + border-radius: var(--mdb-tooltip-border-radius) +} + +.clearfix:after { + display: block; + clear: both; + content: "" +} + +.text-bg-primary { + color: #fff!important; + background-color: RGBA(59,113,202,var(--mdb-bg-opacity,1))!important +} + +.text-bg-secondary { + color: #000!important; + background-color: RGBA(159,166,178,var(--mdb-bg-opacity,1))!important +} + +.text-bg-success { + color: #000!important; + background-color: RGBA(20,164,77,var(--mdb-bg-opacity,1))!important +} + +.text-bg-danger { + color: #000!important; + background-color: RGBA(220,76,100,var(--mdb-bg-opacity,1))!important +} + +.text-bg-warning { + color: #000!important; + background-color: RGBA(228,161,27,var(--mdb-bg-opacity,1))!important +} + +.text-bg-info { + color: #000!important; + background-color: RGBA(84,180,211,var(--mdb-bg-opacity,1))!important +} + +.text-bg-light { + color: #000!important; + background-color: RGBA(251,251,251,var(--mdb-bg-opacity,1))!important +} + +.text-bg-dark { + color: #fff!important; + background-color: RGBA(51,45,45,var(--mdb-bg-opacity,1))!important +} + +.link-primary { + color: #3b71ca!important +} + +.link-primary:focus,.link-primary:hover { + color: #386bc0!important +} + +.link-secondary { + color: #9fa6b2!important +} + +.link-secondary:focus,.link-secondary:hover { + color: #a4aab6!important +} + +.link-success { + color: #14a44d!important +} + +.link-success:focus,.link-success:hover { + color: #20a956!important +} + +.link-danger { + color: #dc4c64!important +} + +.link-danger:focus,.link-danger:hover { + color: #de556c!important +} + +.link-warning { + color: #e4a11b!important +} + +.link-warning:focus,.link-warning:hover { + color: #e5a626!important +} + +.link-info { + color: #54b4d3!important +} + +.link-info:focus,.link-info:hover { + color: #5db8d5!important +} + +.link-light,.link-light:focus,.link-light:hover { + color: #fbfbfb!important +} + +.link-dark { + color: #332d2d!important +} + +.link-dark:focus,.link-dark:hover { + color: #302b2b!important +} + +.ratio { + position: relative; + width: 100% +} + +.ratio:before { + display: block; + padding-top: var(--mdb-aspect-ratio); + content: "" +} + +.ratio>* { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100% +} + +.ratio-1x1 { + --mdb-aspect-ratio: 100% +} + +.ratio-4x3 { + --mdb-aspect-ratio: 75% +} + +.ratio-16x9 { + --mdb-aspect-ratio: 56.25% +} + +.ratio-21x9 { + --mdb-aspect-ratio: 42.8571428571% +} + +.fixed-top { + top: 0 +} + +.fixed-bottom,.fixed-top { + position: fixed; + right: 0; + left: 0; + z-index: 1030 +} + +.fixed-bottom { + bottom: 0 +} + +.sticky-top { + top: 0 +} + +.sticky-bottom,.sticky-top { + position: -webkit-sticky; + position: sticky; + z-index: 1020 +} + +.sticky-bottom { + bottom: 0 +} + +@media(min-width: 576px) { + .sticky-sm-top { + top:0 + } + + .sticky-sm-bottom,.sticky-sm-top { + position: -webkit-sticky; + position: sticky; + z-index: 1020 + } + + .sticky-sm-bottom { + bottom: 0 + } +} + +@media(min-width: 768px) { + .sticky-md-top { + top:0 + } + + .sticky-md-bottom,.sticky-md-top { + position: -webkit-sticky; + position: sticky; + z-index: 1020 + } + + .sticky-md-bottom { + bottom: 0 + } +} + +@media(min-width: 992px) { + .sticky-lg-top { + top:0 + } + + .sticky-lg-bottom,.sticky-lg-top { + position: -webkit-sticky; + position: sticky; + z-index: 1020 + } + + .sticky-lg-bottom { + bottom: 0 + } +} + +@media(min-width: 1200px) { + .sticky-xl-top { + top:0 + } + + .sticky-xl-bottom,.sticky-xl-top { + position: -webkit-sticky; + position: sticky; + z-index: 1020 + } + + .sticky-xl-bottom { + bottom: 0 + } +} + +@media(min-width: 1400px) { + .sticky-xxl-top { + top:0 + } + + .sticky-xxl-bottom,.sticky-xxl-top { + position: -webkit-sticky; + position: sticky; + z-index: 1020 + } + + .sticky-xxl-bottom { + bottom: 0 + } +} + +.hstack { + flex-direction: row; + align-items: center +} + +.hstack,.vstack { + display: flex; + align-self: stretch +} + +.vstack { + flex: 1 1 auto; + flex-direction: column +} + +.visually-hidden,.visually-hidden-focusable:not(:focus):not(:focus-within) { + position: absolute!important; + width: 1px!important; + height: 1px!important; + padding: 0!important; + margin: -1px!important; + overflow: hidden!important; + clip: rect(0,0,0,0)!important; + white-space: nowrap!important; + border: 0!important +} + +.stretched-link:after { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 1; + content: "" +} + +.text-truncate { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap +} + +.vr { + display: inline-block; + align-self: stretch; + width: 1px; + min-height: 1em; + background-color: currentcolor; + opacity: .25 +} + +.align-baseline { + vertical-align: baseline!important +} + +.align-top { + vertical-align: top!important +} + +.align-middle { + vertical-align: middle!important +} + +.align-bottom { + vertical-align: bottom!important +} + +.align-text-bottom { + vertical-align: text-bottom!important +} + +.align-text-top { + vertical-align: text-top!important +} + +.float-start { + float: left!important +} + +.float-end { + float: right!important +} + +.float-none { + float: none!important +} + +.opacity-0 { + opacity: 0!important +} + +.opacity-5 { + opacity: .05!important +} + +.opacity-10 { + opacity: .1!important +} + +.opacity-15 { + opacity: .15!important +} + +.opacity-20 { + opacity: .2!important +} + +.opacity-25 { + opacity: .25!important +} + +.opacity-30 { + opacity: .3!important +} + +.opacity-35 { + opacity: .35!important +} + +.opacity-40 { + opacity: .4!important +} + +.opacity-45 { + opacity: .45!important +} + +.opacity-50 { + opacity: .5!important +} + +.opacity-55 { + opacity: .55!important +} + +.opacity-60 { + opacity: .6!important +} + +.opacity-65 { + opacity: .65!important +} + +.opacity-70 { + opacity: .7!important +} + +.opacity-75 { + opacity: .75!important +} + +.opacity-80 { + opacity: .8!important +} + +.opacity-85 { + opacity: .85!important +} + +.opacity-90 { + opacity: .9!important +} + +.opacity-95 { + opacity: .95!important +} + +.opacity-100 { + opacity: 1!important +} + +.overflow-auto { + overflow: auto!important +} + +.overflow-hidden { + overflow: hidden!important +} + +.overflow-visible { + overflow: visible!important +} + +.overflow-scroll { + overflow: scroll!important +} + +.d-inline { + display: inline!important +} + +.d-inline-block { + display: inline-block!important +} + +.d-block { + display: block!important +} + +.d-grid { + display: grid!important +} + +.d-table { + display: table!important +} + +.d-table-row { + display: table-row!important +} + +.d-table-cell { + display: table-cell!important +} + +.d-flex { + display: flex!important +} + +.d-inline-flex { + display: inline-flex!important +} + +.d-none { + display: none!important +} + +.shadow { + box-shadow: 0 .5rem 1rem rgba(0,0,0,.15)!important +} + +.shadow-sm { + box-shadow: 0 .125rem .25rem rgba(0,0,0,.075)!important +} + +.shadow-lg { + box-shadow: 0 1rem 3rem rgba(0,0,0,.175)!important +} + +.shadow-0,.shadow-none { + box-shadow: none!important +} + +.shadow-1 { + box-shadow: 0 0 2px 0 rgba(0,0,0,.07),0 1px 1px 0 rgba(0,0,0,.04)!important +} + +.shadow-2 { + box-shadow: 0 0 3px 0 rgba(0,0,0,.07),0 2px 2px 0 rgba(0,0,0,.04)!important +} + +.shadow-3 { + box-shadow: 0 2px 6px -1px rgba(0,0,0,.07),0 6px 18px -1px rgba(0,0,0,.04)!important +} + +.shadow-4 { + box-shadow: 0 2px 15px -3px rgba(0,0,0,.07),0 10px 20px -2px rgba(0,0,0,.04)!important +} + +.shadow-5 { + box-shadow: 0 2px 25px -5px rgba(0,0,0,.07),0 25px 21px -5px rgba(0,0,0,.04)!important +} + +.shadow-6 { + box-shadow: 0 2px 35px -12px rgba(0,0,0,.21),0 50px 40px -5px rgba(0,0,0,.04)!important +} + +.shadow-1-soft { + box-shadow: 0 1px 5px 0 rgba(0,0,0,.05)!important +} + +.shadow-2-soft { + box-shadow: 0 2px 10px 0 rgba(0,0,0,.05)!important +} + +.shadow-3-soft { + box-shadow: 0 5px 15px 0 rgba(0,0,0,.05)!important +} + +.shadow-4-soft { + box-shadow: 0 10px 20px 0 rgba(0,0,0,.05)!important +} + +.shadow-5-soft { + box-shadow: 0 15px 30px 0 rgba(0,0,0,.05)!important +} + +.shadow-6-soft { + box-shadow: 0 20px 40px 0 rgba(0,0,0,.05)!important +} + +.shadow-1-strong { + box-shadow: 0 0 2px 0 rgba(0,0,0,.16),0 1px 1px 0 rgba(0,0,0,.1)!important +} + +.shadow-2-strong { + box-shadow: 0 0 3px 0 rgba(0,0,0,.16),0 2px 2px 0 rgba(0,0,0,.1)!important +} + +.shadow-3-strong { + box-shadow: 0 2px 6px -1px rgba(0,0,0,.16),0 6px 18px -1px rgba(0,0,0,.1)!important +} + +.shadow-4-strong { + box-shadow: 0 2px 15px -3px rgba(0,0,0,.16),0 10px 20px -2px rgba(0,0,0,.1)!important +} + +.shadow-5-strong { + box-shadow: 0 2px 25px -5px rgba(0,0,0,.16),0 25px 21px -5px rgba(0,0,0,.1)!important +} + +.shadow-6-strong { + box-shadow: 0 2px 35px -12px rgba(0,0,0,.26),0 50px 40px -5px rgba(0,0,0,.1)!important +} + +.shadow-inner { + box-shadow: inset 0 2px 4px 0 rgba(0,0,0,.06)!important +} + +.position-static { + position: static!important +} + +.position-relative { + position: relative!important +} + +.position-absolute { + position: absolute!important +} + +.position-fixed { + position: fixed!important +} + +.position-sticky { + position: -webkit-sticky!important; + position: sticky!important +} + +.top-0 { + top: 0!important +} + +.top-50 { + top: 50%!important +} + +.top-100 { + top: 100%!important +} + +.bottom-0 { + bottom: 0!important +} + +.bottom-50 { + bottom: 50%!important +} + +.bottom-100 { + bottom: 100%!important +} + +.start-0 { + left: 0!important +} + +.start-50 { + left: 50%!important +} + +.start-100 { + left: 100%!important +} + +.end-0 { + right: 0!important +} + +.end-50 { + right: 50%!important +} + +.end-100 { + right: 100%!important +} + +.translate-middle { + transform: translate(-50%,-50%)!important +} + +.translate-middle-x { + transform: translateX(-50%)!important +} + +.translate-middle-y { + transform: translateY(-50%)!important +} + +.border { + border: var(--mdb-border-width) var(--mdb-border-style) var(--mdb-border-color)!important +} + +.border-0 { + border: 0!important +} + +.border-top { + border-top: var(--mdb-border-width) var(--mdb-border-style) var(--mdb-border-color)!important +} + +.border-top-0 { + border-top: 0!important +} + +.border-end { + border-right: var(--mdb-border-width) var(--mdb-border-style) var(--mdb-border-color)!important +} + +.border-end-0 { + border-right: 0!important +} + +.border-bottom { + border-bottom: var(--mdb-border-width) var(--mdb-border-style) var(--mdb-border-color)!important +} + +.border-bottom-0 { + border-bottom: 0!important +} + +.border-start { + border-left: var(--mdb-border-width) var(--mdb-border-style) var(--mdb-border-color)!important +} + +.border-start-0 { + border-left: 0!important +} + +.border-primary { + --mdb-border-opacity: 1; + border-color: rgba(var(--mdb-primary-rgb),var(--mdb-border-opacity))!important +} + +.border-secondary { + --mdb-border-opacity: 1; + border-color: rgba(var(--mdb-secondary-rgb),var(--mdb-border-opacity))!important +} + +.border-success { + --mdb-border-opacity: 1; + border-color: rgba(var(--mdb-success-rgb),var(--mdb-border-opacity))!important +} + +.border-danger { + --mdb-border-opacity: 1; + border-color: rgba(var(--mdb-danger-rgb),var(--mdb-border-opacity))!important +} + +.border-warning { + --mdb-border-opacity: 1; + border-color: rgba(var(--mdb-warning-rgb),var(--mdb-border-opacity))!important +} + +.border-info { + --mdb-border-opacity: 1; + border-color: rgba(var(--mdb-info-rgb),var(--mdb-border-opacity))!important +} + +.border-light { + --mdb-border-opacity: 1; + border-color: rgba(var(--mdb-light-rgb),var(--mdb-border-opacity))!important +} + +.border-dark { + --mdb-border-opacity: 1; + border-color: rgba(var(--mdb-dark-rgb),var(--mdb-border-opacity))!important +} + +.border-white { + --mdb-border-opacity: 1; + border-color: rgba(var(--mdb-white-rgb),var(--mdb-border-opacity))!important +} + +.border-1 { + --mdb-border-width: 1px +} + +.border-2 { + --mdb-border-width: 2px +} + +.border-3 { + --mdb-border-width: 3px +} + +.border-4 { + --mdb-border-width: 4px +} + +.border-5 { + --mdb-border-width: 5px +} + +.border-opacity-10 { + --mdb-border-opacity: 0.1 +} + +.border-opacity-25 { + --mdb-border-opacity: 0.25 +} + +.border-opacity-50 { + --mdb-border-opacity: 0.5 +} + +.border-opacity-75 { + --mdb-border-opacity: 0.75 +} + +.border-opacity-100 { + --mdb-border-opacity: 1 +} + +.w-25 { + width: 25%!important +} + +.w-50 { + width: 50%!important +} + +.w-75 { + width: 75%!important +} + +.w-100 { + width: 100%!important +} + +.w-auto { + width: auto!important +} + +.mw-100 { + max-width: 100%!important +} + +.vw-100 { + width: 100vw!important +} + +.min-vw-100 { + min-width: 100vw!important +} + +.h-25 { + height: 25%!important +} + +.h-50 { + height: 50%!important +} + +.h-75 { + height: 75%!important +} + +.h-100 { + height: 100%!important +} + +.h-auto { + height: auto!important +} + +.mh-100 { + max-height: 100%!important +} + +.vh-100 { + height: 100vh!important +} + +.min-vh-100 { + min-height: 100vh!important +} + +.flex-fill { + flex: 1 1 auto!important +} + +.flex-row { + flex-direction: row!important +} + +.flex-column { + flex-direction: column!important +} + +.flex-row-reverse { + flex-direction: row-reverse!important +} + +.flex-column-reverse { + flex-direction: column-reverse!important +} + +.flex-grow-0 { + flex-grow: 0!important +} + +.flex-grow-1 { + flex-grow: 1!important +} + +.flex-shrink-0 { + flex-shrink: 0!important +} + +.flex-shrink-1 { + flex-shrink: 1!important +} + +.flex-wrap { + flex-wrap: wrap!important +} + +.flex-nowrap { + flex-wrap: nowrap!important +} + +.flex-wrap-reverse { + flex-wrap: wrap-reverse!important +} + +.justify-content-start { + justify-content: flex-start!important +} + +.justify-content-end { + justify-content: flex-end!important +} + +.justify-content-center { + justify-content: center!important +} + +.justify-content-between { + justify-content: space-between!important +} + +.justify-content-around { + justify-content: space-around!important +} + +.justify-content-evenly { + justify-content: space-evenly!important +} + +.align-items-start { + align-items: flex-start!important +} + +.align-items-end { + align-items: flex-end!important +} + +.align-items-center { + align-items: center!important +} + +.align-items-baseline { + align-items: baseline!important +} + +.align-items-stretch { + align-items: stretch!important +} + +.align-content-start { + align-content: flex-start!important +} + +.align-content-end { + align-content: flex-end!important +} + +.align-content-center { + align-content: center!important +} + +.align-content-between { + align-content: space-between!important +} + +.align-content-around { + align-content: space-around!important +} + +.align-content-stretch { + align-content: stretch!important +} + +.align-self-auto { + align-self: auto!important +} + +.align-self-start { + align-self: flex-start!important +} + +.align-self-end { + align-self: flex-end!important +} + +.align-self-center { + align-self: center!important +} + +.align-self-baseline { + align-self: baseline!important +} + +.align-self-stretch { + align-self: stretch!important +} + +.order-first { + order: -1!important +} + +.order-0 { + order: 0!important +} + +.order-1 { + order: 1!important +} + +.order-2 { + order: 2!important +} + +.order-3 { + order: 3!important +} + +.order-4 { + order: 4!important +} + +.order-5 { + order: 5!important +} + +.order-last { + order: 6!important +} + +.m-0 { + margin: 0!important +} + +.m-1 { + margin: .25rem!important +} + +.m-2 { + margin: .5rem!important +} + +.m-3 { + margin: 1rem!important +} + +.m-4 { + margin: 1.5rem!important +} + +.m-5 { + margin: 3rem!important +} + +.m-auto { + margin: auto!important +} + +.mx-0 { + margin-right: 0!important; + margin-left: 0!important +} + +.mx-1 { + margin-right: .25rem!important; + margin-left: .25rem!important +} + +.mx-2 { + margin-right: .5rem!important; + margin-left: .5rem!important +} + +.mx-3 { + margin-right: 1rem!important; + margin-left: 1rem!important +} + +.mx-4 { + margin-right: 1.5rem!important; + margin-left: 1.5rem!important +} + +.mx-5 { + margin-right: 3rem!important; + margin-left: 3rem!important +} + +.mx-auto { + margin-right: auto!important; + margin-left: auto!important +} + +.my-0 { + margin-top: 0!important; + margin-bottom: 0!important +} + +.my-1 { + margin-top: .25rem!important; + margin-bottom: .25rem!important +} + +.my-2 { + margin-top: .5rem!important; + margin-bottom: .5rem!important +} + +.my-3 { + margin-top: 1rem!important; + margin-bottom: 1rem!important +} + +.my-4 { + margin-top: 1.5rem!important; + margin-bottom: 1.5rem!important +} + +.my-5 { + margin-top: 3rem!important; + margin-bottom: 3rem!important +} + +.my-auto { + margin-top: auto!important; + margin-bottom: auto!important +} + +.mt-0 { + margin-top: 0!important +} + +.mt-1 { + margin-top: .25rem!important +} + +.mt-2 { + margin-top: .5rem!important +} + +.mt-3 { + margin-top: 1rem!important +} + +.mt-4 { + margin-top: 1.5rem!important +} + +.mt-5 { + margin-top: 3rem!important +} + +.mt-auto { + margin-top: auto!important +} + +.me-0 { + margin-right: 0!important +} + +.me-1 { + margin-right: .25rem!important +} + +.me-2 { + margin-right: .5rem!important +} + +.me-3 { + margin-right: 1rem!important +} + +.me-4 { + margin-right: 1.5rem!important +} + +.me-5 { + margin-right: 3rem!important +} + +.me-auto { + margin-right: auto!important +} + +.mb-0 { + margin-bottom: 0!important +} + +.mb-1 { + margin-bottom: .25rem!important +} + +.mb-2 { + margin-bottom: .5rem!important +} + +.mb-3 { + margin-bottom: 1rem!important +} + +.mb-4 { + margin-bottom: 1.5rem!important +} + +.mb-5 { + margin-bottom: 3rem!important +} + +.mb-auto { + margin-bottom: auto!important +} + +.mb-6 { + margin-bottom: 3.5rem!important +} + +.mb-7 { + margin-bottom: 4rem!important +} + +.mb-8 { + margin-bottom: 5rem!important +} + +.mb-9 { + margin-bottom: 6rem!important +} + +.mb-10 { + margin-bottom: 8rem!important +} + +.mb-11 { + margin-bottom: 10rem!important +} + +.mb-12 { + margin-bottom: 12rem!important +} + +.mb-13 { + margin-bottom: 14rem!important +} + +.mb-14 { + margin-bottom: 16rem!important +} + +.ms-0 { + margin-left: 0!important +} + +.ms-1 { + margin-left: .25rem!important +} + +.ms-2 { + margin-left: .5rem!important +} + +.ms-3 { + margin-left: 1rem!important +} + +.ms-4 { + margin-left: 1.5rem!important +} + +.ms-5 { + margin-left: 3rem!important +} + +.ms-auto { + margin-left: auto!important +} + +.m-n1 { + margin: -.25rem!important +} + +.m-n2 { + margin: -.5rem!important +} + +.m-n3 { + margin: -1rem!important +} + +.m-n4 { + margin: -1.5rem!important +} + +.m-n5 { + margin: -3rem!important +} + +.mx-n1 { + margin-right: -.25rem!important; + margin-left: -.25rem!important +} + +.mx-n2 { + margin-right: -.5rem!important; + margin-left: -.5rem!important +} + +.mx-n3 { + margin-right: -1rem!important; + margin-left: -1rem!important +} + +.mx-n4 { + margin-right: -1.5rem!important; + margin-left: -1.5rem!important +} + +.mx-n5 { + margin-right: -3rem!important; + margin-left: -3rem!important +} + +.my-n1 { + margin-top: -.25rem!important; + margin-bottom: -.25rem!important +} + +.my-n2 { + margin-top: -.5rem!important; + margin-bottom: -.5rem!important +} + +.my-n3 { + margin-top: -1rem!important; + margin-bottom: -1rem!important +} + +.my-n4 { + margin-top: -1.5rem!important; + margin-bottom: -1.5rem!important +} + +.my-n5 { + margin-top: -3rem!important; + margin-bottom: -3rem!important +} + +.mt-n1 { + margin-top: -.25rem!important +} + +.mt-n2 { + margin-top: -.5rem!important +} + +.mt-n3 { + margin-top: -1rem!important +} + +.mt-n4 { + margin-top: -1.5rem!important +} + +.mt-n5 { + margin-top: -3rem!important +} + +.me-n1 { + margin-right: -.25rem!important +} + +.me-n2 { + margin-right: -.5rem!important +} + +.me-n3 { + margin-right: -1rem!important +} + +.me-n4 { + margin-right: -1.5rem!important +} + +.me-n5 { + margin-right: -3rem!important +} + +.mb-n1 { + margin-bottom: -.25rem!important +} + +.mb-n2 { + margin-bottom: -.5rem!important +} + +.mb-n3 { + margin-bottom: -1rem!important +} + +.mb-n4 { + margin-bottom: -1.5rem!important +} + +.mb-n5 { + margin-bottom: -3rem!important +} + +.ms-n1 { + margin-left: -.25rem!important +} + +.ms-n2 { + margin-left: -.5rem!important +} + +.ms-n3 { + margin-left: -1rem!important +} + +.ms-n4 { + margin-left: -1.5rem!important +} + +.ms-n5 { + margin-left: -3rem!important +} + +.p-0 { + padding: 0!important +} + +.p-1 { + padding: .25rem!important +} + +.p-2 { + padding: .5rem!important +} + +.p-3 { + padding: 1rem!important +} + +.p-4 { + padding: 1.5rem!important +} + +.p-5 { + padding: 3rem!important +} + +.px-0 { + padding-right: 0!important; + padding-left: 0!important +} + +.px-1 { + padding-right: .25rem!important; + padding-left: .25rem!important +} + +.px-2 { + padding-right: .5rem!important; + padding-left: .5rem!important +} + +.px-3 { + padding-right: 1rem!important; + padding-left: 1rem!important +} + +.px-4 { + padding-right: 1.5rem!important; + padding-left: 1.5rem!important +} + +.px-5 { + padding-right: 3rem!important; + padding-left: 3rem!important +} + +.py-0 { + padding-top: 0!important; + padding-bottom: 0!important +} + +.py-1 { + padding-top: .25rem!important; + padding-bottom: .25rem!important +} + +.py-2 { + padding-top: .5rem!important; + padding-bottom: .5rem!important +} + +.py-3 { + padding-top: 1rem!important; + padding-bottom: 1rem!important +} + +.py-4 { + padding-top: 1.5rem!important; + padding-bottom: 1.5rem!important +} + +.py-5 { + padding-top: 3rem!important; + padding-bottom: 3rem!important +} + +.pt-0 { + padding-top: 0!important +} + +.pt-1 { + padding-top: .25rem!important +} + +.pt-2 { + padding-top: .5rem!important +} + +.pt-3 { + padding-top: 1rem!important +} + +.pt-4 { + padding-top: 1.5rem!important +} + +.pt-5 { + padding-top: 3rem!important +} + +.pe-0 { + padding-right: 0!important +} + +.pe-1 { + padding-right: .25rem!important +} + +.pe-2 { + padding-right: .5rem!important +} + +.pe-3 { + padding-right: 1rem!important +} + +.pe-4 { + padding-right: 1.5rem!important +} + +.pe-5 { + padding-right: 3rem!important +} + +.pb-0 { + padding-bottom: 0!important +} + +.pb-1 { + padding-bottom: .25rem!important +} + +.pb-2 { + padding-bottom: .5rem!important +} + +.pb-3 { + padding-bottom: 1rem!important +} + +.pb-4 { + padding-bottom: 1.5rem!important +} + +.pb-5 { + padding-bottom: 3rem!important +} + +.ps-0 { + padding-left: 0!important +} + +.ps-1 { + padding-left: .25rem!important +} + +.ps-2 { + padding-left: .5rem!important +} + +.ps-3 { + padding-left: 1rem!important +} + +.ps-4 { + padding-left: 1.5rem!important +} + +.ps-5 { + padding-left: 3rem!important +} + +.gap-0 { + gap: 0!important +} + +.gap-1 { + gap: .25rem!important +} + +.gap-2 { + gap: .5rem!important +} + +.gap-3 { + gap: 1rem!important +} + +.gap-4 { + gap: 1.5rem!important +} + +.gap-5 { + gap: 3rem!important +} + +.font-monospace { + font-family: var(--mdb-font-monospace)!important +} + +.fs-1 { + font-size: calc(1.375rem + 1.5vw)!important +} + +.fs-2 { + font-size: calc(1.325rem + .9vw)!important +} + +.fs-3 { + font-size: calc(1.3rem + .6vw)!important +} + +.fs-4 { + font-size: calc(1.275rem + .3vw)!important +} + +.fs-5 { + font-size: 1.25rem!important +} + +.fs-6 { + font-size: 1rem!important +} + +.fst-italic { + font-style: italic!important +} + +.fst-normal { + font-style: normal!important +} + +.fw-light { + font-weight: 300!important +} + +.fw-lighter { + font-weight: lighter!important +} + +.fw-normal { + font-weight: 400!important +} + +.fw-bold { + font-weight: 700!important +} + +.fw-semibold { + font-weight: 600!important +} + +.fw-bolder { + font-weight: bolder!important +} + +.lh-1 { + line-height: 1!important +} + +.lh-sm { + line-height: 1.25!important +} + +.lh-base { + line-height: 1.6!important +} + +.lh-lg { + line-height: 2!important +} + +.text-start { + text-align: left!important +} + +.text-end { + text-align: right!important +} + +.text-center { + text-align: center!important +} + +.text-decoration-none { + text-decoration: none!important +} + +.text-decoration-underline { + text-decoration: underline!important +} + +.text-decoration-line-through { + text-decoration: line-through!important +} + +.text-lowercase { + text-transform: lowercase!important +} + +.text-uppercase { + text-transform: uppercase!important +} + +.text-capitalize { + text-transform: capitalize!important +} + +.text-wrap { + white-space: normal!important +} + +.text-nowrap { + white-space: nowrap!important +} + +/*!rtl:begin:remove*/ +.text-break { + word-wrap: break-word!important; + word-break: break-word!important +} + +/*!rtl:end:remove*/ +.text-primary { + --mdb-text-opacity: 1; + color: rgba(var(--mdb-primary-rgb),var(--mdb-text-opacity))!important +} + +.text-secondary { + --mdb-text-opacity: 1; + color: rgba(var(--mdb-secondary-rgb),var(--mdb-text-opacity))!important +} + +.text-success { + --mdb-text-opacity: 1; + color: rgba(var(--mdb-success-rgb),var(--mdb-text-opacity))!important +} + +.text-danger { + --mdb-text-opacity: 1; + color: rgba(var(--mdb-danger-rgb),var(--mdb-text-opacity))!important +} + +.text-warning { + --mdb-text-opacity: 1; + color: rgba(var(--mdb-warning-rgb),var(--mdb-text-opacity))!important +} + +.text-info { + --mdb-text-opacity: 1; + color: rgba(var(--mdb-info-rgb),var(--mdb-text-opacity))!important +} + +.text-light { + --mdb-text-opacity: 1; + color: rgba(var(--mdb-light-rgb),var(--mdb-text-opacity))!important +} + +.text-dark { + --mdb-text-opacity: 1; + color: rgba(var(--mdb-dark-rgb),var(--mdb-text-opacity))!important +} + +.text-black { + --mdb-text-opacity: 1; + color: rgba(var(--mdb-black-rgb),var(--mdb-text-opacity))!important +} + +.text-white { + --mdb-text-opacity: 1; + color: rgba(var(--mdb-white-rgb),var(--mdb-text-opacity))!important +} + +.text-body { + --mdb-text-opacity: 1; + color: rgba(var(--mdb-body-color-rgb),var(--mdb-text-opacity))!important +} + +.text-muted { + --mdb-text-opacity: 1; + color: #757575!important +} + +.text-black-50 { + --mdb-text-opacity: 1; + color: rgba(0,0,0,.5)!important +} + +.text-white-50 { + --mdb-text-opacity: 1; + color: hsla(0,0%,100%,.5)!important +} + +.text-reset { + --mdb-text-opacity: 1; + color: inherit!important +} + +.text-opacity-25 { + --mdb-text-opacity: 0.25 +} + +.text-opacity-50 { + --mdb-text-opacity: 0.5 +} + +.text-opacity-75 { + --mdb-text-opacity: 0.75 +} + +.text-opacity-100 { + --mdb-text-opacity: 1 +} + +.bg-primary { + --mdb-bg-opacity: 1; + background-color: rgba(var(--mdb-primary-rgb),var(--mdb-bg-opacity))!important +} + +.bg-secondary { + --mdb-bg-opacity: 1; + background-color: rgba(var(--mdb-secondary-rgb),var(--mdb-bg-opacity))!important +} + +.bg-success { + --mdb-bg-opacity: 1; + background-color: rgba(var(--mdb-success-rgb),var(--mdb-bg-opacity))!important +} + +.bg-danger { + --mdb-bg-opacity: 1; + background-color: rgba(var(--mdb-danger-rgb),var(--mdb-bg-opacity))!important +} + +.bg-warning { + --mdb-bg-opacity: 1; + background-color: rgba(var(--mdb-warning-rgb),var(--mdb-bg-opacity))!important +} + +.bg-info { + --mdb-bg-opacity: 1; + background-color: rgba(var(--mdb-info-rgb),var(--mdb-bg-opacity))!important +} + +.bg-light { + --mdb-bg-opacity: 1; + background-color: rgba(var(--mdb-light-rgb),var(--mdb-bg-opacity))!important +} + +.bg-dark { + --mdb-bg-opacity: 1; + background-color: rgba(var(--mdb-dark-rgb),var(--mdb-bg-opacity))!important +} + +.bg-black { + --mdb-bg-opacity: 1; + background-color: rgba(var(--mdb-black-rgb),var(--mdb-bg-opacity))!important +} + +.bg-white { + --mdb-bg-opacity: 1; + background-color: rgba(var(--mdb-white-rgb),var(--mdb-bg-opacity))!important +} + +.bg-body { + --mdb-bg-opacity: 1; + background-color: rgba(var(--mdb-body-bg-rgb),var(--mdb-bg-opacity))!important +} + +.bg-transparent { + --mdb-bg-opacity: 1; + background-color: transparent!important +} + +.bg-opacity-10 { + --mdb-bg-opacity: 0.1 +} + +.bg-opacity-25 { + --mdb-bg-opacity: 0.25 +} + +.bg-opacity-50 { + --mdb-bg-opacity: 0.5 +} + +.bg-opacity-75 { + --mdb-bg-opacity: 0.75 +} + +.bg-opacity-100 { + --mdb-bg-opacity: 1 +} + +.bg-gradient { + background-image: var(--mdb-gradient)!important +} + +.user-select-all { + -webkit-user-select: all!important; + -moz-user-select: all!important; + user-select: all!important +} + +.user-select-auto { + -webkit-user-select: auto!important; + -moz-user-select: auto!important; + user-select: auto!important +} + +.user-select-none { + -webkit-user-select: none!important; + -moz-user-select: none!important; + user-select: none!important +} + +.pe-none { + pointer-events: none!important +} + +.pe-auto { + pointer-events: auto!important +} + +.rounded { + border-radius: var(--mdb-border-radius)!important +} + +.rounded-0 { + border-radius: 0!important +} + +.rounded-1 { + border-radius: var(--mdb-border-radius-sm)!important +} + +.rounded-2 { + border-radius: var(--mdb-border-radius)!important +} + +.rounded-3 { + border-radius: var(--mdb-border-radius-lg)!important +} + +.rounded-4 { + border-radius: .375rem!important +} + +.rounded-5 { + border-radius: .5rem!important +} + +.rounded-circle { + border-radius: 50%!important +} + +.rounded-pill { + border-radius: var(--mdb-border-radius-pill)!important +} + +.rounded-6 { + border-radius: .75rem!important +} + +.rounded-7 { + border-radius: 1rem!important +} + +.rounded-8 { + border-radius: 1.25rem!important +} + +.rounded-9 { + border-radius: 1.5rem!important +} + +.rounded-top { + border-top-left-radius: var(--mdb-border-radius)!important +} + +.rounded-end,.rounded-top { + border-top-right-radius: var(--mdb-border-radius)!important +} + +.rounded-bottom,.rounded-end { + border-bottom-right-radius: var(--mdb-border-radius)!important +} + +.rounded-bottom,.rounded-start { + border-bottom-left-radius: var(--mdb-border-radius)!important +} + +.rounded-start { + border-top-left-radius: var(--mdb-border-radius)!important +} + +.visible { + visibility: visible!important +} + +.invisible { + visibility: hidden!important +} + +.ls-tighter { + letter-spacing: -.05em!important +} + +.ls-tight { + letter-spacing: -.025em!important +} + +.ls-normal { + letter-spacing: 0!important +} + +.ls-wide { + letter-spacing: .025em!important +} + +.ls-wider { + letter-spacing: .05em!important +} + +.ls-widest { + letter-spacing: .1em!important +} + +.object-cover { + -o-object-fit: cover!important; + object-fit: cover!important +} + +.object-top { + -o-object-position: top!important; + object-position: top!important +} + +.object-center { + -o-object-position: center!important; + object-position: center!important +} + +.object-bottom { + -o-object-position: bottom!important; + object-position: bottom!important +} + +@media(min-width: 576px) { + .float-sm-start { + float:left!important + } + + .float-sm-end { + float: right!important + } + + .float-sm-none { + float: none!important + } + + .d-sm-inline { + display: inline!important + } + + .d-sm-inline-block { + display: inline-block!important + } + + .d-sm-block { + display: block!important + } + + .d-sm-grid { + display: grid!important + } + + .d-sm-table { + display: table!important + } + + .d-sm-table-row { + display: table-row!important + } + + .d-sm-table-cell { + display: table-cell!important + } + + .d-sm-flex { + display: flex!important + } + + .d-sm-inline-flex { + display: inline-flex!important + } + + .d-sm-none { + display: none!important + } + + .flex-sm-fill { + flex: 1 1 auto!important + } + + .flex-sm-row { + flex-direction: row!important + } + + .flex-sm-column { + flex-direction: column!important + } + + .flex-sm-row-reverse { + flex-direction: row-reverse!important + } + + .flex-sm-column-reverse { + flex-direction: column-reverse!important + } + + .flex-sm-grow-0 { + flex-grow: 0!important + } + + .flex-sm-grow-1 { + flex-grow: 1!important + } + + .flex-sm-shrink-0 { + flex-shrink: 0!important + } + + .flex-sm-shrink-1 { + flex-shrink: 1!important + } + + .flex-sm-wrap { + flex-wrap: wrap!important + } + + .flex-sm-nowrap { + flex-wrap: nowrap!important + } + + .flex-sm-wrap-reverse { + flex-wrap: wrap-reverse!important + } + + .justify-content-sm-start { + justify-content: flex-start!important + } + + .justify-content-sm-end { + justify-content: flex-end!important + } + + .justify-content-sm-center { + justify-content: center!important + } + + .justify-content-sm-between { + justify-content: space-between!important + } + + .justify-content-sm-around { + justify-content: space-around!important + } + + .justify-content-sm-evenly { + justify-content: space-evenly!important + } + + .align-items-sm-start { + align-items: flex-start!important + } + + .align-items-sm-end { + align-items: flex-end!important + } + + .align-items-sm-center { + align-items: center!important + } + + .align-items-sm-baseline { + align-items: baseline!important + } + + .align-items-sm-stretch { + align-items: stretch!important + } + + .align-content-sm-start { + align-content: flex-start!important + } + + .align-content-sm-end { + align-content: flex-end!important + } + + .align-content-sm-center { + align-content: center!important + } + + .align-content-sm-between { + align-content: space-between!important + } + + .align-content-sm-around { + align-content: space-around!important + } + + .align-content-sm-stretch { + align-content: stretch!important + } + + .align-self-sm-auto { + align-self: auto!important + } + + .align-self-sm-start { + align-self: flex-start!important + } + + .align-self-sm-end { + align-self: flex-end!important + } + + .align-self-sm-center { + align-self: center!important + } + + .align-self-sm-baseline { + align-self: baseline!important + } + + .align-self-sm-stretch { + align-self: stretch!important + } + + .order-sm-first { + order: -1!important + } + + .order-sm-0 { + order: 0!important + } + + .order-sm-1 { + order: 1!important + } + + .order-sm-2 { + order: 2!important + } + + .order-sm-3 { + order: 3!important + } + + .order-sm-4 { + order: 4!important + } + + .order-sm-5 { + order: 5!important + } + + .order-sm-last { + order: 6!important + } + + .m-sm-0 { + margin: 0!important + } + + .m-sm-1 { + margin: .25rem!important + } + + .m-sm-2 { + margin: .5rem!important + } + + .m-sm-3 { + margin: 1rem!important + } + + .m-sm-4 { + margin: 1.5rem!important + } + + .m-sm-5 { + margin: 3rem!important + } + + .m-sm-auto { + margin: auto!important + } + + .mx-sm-0 { + margin-right: 0!important; + margin-left: 0!important + } + + .mx-sm-1 { + margin-right: .25rem!important; + margin-left: .25rem!important + } + + .mx-sm-2 { + margin-right: .5rem!important; + margin-left: .5rem!important + } + + .mx-sm-3 { + margin-right: 1rem!important; + margin-left: 1rem!important + } + + .mx-sm-4 { + margin-right: 1.5rem!important; + margin-left: 1.5rem!important + } + + .mx-sm-5 { + margin-right: 3rem!important; + margin-left: 3rem!important + } + + .mx-sm-auto { + margin-right: auto!important; + margin-left: auto!important + } + + .my-sm-0 { + margin-top: 0!important; + margin-bottom: 0!important + } + + .my-sm-1 { + margin-top: .25rem!important; + margin-bottom: .25rem!important + } + + .my-sm-2 { + margin-top: .5rem!important; + margin-bottom: .5rem!important + } + + .my-sm-3 { + margin-top: 1rem!important; + margin-bottom: 1rem!important + } + + .my-sm-4 { + margin-top: 1.5rem!important; + margin-bottom: 1.5rem!important + } + + .my-sm-5 { + margin-top: 3rem!important; + margin-bottom: 3rem!important + } + + .my-sm-auto { + margin-top: auto!important; + margin-bottom: auto!important + } + + .mt-sm-0 { + margin-top: 0!important + } + + .mt-sm-1 { + margin-top: .25rem!important + } + + .mt-sm-2 { + margin-top: .5rem!important + } + + .mt-sm-3 { + margin-top: 1rem!important + } + + .mt-sm-4 { + margin-top: 1.5rem!important + } + + .mt-sm-5 { + margin-top: 3rem!important + } + + .mt-sm-auto { + margin-top: auto!important + } + + .me-sm-0 { + margin-right: 0!important + } + + .me-sm-1 { + margin-right: .25rem!important + } + + .me-sm-2 { + margin-right: .5rem!important + } + + .me-sm-3 { + margin-right: 1rem!important + } + + .me-sm-4 { + margin-right: 1.5rem!important + } + + .me-sm-5 { + margin-right: 3rem!important + } + + .me-sm-auto { + margin-right: auto!important + } + + .mb-sm-0 { + margin-bottom: 0!important + } + + .mb-sm-1 { + margin-bottom: .25rem!important + } + + .mb-sm-2 { + margin-bottom: .5rem!important + } + + .mb-sm-3 { + margin-bottom: 1rem!important + } + + .mb-sm-4 { + margin-bottom: 1.5rem!important + } + + .mb-sm-5 { + margin-bottom: 3rem!important + } + + .mb-sm-auto { + margin-bottom: auto!important + } + + .mb-sm-6 { + margin-bottom: 3.5rem!important + } + + .mb-sm-7 { + margin-bottom: 4rem!important + } + + .mb-sm-8 { + margin-bottom: 5rem!important + } + + .mb-sm-9 { + margin-bottom: 6rem!important + } + + .mb-sm-10 { + margin-bottom: 8rem!important + } + + .mb-sm-11 { + margin-bottom: 10rem!important + } + + .mb-sm-12 { + margin-bottom: 12rem!important + } + + .mb-sm-13 { + margin-bottom: 14rem!important + } + + .mb-sm-14 { + margin-bottom: 16rem!important + } + + .ms-sm-0 { + margin-left: 0!important + } + + .ms-sm-1 { + margin-left: .25rem!important + } + + .ms-sm-2 { + margin-left: .5rem!important + } + + .ms-sm-3 { + margin-left: 1rem!important + } + + .ms-sm-4 { + margin-left: 1.5rem!important + } + + .ms-sm-5 { + margin-left: 3rem!important + } + + .ms-sm-auto { + margin-left: auto!important + } + + .m-sm-n1 { + margin: -.25rem!important + } + + .m-sm-n2 { + margin: -.5rem!important + } + + .m-sm-n3 { + margin: -1rem!important + } + + .m-sm-n4 { + margin: -1.5rem!important + } + + .m-sm-n5 { + margin: -3rem!important + } + + .mx-sm-n1 { + margin-right: -.25rem!important; + margin-left: -.25rem!important + } + + .mx-sm-n2 { + margin-right: -.5rem!important; + margin-left: -.5rem!important + } + + .mx-sm-n3 { + margin-right: -1rem!important; + margin-left: -1rem!important + } + + .mx-sm-n4 { + margin-right: -1.5rem!important; + margin-left: -1.5rem!important + } + + .mx-sm-n5 { + margin-right: -3rem!important; + margin-left: -3rem!important + } + + .my-sm-n1 { + margin-top: -.25rem!important; + margin-bottom: -.25rem!important + } + + .my-sm-n2 { + margin-top: -.5rem!important; + margin-bottom: -.5rem!important + } + + .my-sm-n3 { + margin-top: -1rem!important; + margin-bottom: -1rem!important + } + + .my-sm-n4 { + margin-top: -1.5rem!important; + margin-bottom: -1.5rem!important + } + + .my-sm-n5 { + margin-top: -3rem!important; + margin-bottom: -3rem!important + } + + .mt-sm-n1 { + margin-top: -.25rem!important + } + + .mt-sm-n2 { + margin-top: -.5rem!important + } + + .mt-sm-n3 { + margin-top: -1rem!important + } + + .mt-sm-n4 { + margin-top: -1.5rem!important + } + + .mt-sm-n5 { + margin-top: -3rem!important + } + + .me-sm-n1 { + margin-right: -.25rem!important + } + + .me-sm-n2 { + margin-right: -.5rem!important + } + + .me-sm-n3 { + margin-right: -1rem!important + } + + .me-sm-n4 { + margin-right: -1.5rem!important + } + + .me-sm-n5 { + margin-right: -3rem!important + } + + .mb-sm-n1 { + margin-bottom: -.25rem!important + } + + .mb-sm-n2 { + margin-bottom: -.5rem!important + } + + .mb-sm-n3 { + margin-bottom: -1rem!important + } + + .mb-sm-n4 { + margin-bottom: -1.5rem!important + } + + .mb-sm-n5 { + margin-bottom: -3rem!important + } + + .ms-sm-n1 { + margin-left: -.25rem!important + } + + .ms-sm-n2 { + margin-left: -.5rem!important + } + + .ms-sm-n3 { + margin-left: -1rem!important + } + + .ms-sm-n4 { + margin-left: -1.5rem!important + } + + .ms-sm-n5 { + margin-left: -3rem!important + } + + .p-sm-0 { + padding: 0!important + } + + .p-sm-1 { + padding: .25rem!important + } + + .p-sm-2 { + padding: .5rem!important + } + + .p-sm-3 { + padding: 1rem!important + } + + .p-sm-4 { + padding: 1.5rem!important + } + + .p-sm-5 { + padding: 3rem!important + } + + .px-sm-0 { + padding-right: 0!important; + padding-left: 0!important + } + + .px-sm-1 { + padding-right: .25rem!important; + padding-left: .25rem!important + } + + .px-sm-2 { + padding-right: .5rem!important; + padding-left: .5rem!important + } + + .px-sm-3 { + padding-right: 1rem!important; + padding-left: 1rem!important + } + + .px-sm-4 { + padding-right: 1.5rem!important; + padding-left: 1.5rem!important + } + + .px-sm-5 { + padding-right: 3rem!important; + padding-left: 3rem!important + } + + .py-sm-0 { + padding-top: 0!important; + padding-bottom: 0!important + } + + .py-sm-1 { + padding-top: .25rem!important; + padding-bottom: .25rem!important + } + + .py-sm-2 { + padding-top: .5rem!important; + padding-bottom: .5rem!important + } + + .py-sm-3 { + padding-top: 1rem!important; + padding-bottom: 1rem!important + } + + .py-sm-4 { + padding-top: 1.5rem!important; + padding-bottom: 1.5rem!important + } + + .py-sm-5 { + padding-top: 3rem!important; + padding-bottom: 3rem!important + } + + .pt-sm-0 { + padding-top: 0!important + } + + .pt-sm-1 { + padding-top: .25rem!important + } + + .pt-sm-2 { + padding-top: .5rem!important + } + + .pt-sm-3 { + padding-top: 1rem!important + } + + .pt-sm-4 { + padding-top: 1.5rem!important + } + + .pt-sm-5 { + padding-top: 3rem!important + } + + .pe-sm-0 { + padding-right: 0!important + } + + .pe-sm-1 { + padding-right: .25rem!important + } + + .pe-sm-2 { + padding-right: .5rem!important + } + + .pe-sm-3 { + padding-right: 1rem!important + } + + .pe-sm-4 { + padding-right: 1.5rem!important + } + + .pe-sm-5 { + padding-right: 3rem!important + } + + .pb-sm-0 { + padding-bottom: 0!important + } + + .pb-sm-1 { + padding-bottom: .25rem!important + } + + .pb-sm-2 { + padding-bottom: .5rem!important + } + + .pb-sm-3 { + padding-bottom: 1rem!important + } + + .pb-sm-4 { + padding-bottom: 1.5rem!important + } + + .pb-sm-5 { + padding-bottom: 3rem!important + } + + .ps-sm-0 { + padding-left: 0!important + } + + .ps-sm-1 { + padding-left: .25rem!important + } + + .ps-sm-2 { + padding-left: .5rem!important + } + + .ps-sm-3 { + padding-left: 1rem!important + } + + .ps-sm-4 { + padding-left: 1.5rem!important + } + + .ps-sm-5 { + padding-left: 3rem!important + } + + .gap-sm-0 { + gap: 0!important + } + + .gap-sm-1 { + gap: .25rem!important + } + + .gap-sm-2 { + gap: .5rem!important + } + + .gap-sm-3 { + gap: 1rem!important + } + + .gap-sm-4 { + gap: 1.5rem!important + } + + .gap-sm-5 { + gap: 3rem!important + } + + .text-sm-start { + text-align: left!important + } + + .text-sm-end { + text-align: right!important + } + + .text-sm-center { + text-align: center!important + } +} + +@media(min-width: 768px) { + .float-md-start { + float:left!important + } + + .float-md-end { + float: right!important + } + + .float-md-none { + float: none!important + } + + .d-md-inline { + display: inline!important + } + + .d-md-inline-block { + display: inline-block!important + } + + .d-md-block { + display: block!important + } + + .d-md-grid { + display: grid!important + } + + .d-md-table { + display: table!important + } + + .d-md-table-row { + display: table-row!important + } + + .d-md-table-cell { + display: table-cell!important + } + + .d-md-flex { + display: flex!important + } + + .d-md-inline-flex { + display: inline-flex!important + } + + .d-md-none { + display: none!important + } + + .flex-md-fill { + flex: 1 1 auto!important + } + + .flex-md-row { + flex-direction: row!important + } + + .flex-md-column { + flex-direction: column!important + } + + .flex-md-row-reverse { + flex-direction: row-reverse!important + } + + .flex-md-column-reverse { + flex-direction: column-reverse!important + } + + .flex-md-grow-0 { + flex-grow: 0!important + } + + .flex-md-grow-1 { + flex-grow: 1!important + } + + .flex-md-shrink-0 { + flex-shrink: 0!important + } + + .flex-md-shrink-1 { + flex-shrink: 1!important + } + + .flex-md-wrap { + flex-wrap: wrap!important + } + + .flex-md-nowrap { + flex-wrap: nowrap!important + } + + .flex-md-wrap-reverse { + flex-wrap: wrap-reverse!important + } + + .justify-content-md-start { + justify-content: flex-start!important + } + + .justify-content-md-end { + justify-content: flex-end!important + } + + .justify-content-md-center { + justify-content: center!important + } + + .justify-content-md-between { + justify-content: space-between!important + } + + .justify-content-md-around { + justify-content: space-around!important + } + + .justify-content-md-evenly { + justify-content: space-evenly!important + } + + .align-items-md-start { + align-items: flex-start!important + } + + .align-items-md-end { + align-items: flex-end!important + } + + .align-items-md-center { + align-items: center!important + } + + .align-items-md-baseline { + align-items: baseline!important + } + + .align-items-md-stretch { + align-items: stretch!important + } + + .align-content-md-start { + align-content: flex-start!important + } + + .align-content-md-end { + align-content: flex-end!important + } + + .align-content-md-center { + align-content: center!important + } + + .align-content-md-between { + align-content: space-between!important + } + + .align-content-md-around { + align-content: space-around!important + } + + .align-content-md-stretch { + align-content: stretch!important + } + + .align-self-md-auto { + align-self: auto!important + } + + .align-self-md-start { + align-self: flex-start!important + } + + .align-self-md-end { + align-self: flex-end!important + } + + .align-self-md-center { + align-self: center!important + } + + .align-self-md-baseline { + align-self: baseline!important + } + + .align-self-md-stretch { + align-self: stretch!important + } + + .order-md-first { + order: -1!important + } + + .order-md-0 { + order: 0!important + } + + .order-md-1 { + order: 1!important + } + + .order-md-2 { + order: 2!important + } + + .order-md-3 { + order: 3!important + } + + .order-md-4 { + order: 4!important + } + + .order-md-5 { + order: 5!important + } + + .order-md-last { + order: 6!important + } + + .m-md-0 { + margin: 0!important + } + + .m-md-1 { + margin: .25rem!important + } + + .m-md-2 { + margin: .5rem!important + } + + .m-md-3 { + margin: 1rem!important + } + + .m-md-4 { + margin: 1.5rem!important + } + + .m-md-5 { + margin: 3rem!important + } + + .m-md-auto { + margin: auto!important + } + + .mx-md-0 { + margin-right: 0!important; + margin-left: 0!important + } + + .mx-md-1 { + margin-right: .25rem!important; + margin-left: .25rem!important + } + + .mx-md-2 { + margin-right: .5rem!important; + margin-left: .5rem!important + } + + .mx-md-3 { + margin-right: 1rem!important; + margin-left: 1rem!important + } + + .mx-md-4 { + margin-right: 1.5rem!important; + margin-left: 1.5rem!important + } + + .mx-md-5 { + margin-right: 3rem!important; + margin-left: 3rem!important + } + + .mx-md-auto { + margin-right: auto!important; + margin-left: auto!important + } + + .my-md-0 { + margin-top: 0!important; + margin-bottom: 0!important + } + + .my-md-1 { + margin-top: .25rem!important; + margin-bottom: .25rem!important + } + + .my-md-2 { + margin-top: .5rem!important; + margin-bottom: .5rem!important + } + + .my-md-3 { + margin-top: 1rem!important; + margin-bottom: 1rem!important + } + + .my-md-4 { + margin-top: 1.5rem!important; + margin-bottom: 1.5rem!important + } + + .my-md-5 { + margin-top: 3rem!important; + margin-bottom: 3rem!important + } + + .my-md-auto { + margin-top: auto!important; + margin-bottom: auto!important + } + + .mt-md-0 { + margin-top: 0!important + } + + .mt-md-1 { + margin-top: .25rem!important + } + + .mt-md-2 { + margin-top: .5rem!important + } + + .mt-md-3 { + margin-top: 1rem!important + } + + .mt-md-4 { + margin-top: 1.5rem!important + } + + .mt-md-5 { + margin-top: 3rem!important + } + + .mt-md-auto { + margin-top: auto!important + } + + .me-md-0 { + margin-right: 0!important + } + + .me-md-1 { + margin-right: .25rem!important + } + + .me-md-2 { + margin-right: .5rem!important + } + + .me-md-3 { + margin-right: 1rem!important + } + + .me-md-4 { + margin-right: 1.5rem!important + } + + .me-md-5 { + margin-right: 3rem!important + } + + .me-md-auto { + margin-right: auto!important + } + + .mb-md-0 { + margin-bottom: 0!important + } + + .mb-md-1 { + margin-bottom: .25rem!important + } + + .mb-md-2 { + margin-bottom: .5rem!important + } + + .mb-md-3 { + margin-bottom: 1rem!important + } + + .mb-md-4 { + margin-bottom: 1.5rem!important + } + + .mb-md-5 { + margin-bottom: 3rem!important + } + + .mb-md-auto { + margin-bottom: auto!important + } + + .mb-md-6 { + margin-bottom: 3.5rem!important + } + + .mb-md-7 { + margin-bottom: 4rem!important + } + + .mb-md-8 { + margin-bottom: 5rem!important + } + + .mb-md-9 { + margin-bottom: 6rem!important + } + + .mb-md-10 { + margin-bottom: 8rem!important + } + + .mb-md-11 { + margin-bottom: 10rem!important + } + + .mb-md-12 { + margin-bottom: 12rem!important + } + + .mb-md-13 { + margin-bottom: 14rem!important + } + + .mb-md-14 { + margin-bottom: 16rem!important + } + + .ms-md-0 { + margin-left: 0!important + } + + .ms-md-1 { + margin-left: .25rem!important + } + + .ms-md-2 { + margin-left: .5rem!important + } + + .ms-md-3 { + margin-left: 1rem!important + } + + .ms-md-4 { + margin-left: 1.5rem!important + } + + .ms-md-5 { + margin-left: 3rem!important + } + + .ms-md-auto { + margin-left: auto!important + } + + .m-md-n1 { + margin: -.25rem!important + } + + .m-md-n2 { + margin: -.5rem!important + } + + .m-md-n3 { + margin: -1rem!important + } + + .m-md-n4 { + margin: -1.5rem!important + } + + .m-md-n5 { + margin: -3rem!important + } + + .mx-md-n1 { + margin-right: -.25rem!important; + margin-left: -.25rem!important + } + + .mx-md-n2 { + margin-right: -.5rem!important; + margin-left: -.5rem!important + } + + .mx-md-n3 { + margin-right: -1rem!important; + margin-left: -1rem!important + } + + .mx-md-n4 { + margin-right: -1.5rem!important; + margin-left: -1.5rem!important + } + + .mx-md-n5 { + margin-right: -3rem!important; + margin-left: -3rem!important + } + + .my-md-n1 { + margin-top: -.25rem!important; + margin-bottom: -.25rem!important + } + + .my-md-n2 { + margin-top: -.5rem!important; + margin-bottom: -.5rem!important + } + + .my-md-n3 { + margin-top: -1rem!important; + margin-bottom: -1rem!important + } + + .my-md-n4 { + margin-top: -1.5rem!important; + margin-bottom: -1.5rem!important + } + + .my-md-n5 { + margin-top: -3rem!important; + margin-bottom: -3rem!important + } + + .mt-md-n1 { + margin-top: -.25rem!important + } + + .mt-md-n2 { + margin-top: -.5rem!important + } + + .mt-md-n3 { + margin-top: -1rem!important + } + + .mt-md-n4 { + margin-top: -1.5rem!important + } + + .mt-md-n5 { + margin-top: -3rem!important + } + + .me-md-n1 { + margin-right: -.25rem!important + } + + .me-md-n2 { + margin-right: -.5rem!important + } + + .me-md-n3 { + margin-right: -1rem!important + } + + .me-md-n4 { + margin-right: -1.5rem!important + } + + .me-md-n5 { + margin-right: -3rem!important + } + + .mb-md-n1 { + margin-bottom: -.25rem!important + } + + .mb-md-n2 { + margin-bottom: -.5rem!important + } + + .mb-md-n3 { + margin-bottom: -1rem!important + } + + .mb-md-n4 { + margin-bottom: -1.5rem!important + } + + .mb-md-n5 { + margin-bottom: -3rem!important + } + + .ms-md-n1 { + margin-left: -.25rem!important + } + + .ms-md-n2 { + margin-left: -.5rem!important + } + + .ms-md-n3 { + margin-left: -1rem!important + } + + .ms-md-n4 { + margin-left: -1.5rem!important + } + + .ms-md-n5 { + margin-left: -3rem!important + } + + .p-md-0 { + padding: 0!important + } + + .p-md-1 { + padding: .25rem!important + } + + .p-md-2 { + padding: .5rem!important + } + + .p-md-3 { + padding: 1rem!important + } + + .p-md-4 { + padding: 1.5rem!important + } + + .p-md-5 { + padding: 3rem!important + } + + .px-md-0 { + padding-right: 0!important; + padding-left: 0!important + } + + .px-md-1 { + padding-right: .25rem!important; + padding-left: .25rem!important + } + + .px-md-2 { + padding-right: .5rem!important; + padding-left: .5rem!important + } + + .px-md-3 { + padding-right: 1rem!important; + padding-left: 1rem!important + } + + .px-md-4 { + padding-right: 1.5rem!important; + padding-left: 1.5rem!important + } + + .px-md-5 { + padding-right: 3rem!important; + padding-left: 3rem!important + } + + .py-md-0 { + padding-top: 0!important; + padding-bottom: 0!important + } + + .py-md-1 { + padding-top: .25rem!important; + padding-bottom: .25rem!important + } + + .py-md-2 { + padding-top: .5rem!important; + padding-bottom: .5rem!important + } + + .py-md-3 { + padding-top: 1rem!important; + padding-bottom: 1rem!important + } + + .py-md-4 { + padding-top: 1.5rem!important; + padding-bottom: 1.5rem!important + } + + .py-md-5 { + padding-top: 3rem!important; + padding-bottom: 3rem!important + } + + .pt-md-0 { + padding-top: 0!important + } + + .pt-md-1 { + padding-top: .25rem!important + } + + .pt-md-2 { + padding-top: .5rem!important + } + + .pt-md-3 { + padding-top: 1rem!important + } + + .pt-md-4 { + padding-top: 1.5rem!important + } + + .pt-md-5 { + padding-top: 3rem!important + } + + .pe-md-0 { + padding-right: 0!important + } + + .pe-md-1 { + padding-right: .25rem!important + } + + .pe-md-2 { + padding-right: .5rem!important + } + + .pe-md-3 { + padding-right: 1rem!important + } + + .pe-md-4 { + padding-right: 1.5rem!important + } + + .pe-md-5 { + padding-right: 3rem!important + } + + .pb-md-0 { + padding-bottom: 0!important + } + + .pb-md-1 { + padding-bottom: .25rem!important + } + + .pb-md-2 { + padding-bottom: .5rem!important + } + + .pb-md-3 { + padding-bottom: 1rem!important + } + + .pb-md-4 { + padding-bottom: 1.5rem!important + } + + .pb-md-5 { + padding-bottom: 3rem!important + } + + .ps-md-0 { + padding-left: 0!important + } + + .ps-md-1 { + padding-left: .25rem!important + } + + .ps-md-2 { + padding-left: .5rem!important + } + + .ps-md-3 { + padding-left: 1rem!important + } + + .ps-md-4 { + padding-left: 1.5rem!important + } + + .ps-md-5 { + padding-left: 3rem!important + } + + .gap-md-0 { + gap: 0!important + } + + .gap-md-1 { + gap: .25rem!important + } + + .gap-md-2 { + gap: .5rem!important + } + + .gap-md-3 { + gap: 1rem!important + } + + .gap-md-4 { + gap: 1.5rem!important + } + + .gap-md-5 { + gap: 3rem!important + } + + .text-md-start { + text-align: left!important + } + + .text-md-end { + text-align: right!important + } + + .text-md-center { + text-align: center!important + } +} + +@media(min-width: 992px) { + .float-lg-start { + float:left!important + } + + .float-lg-end { + float: right!important + } + + .float-lg-none { + float: none!important + } + + .d-lg-inline { + display: inline!important + } + + .d-lg-inline-block { + display: inline-block!important + } + + .d-lg-block { + display: block!important + } + + .d-lg-grid { + display: grid!important + } + + .d-lg-table { + display: table!important + } + + .d-lg-table-row { + display: table-row!important + } + + .d-lg-table-cell { + display: table-cell!important + } + + .d-lg-flex { + display: flex!important + } + + .d-lg-inline-flex { + display: inline-flex!important + } + + .d-lg-none { + display: none!important + } + + .flex-lg-fill { + flex: 1 1 auto!important + } + + .flex-lg-row { + flex-direction: row!important + } + + .flex-lg-column { + flex-direction: column!important + } + + .flex-lg-row-reverse { + flex-direction: row-reverse!important + } + + .flex-lg-column-reverse { + flex-direction: column-reverse!important + } + + .flex-lg-grow-0 { + flex-grow: 0!important + } + + .flex-lg-grow-1 { + flex-grow: 1!important + } + + .flex-lg-shrink-0 { + flex-shrink: 0!important + } + + .flex-lg-shrink-1 { + flex-shrink: 1!important + } + + .flex-lg-wrap { + flex-wrap: wrap!important + } + + .flex-lg-nowrap { + flex-wrap: nowrap!important + } + + .flex-lg-wrap-reverse { + flex-wrap: wrap-reverse!important + } + + .justify-content-lg-start { + justify-content: flex-start!important + } + + .justify-content-lg-end { + justify-content: flex-end!important + } + + .justify-content-lg-center { + justify-content: center!important + } + + .justify-content-lg-between { + justify-content: space-between!important + } + + .justify-content-lg-around { + justify-content: space-around!important + } + + .justify-content-lg-evenly { + justify-content: space-evenly!important + } + + .align-items-lg-start { + align-items: flex-start!important + } + + .align-items-lg-end { + align-items: flex-end!important + } + + .align-items-lg-center { + align-items: center!important + } + + .align-items-lg-baseline { + align-items: baseline!important + } + + .align-items-lg-stretch { + align-items: stretch!important + } + + .align-content-lg-start { + align-content: flex-start!important + } + + .align-content-lg-end { + align-content: flex-end!important + } + + .align-content-lg-center { + align-content: center!important + } + + .align-content-lg-between { + align-content: space-between!important + } + + .align-content-lg-around { + align-content: space-around!important + } + + .align-content-lg-stretch { + align-content: stretch!important + } + + .align-self-lg-auto { + align-self: auto!important + } + + .align-self-lg-start { + align-self: flex-start!important + } + + .align-self-lg-end { + align-self: flex-end!important + } + + .align-self-lg-center { + align-self: center!important + } + + .align-self-lg-baseline { + align-self: baseline!important + } + + .align-self-lg-stretch { + align-self: stretch!important + } + + .order-lg-first { + order: -1!important + } + + .order-lg-0 { + order: 0!important + } + + .order-lg-1 { + order: 1!important + } + + .order-lg-2 { + order: 2!important + } + + .order-lg-3 { + order: 3!important + } + + .order-lg-4 { + order: 4!important + } + + .order-lg-5 { + order: 5!important + } + + .order-lg-last { + order: 6!important + } + + .m-lg-0 { + margin: 0!important + } + + .m-lg-1 { + margin: .25rem!important + } + + .m-lg-2 { + margin: .5rem!important + } + + .m-lg-3 { + margin: 1rem!important + } + + .m-lg-4 { + margin: 1.5rem!important + } + + .m-lg-5 { + margin: 3rem!important + } + + .m-lg-auto { + margin: auto!important + } + + .mx-lg-0 { + margin-right: 0!important; + margin-left: 0!important + } + + .mx-lg-1 { + margin-right: .25rem!important; + margin-left: .25rem!important + } + + .mx-lg-2 { + margin-right: .5rem!important; + margin-left: .5rem!important + } + + .mx-lg-3 { + margin-right: 1rem!important; + margin-left: 1rem!important + } + + .mx-lg-4 { + margin-right: 1.5rem!important; + margin-left: 1.5rem!important + } + + .mx-lg-5 { + margin-right: 3rem!important; + margin-left: 3rem!important + } + + .mx-lg-auto { + margin-right: auto!important; + margin-left: auto!important + } + + .my-lg-0 { + margin-top: 0!important; + margin-bottom: 0!important + } + + .my-lg-1 { + margin-top: .25rem!important; + margin-bottom: .25rem!important + } + + .my-lg-2 { + margin-top: .5rem!important; + margin-bottom: .5rem!important + } + + .my-lg-3 { + margin-top: 1rem!important; + margin-bottom: 1rem!important + } + + .my-lg-4 { + margin-top: 1.5rem!important; + margin-bottom: 1.5rem!important + } + + .my-lg-5 { + margin-top: 3rem!important; + margin-bottom: 3rem!important + } + + .my-lg-auto { + margin-top: auto!important; + margin-bottom: auto!important + } + + .mt-lg-0 { + margin-top: 0!important + } + + .mt-lg-1 { + margin-top: .25rem!important + } + + .mt-lg-2 { + margin-top: .5rem!important + } + + .mt-lg-3 { + margin-top: 1rem!important + } + + .mt-lg-4 { + margin-top: 1.5rem!important + } + + .mt-lg-5 { + margin-top: 3rem!important + } + + .mt-lg-auto { + margin-top: auto!important + } + + .me-lg-0 { + margin-right: 0!important + } + + .me-lg-1 { + margin-right: .25rem!important + } + + .me-lg-2 { + margin-right: .5rem!important + } + + .me-lg-3 { + margin-right: 1rem!important + } + + .me-lg-4 { + margin-right: 1.5rem!important + } + + .me-lg-5 { + margin-right: 3rem!important + } + + .me-lg-auto { + margin-right: auto!important + } + + .mb-lg-0 { + margin-bottom: 0!important + } + + .mb-lg-1 { + margin-bottom: .25rem!important + } + + .mb-lg-2 { + margin-bottom: .5rem!important + } + + .mb-lg-3 { + margin-bottom: 1rem!important + } + + .mb-lg-4 { + margin-bottom: 1.5rem!important + } + + .mb-lg-5 { + margin-bottom: 3rem!important + } + + .mb-lg-auto { + margin-bottom: auto!important + } + + .mb-lg-6 { + margin-bottom: 3.5rem!important + } + + .mb-lg-7 { + margin-bottom: 4rem!important + } + + .mb-lg-8 { + margin-bottom: 5rem!important + } + + .mb-lg-9 { + margin-bottom: 6rem!important + } + + .mb-lg-10 { + margin-bottom: 8rem!important + } + + .mb-lg-11 { + margin-bottom: 10rem!important + } + + .mb-lg-12 { + margin-bottom: 12rem!important + } + + .mb-lg-13 { + margin-bottom: 14rem!important + } + + .mb-lg-14 { + margin-bottom: 16rem!important + } + + .ms-lg-0 { + margin-left: 0!important + } + + .ms-lg-1 { + margin-left: .25rem!important + } + + .ms-lg-2 { + margin-left: .5rem!important + } + + .ms-lg-3 { + margin-left: 1rem!important + } + + .ms-lg-4 { + margin-left: 1.5rem!important + } + + .ms-lg-5 { + margin-left: 3rem!important + } + + .ms-lg-auto { + margin-left: auto!important + } + + .m-lg-n1 { + margin: -.25rem!important + } + + .m-lg-n2 { + margin: -.5rem!important + } + + .m-lg-n3 { + margin: -1rem!important + } + + .m-lg-n4 { + margin: -1.5rem!important + } + + .m-lg-n5 { + margin: -3rem!important + } + + .mx-lg-n1 { + margin-right: -.25rem!important; + margin-left: -.25rem!important + } + + .mx-lg-n2 { + margin-right: -.5rem!important; + margin-left: -.5rem!important + } + + .mx-lg-n3 { + margin-right: -1rem!important; + margin-left: -1rem!important + } + + .mx-lg-n4 { + margin-right: -1.5rem!important; + margin-left: -1.5rem!important + } + + .mx-lg-n5 { + margin-right: -3rem!important; + margin-left: -3rem!important + } + + .my-lg-n1 { + margin-top: -.25rem!important; + margin-bottom: -.25rem!important + } + + .my-lg-n2 { + margin-top: -.5rem!important; + margin-bottom: -.5rem!important + } + + .my-lg-n3 { + margin-top: -1rem!important; + margin-bottom: -1rem!important + } + + .my-lg-n4 { + margin-top: -1.5rem!important; + margin-bottom: -1.5rem!important + } + + .my-lg-n5 { + margin-top: -3rem!important; + margin-bottom: -3rem!important + } + + .mt-lg-n1 { + margin-top: -.25rem!important + } + + .mt-lg-n2 { + margin-top: -.5rem!important + } + + .mt-lg-n3 { + margin-top: -1rem!important + } + + .mt-lg-n4 { + margin-top: -1.5rem!important + } + + .mt-lg-n5 { + margin-top: -3rem!important + } + + .me-lg-n1 { + margin-right: -.25rem!important + } + + .me-lg-n2 { + margin-right: -.5rem!important + } + + .me-lg-n3 { + margin-right: -1rem!important + } + + .me-lg-n4 { + margin-right: -1.5rem!important + } + + .me-lg-n5 { + margin-right: -3rem!important + } + + .mb-lg-n1 { + margin-bottom: -.25rem!important + } + + .mb-lg-n2 { + margin-bottom: -.5rem!important + } + + .mb-lg-n3 { + margin-bottom: -1rem!important + } + + .mb-lg-n4 { + margin-bottom: -1.5rem!important + } + + .mb-lg-n5 { + margin-bottom: -3rem!important + } + + .ms-lg-n1 { + margin-left: -.25rem!important + } + + .ms-lg-n2 { + margin-left: -.5rem!important + } + + .ms-lg-n3 { + margin-left: -1rem!important + } + + .ms-lg-n4 { + margin-left: -1.5rem!important + } + + .ms-lg-n5 { + margin-left: -3rem!important + } + + .p-lg-0 { + padding: 0!important + } + + .p-lg-1 { + padding: .25rem!important + } + + .p-lg-2 { + padding: .5rem!important + } + + .p-lg-3 { + padding: 1rem!important + } + + .p-lg-4 { + padding: 1.5rem!important + } + + .p-lg-5 { + padding: 3rem!important + } + + .px-lg-0 { + padding-right: 0!important; + padding-left: 0!important + } + + .px-lg-1 { + padding-right: .25rem!important; + padding-left: .25rem!important + } + + .px-lg-2 { + padding-right: .5rem!important; + padding-left: .5rem!important + } + + .px-lg-3 { + padding-right: 1rem!important; + padding-left: 1rem!important + } + + .px-lg-4 { + padding-right: 1.5rem!important; + padding-left: 1.5rem!important + } + + .px-lg-5 { + padding-right: 3rem!important; + padding-left: 3rem!important + } + + .py-lg-0 { + padding-top: 0!important; + padding-bottom: 0!important + } + + .py-lg-1 { + padding-top: .25rem!important; + padding-bottom: .25rem!important + } + + .py-lg-2 { + padding-top: .5rem!important; + padding-bottom: .5rem!important + } + + .py-lg-3 { + padding-top: 1rem!important; + padding-bottom: 1rem!important + } + + .py-lg-4 { + padding-top: 1.5rem!important; + padding-bottom: 1.5rem!important + } + + .py-lg-5 { + padding-top: 3rem!important; + padding-bottom: 3rem!important + } + + .pt-lg-0 { + padding-top: 0!important + } + + .pt-lg-1 { + padding-top: .25rem!important + } + + .pt-lg-2 { + padding-top: .5rem!important + } + + .pt-lg-3 { + padding-top: 1rem!important + } + + .pt-lg-4 { + padding-top: 1.5rem!important + } + + .pt-lg-5 { + padding-top: 3rem!important + } + + .pe-lg-0 { + padding-right: 0!important + } + + .pe-lg-1 { + padding-right: .25rem!important + } + + .pe-lg-2 { + padding-right: .5rem!important + } + + .pe-lg-3 { + padding-right: 1rem!important + } + + .pe-lg-4 { + padding-right: 1.5rem!important + } + + .pe-lg-5 { + padding-right: 3rem!important + } + + .pb-lg-0 { + padding-bottom: 0!important + } + + .pb-lg-1 { + padding-bottom: .25rem!important + } + + .pb-lg-2 { + padding-bottom: .5rem!important + } + + .pb-lg-3 { + padding-bottom: 1rem!important + } + + .pb-lg-4 { + padding-bottom: 1.5rem!important + } + + .pb-lg-5 { + padding-bottom: 3rem!important + } + + .ps-lg-0 { + padding-left: 0!important + } + + .ps-lg-1 { + padding-left: .25rem!important + } + + .ps-lg-2 { + padding-left: .5rem!important + } + + .ps-lg-3 { + padding-left: 1rem!important + } + + .ps-lg-4 { + padding-left: 1.5rem!important + } + + .ps-lg-5 { + padding-left: 3rem!important + } + + .gap-lg-0 { + gap: 0!important + } + + .gap-lg-1 { + gap: .25rem!important + } + + .gap-lg-2 { + gap: .5rem!important + } + + .gap-lg-3 { + gap: 1rem!important + } + + .gap-lg-4 { + gap: 1.5rem!important + } + + .gap-lg-5 { + gap: 3rem!important + } + + .text-lg-start { + text-align: left!important + } + + .text-lg-end { + text-align: right!important + } + + .text-lg-center { + text-align: center!important + } +} + +@media(min-width: 1200px) { + .float-xl-start { + float:left!important + } + + .float-xl-end { + float: right!important + } + + .float-xl-none { + float: none!important + } + + .d-xl-inline { + display: inline!important + } + + .d-xl-inline-block { + display: inline-block!important + } + + .d-xl-block { + display: block!important + } + + .d-xl-grid { + display: grid!important + } + + .d-xl-table { + display: table!important + } + + .d-xl-table-row { + display: table-row!important + } + + .d-xl-table-cell { + display: table-cell!important + } + + .d-xl-flex { + display: flex!important + } + + .d-xl-inline-flex { + display: inline-flex!important + } + + .d-xl-none { + display: none!important + } + + .flex-xl-fill { + flex: 1 1 auto!important + } + + .flex-xl-row { + flex-direction: row!important + } + + .flex-xl-column { + flex-direction: column!important + } + + .flex-xl-row-reverse { + flex-direction: row-reverse!important + } + + .flex-xl-column-reverse { + flex-direction: column-reverse!important + } + + .flex-xl-grow-0 { + flex-grow: 0!important + } + + .flex-xl-grow-1 { + flex-grow: 1!important + } + + .flex-xl-shrink-0 { + flex-shrink: 0!important + } + + .flex-xl-shrink-1 { + flex-shrink: 1!important + } + + .flex-xl-wrap { + flex-wrap: wrap!important + } + + .flex-xl-nowrap { + flex-wrap: nowrap!important + } + + .flex-xl-wrap-reverse { + flex-wrap: wrap-reverse!important + } + + .justify-content-xl-start { + justify-content: flex-start!important + } + + .justify-content-xl-end { + justify-content: flex-end!important + } + + .justify-content-xl-center { + justify-content: center!important + } + + .justify-content-xl-between { + justify-content: space-between!important + } + + .justify-content-xl-around { + justify-content: space-around!important + } + + .justify-content-xl-evenly { + justify-content: space-evenly!important + } + + .align-items-xl-start { + align-items: flex-start!important + } + + .align-items-xl-end { + align-items: flex-end!important + } + + .align-items-xl-center { + align-items: center!important + } + + .align-items-xl-baseline { + align-items: baseline!important + } + + .align-items-xl-stretch { + align-items: stretch!important + } + + .align-content-xl-start { + align-content: flex-start!important + } + + .align-content-xl-end { + align-content: flex-end!important + } + + .align-content-xl-center { + align-content: center!important + } + + .align-content-xl-between { + align-content: space-between!important + } + + .align-content-xl-around { + align-content: space-around!important + } + + .align-content-xl-stretch { + align-content: stretch!important + } + + .align-self-xl-auto { + align-self: auto!important + } + + .align-self-xl-start { + align-self: flex-start!important + } + + .align-self-xl-end { + align-self: flex-end!important + } + + .align-self-xl-center { + align-self: center!important + } + + .align-self-xl-baseline { + align-self: baseline!important + } + + .align-self-xl-stretch { + align-self: stretch!important + } + + .order-xl-first { + order: -1!important + } + + .order-xl-0 { + order: 0!important + } + + .order-xl-1 { + order: 1!important + } + + .order-xl-2 { + order: 2!important + } + + .order-xl-3 { + order: 3!important + } + + .order-xl-4 { + order: 4!important + } + + .order-xl-5 { + order: 5!important + } + + .order-xl-last { + order: 6!important + } + + .m-xl-0 { + margin: 0!important + } + + .m-xl-1 { + margin: .25rem!important + } + + .m-xl-2 { + margin: .5rem!important + } + + .m-xl-3 { + margin: 1rem!important + } + + .m-xl-4 { + margin: 1.5rem!important + } + + .m-xl-5 { + margin: 3rem!important + } + + .m-xl-auto { + margin: auto!important + } + + .mx-xl-0 { + margin-right: 0!important; + margin-left: 0!important + } + + .mx-xl-1 { + margin-right: .25rem!important; + margin-left: .25rem!important + } + + .mx-xl-2 { + margin-right: .5rem!important; + margin-left: .5rem!important + } + + .mx-xl-3 { + margin-right: 1rem!important; + margin-left: 1rem!important + } + + .mx-xl-4 { + margin-right: 1.5rem!important; + margin-left: 1.5rem!important + } + + .mx-xl-5 { + margin-right: 3rem!important; + margin-left: 3rem!important + } + + .mx-xl-auto { + margin-right: auto!important; + margin-left: auto!important + } + + .my-xl-0 { + margin-top: 0!important; + margin-bottom: 0!important + } + + .my-xl-1 { + margin-top: .25rem!important; + margin-bottom: .25rem!important + } + + .my-xl-2 { + margin-top: .5rem!important; + margin-bottom: .5rem!important + } + + .my-xl-3 { + margin-top: 1rem!important; + margin-bottom: 1rem!important + } + + .my-xl-4 { + margin-top: 1.5rem!important; + margin-bottom: 1.5rem!important + } + + .my-xl-5 { + margin-top: 3rem!important; + margin-bottom: 3rem!important + } + + .my-xl-auto { + margin-top: auto!important; + margin-bottom: auto!important + } + + .mt-xl-0 { + margin-top: 0!important + } + + .mt-xl-1 { + margin-top: .25rem!important + } + + .mt-xl-2 { + margin-top: .5rem!important + } + + .mt-xl-3 { + margin-top: 1rem!important + } + + .mt-xl-4 { + margin-top: 1.5rem!important + } + + .mt-xl-5 { + margin-top: 3rem!important + } + + .mt-xl-auto { + margin-top: auto!important + } + + .me-xl-0 { + margin-right: 0!important + } + + .me-xl-1 { + margin-right: .25rem!important + } + + .me-xl-2 { + margin-right: .5rem!important + } + + .me-xl-3 { + margin-right: 1rem!important + } + + .me-xl-4 { + margin-right: 1.5rem!important + } + + .me-xl-5 { + margin-right: 3rem!important + } + + .me-xl-auto { + margin-right: auto!important + } + + .mb-xl-0 { + margin-bottom: 0!important + } + + .mb-xl-1 { + margin-bottom: .25rem!important + } + + .mb-xl-2 { + margin-bottom: .5rem!important + } + + .mb-xl-3 { + margin-bottom: 1rem!important + } + + .mb-xl-4 { + margin-bottom: 1.5rem!important + } + + .mb-xl-5 { + margin-bottom: 3rem!important + } + + .mb-xl-auto { + margin-bottom: auto!important + } + + .mb-xl-6 { + margin-bottom: 3.5rem!important + } + + .mb-xl-7 { + margin-bottom: 4rem!important + } + + .mb-xl-8 { + margin-bottom: 5rem!important + } + + .mb-xl-9 { + margin-bottom: 6rem!important + } + + .mb-xl-10 { + margin-bottom: 8rem!important + } + + .mb-xl-11 { + margin-bottom: 10rem!important + } + + .mb-xl-12 { + margin-bottom: 12rem!important + } + + .mb-xl-13 { + margin-bottom: 14rem!important + } + + .mb-xl-14 { + margin-bottom: 16rem!important + } + + .ms-xl-0 { + margin-left: 0!important + } + + .ms-xl-1 { + margin-left: .25rem!important + } + + .ms-xl-2 { + margin-left: .5rem!important + } + + .ms-xl-3 { + margin-left: 1rem!important + } + + .ms-xl-4 { + margin-left: 1.5rem!important + } + + .ms-xl-5 { + margin-left: 3rem!important + } + + .ms-xl-auto { + margin-left: auto!important + } + + .m-xl-n1 { + margin: -.25rem!important + } + + .m-xl-n2 { + margin: -.5rem!important + } + + .m-xl-n3 { + margin: -1rem!important + } + + .m-xl-n4 { + margin: -1.5rem!important + } + + .m-xl-n5 { + margin: -3rem!important + } + + .mx-xl-n1 { + margin-right: -.25rem!important; + margin-left: -.25rem!important + } + + .mx-xl-n2 { + margin-right: -.5rem!important; + margin-left: -.5rem!important + } + + .mx-xl-n3 { + margin-right: -1rem!important; + margin-left: -1rem!important + } + + .mx-xl-n4 { + margin-right: -1.5rem!important; + margin-left: -1.5rem!important + } + + .mx-xl-n5 { + margin-right: -3rem!important; + margin-left: -3rem!important + } + + .my-xl-n1 { + margin-top: -.25rem!important; + margin-bottom: -.25rem!important + } + + .my-xl-n2 { + margin-top: -.5rem!important; + margin-bottom: -.5rem!important + } + + .my-xl-n3 { + margin-top: -1rem!important; + margin-bottom: -1rem!important + } + + .my-xl-n4 { + margin-top: -1.5rem!important; + margin-bottom: -1.5rem!important + } + + .my-xl-n5 { + margin-top: -3rem!important; + margin-bottom: -3rem!important + } + + .mt-xl-n1 { + margin-top: -.25rem!important + } + + .mt-xl-n2 { + margin-top: -.5rem!important + } + + .mt-xl-n3 { + margin-top: -1rem!important + } + + .mt-xl-n4 { + margin-top: -1.5rem!important + } + + .mt-xl-n5 { + margin-top: -3rem!important + } + + .me-xl-n1 { + margin-right: -.25rem!important + } + + .me-xl-n2 { + margin-right: -.5rem!important + } + + .me-xl-n3 { + margin-right: -1rem!important + } + + .me-xl-n4 { + margin-right: -1.5rem!important + } + + .me-xl-n5 { + margin-right: -3rem!important + } + + .mb-xl-n1 { + margin-bottom: -.25rem!important + } + + .mb-xl-n2 { + margin-bottom: -.5rem!important + } + + .mb-xl-n3 { + margin-bottom: -1rem!important + } + + .mb-xl-n4 { + margin-bottom: -1.5rem!important + } + + .mb-xl-n5 { + margin-bottom: -3rem!important + } + + .ms-xl-n1 { + margin-left: -.25rem!important + } + + .ms-xl-n2 { + margin-left: -.5rem!important + } + + .ms-xl-n3 { + margin-left: -1rem!important + } + + .ms-xl-n4 { + margin-left: -1.5rem!important + } + + .ms-xl-n5 { + margin-left: -3rem!important + } + + .p-xl-0 { + padding: 0!important + } + + .p-xl-1 { + padding: .25rem!important + } + + .p-xl-2 { + padding: .5rem!important + } + + .p-xl-3 { + padding: 1rem!important + } + + .p-xl-4 { + padding: 1.5rem!important + } + + .p-xl-5 { + padding: 3rem!important + } + + .px-xl-0 { + padding-right: 0!important; + padding-left: 0!important + } + + .px-xl-1 { + padding-right: .25rem!important; + padding-left: .25rem!important + } + + .px-xl-2 { + padding-right: .5rem!important; + padding-left: .5rem!important + } + + .px-xl-3 { + padding-right: 1rem!important; + padding-left: 1rem!important + } + + .px-xl-4 { + padding-right: 1.5rem!important; + padding-left: 1.5rem!important + } + + .px-xl-5 { + padding-right: 3rem!important; + padding-left: 3rem!important + } + + .py-xl-0 { + padding-top: 0!important; + padding-bottom: 0!important + } + + .py-xl-1 { + padding-top: .25rem!important; + padding-bottom: .25rem!important + } + + .py-xl-2 { + padding-top: .5rem!important; + padding-bottom: .5rem!important + } + + .py-xl-3 { + padding-top: 1rem!important; + padding-bottom: 1rem!important + } + + .py-xl-4 { + padding-top: 1.5rem!important; + padding-bottom: 1.5rem!important + } + + .py-xl-5 { + padding-top: 3rem!important; + padding-bottom: 3rem!important + } + + .pt-xl-0 { + padding-top: 0!important + } + + .pt-xl-1 { + padding-top: .25rem!important + } + + .pt-xl-2 { + padding-top: .5rem!important + } + + .pt-xl-3 { + padding-top: 1rem!important + } + + .pt-xl-4 { + padding-top: 1.5rem!important + } + + .pt-xl-5 { + padding-top: 3rem!important + } + + .pe-xl-0 { + padding-right: 0!important + } + + .pe-xl-1 { + padding-right: .25rem!important + } + + .pe-xl-2 { + padding-right: .5rem!important + } + + .pe-xl-3 { + padding-right: 1rem!important + } + + .pe-xl-4 { + padding-right: 1.5rem!important + } + + .pe-xl-5 { + padding-right: 3rem!important + } + + .pb-xl-0 { + padding-bottom: 0!important + } + + .pb-xl-1 { + padding-bottom: .25rem!important + } + + .pb-xl-2 { + padding-bottom: .5rem!important + } + + .pb-xl-3 { + padding-bottom: 1rem!important + } + + .pb-xl-4 { + padding-bottom: 1.5rem!important + } + + .pb-xl-5 { + padding-bottom: 3rem!important + } + + .ps-xl-0 { + padding-left: 0!important + } + + .ps-xl-1 { + padding-left: .25rem!important + } + + .ps-xl-2 { + padding-left: .5rem!important + } + + .ps-xl-3 { + padding-left: 1rem!important + } + + .ps-xl-4 { + padding-left: 1.5rem!important + } + + .ps-xl-5 { + padding-left: 3rem!important + } + + .gap-xl-0 { + gap: 0!important + } + + .gap-xl-1 { + gap: .25rem!important + } + + .gap-xl-2 { + gap: .5rem!important + } + + .gap-xl-3 { + gap: 1rem!important + } + + .gap-xl-4 { + gap: 1.5rem!important + } + + .gap-xl-5 { + gap: 3rem!important + } + + .text-xl-start { + text-align: left!important + } + + .text-xl-end { + text-align: right!important + } + + .text-xl-center { + text-align: center!important + } +} + +@media(min-width: 1400px) { + .float-xxl-start { + float:left!important + } + + .float-xxl-end { + float: right!important + } + + .float-xxl-none { + float: none!important + } + + .d-xxl-inline { + display: inline!important + } + + .d-xxl-inline-block { + display: inline-block!important + } + + .d-xxl-block { + display: block!important + } + + .d-xxl-grid { + display: grid!important + } + + .d-xxl-table { + display: table!important + } + + .d-xxl-table-row { + display: table-row!important + } + + .d-xxl-table-cell { + display: table-cell!important + } + + .d-xxl-flex { + display: flex!important + } + + .d-xxl-inline-flex { + display: inline-flex!important + } + + .d-xxl-none { + display: none!important + } + + .flex-xxl-fill { + flex: 1 1 auto!important + } + + .flex-xxl-row { + flex-direction: row!important + } + + .flex-xxl-column { + flex-direction: column!important + } + + .flex-xxl-row-reverse { + flex-direction: row-reverse!important + } + + .flex-xxl-column-reverse { + flex-direction: column-reverse!important + } + + .flex-xxl-grow-0 { + flex-grow: 0!important + } + + .flex-xxl-grow-1 { + flex-grow: 1!important + } + + .flex-xxl-shrink-0 { + flex-shrink: 0!important + } + + .flex-xxl-shrink-1 { + flex-shrink: 1!important + } + + .flex-xxl-wrap { + flex-wrap: wrap!important + } + + .flex-xxl-nowrap { + flex-wrap: nowrap!important + } + + .flex-xxl-wrap-reverse { + flex-wrap: wrap-reverse!important + } + + .justify-content-xxl-start { + justify-content: flex-start!important + } + + .justify-content-xxl-end { + justify-content: flex-end!important + } + + .justify-content-xxl-center { + justify-content: center!important + } + + .justify-content-xxl-between { + justify-content: space-between!important + } + + .justify-content-xxl-around { + justify-content: space-around!important + } + + .justify-content-xxl-evenly { + justify-content: space-evenly!important + } + + .align-items-xxl-start { + align-items: flex-start!important + } + + .align-items-xxl-end { + align-items: flex-end!important + } + + .align-items-xxl-center { + align-items: center!important + } + + .align-items-xxl-baseline { + align-items: baseline!important + } + + .align-items-xxl-stretch { + align-items: stretch!important + } + + .align-content-xxl-start { + align-content: flex-start!important + } + + .align-content-xxl-end { + align-content: flex-end!important + } + + .align-content-xxl-center { + align-content: center!important + } + + .align-content-xxl-between { + align-content: space-between!important + } + + .align-content-xxl-around { + align-content: space-around!important + } + + .align-content-xxl-stretch { + align-content: stretch!important + } + + .align-self-xxl-auto { + align-self: auto!important + } + + .align-self-xxl-start { + align-self: flex-start!important + } + + .align-self-xxl-end { + align-self: flex-end!important + } + + .align-self-xxl-center { + align-self: center!important + } + + .align-self-xxl-baseline { + align-self: baseline!important + } + + .align-self-xxl-stretch { + align-self: stretch!important + } + + .order-xxl-first { + order: -1!important + } + + .order-xxl-0 { + order: 0!important + } + + .order-xxl-1 { + order: 1!important + } + + .order-xxl-2 { + order: 2!important + } + + .order-xxl-3 { + order: 3!important + } + + .order-xxl-4 { + order: 4!important + } + + .order-xxl-5 { + order: 5!important + } + + .order-xxl-last { + order: 6!important + } + + .m-xxl-0 { + margin: 0!important + } + + .m-xxl-1 { + margin: .25rem!important + } + + .m-xxl-2 { + margin: .5rem!important + } + + .m-xxl-3 { + margin: 1rem!important + } + + .m-xxl-4 { + margin: 1.5rem!important + } + + .m-xxl-5 { + margin: 3rem!important + } + + .m-xxl-auto { + margin: auto!important + } + + .mx-xxl-0 { + margin-right: 0!important; + margin-left: 0!important + } + + .mx-xxl-1 { + margin-right: .25rem!important; + margin-left: .25rem!important + } + + .mx-xxl-2 { + margin-right: .5rem!important; + margin-left: .5rem!important + } + + .mx-xxl-3 { + margin-right: 1rem!important; + margin-left: 1rem!important + } + + .mx-xxl-4 { + margin-right: 1.5rem!important; + margin-left: 1.5rem!important + } + + .mx-xxl-5 { + margin-right: 3rem!important; + margin-left: 3rem!important + } + + .mx-xxl-auto { + margin-right: auto!important; + margin-left: auto!important + } + + .my-xxl-0 { + margin-top: 0!important; + margin-bottom: 0!important + } + + .my-xxl-1 { + margin-top: .25rem!important; + margin-bottom: .25rem!important + } + + .my-xxl-2 { + margin-top: .5rem!important; + margin-bottom: .5rem!important + } + + .my-xxl-3 { + margin-top: 1rem!important; + margin-bottom: 1rem!important + } + + .my-xxl-4 { + margin-top: 1.5rem!important; + margin-bottom: 1.5rem!important + } + + .my-xxl-5 { + margin-top: 3rem!important; + margin-bottom: 3rem!important + } + + .my-xxl-auto { + margin-top: auto!important; + margin-bottom: auto!important + } + + .mt-xxl-0 { + margin-top: 0!important + } + + .mt-xxl-1 { + margin-top: .25rem!important + } + + .mt-xxl-2 { + margin-top: .5rem!important + } + + .mt-xxl-3 { + margin-top: 1rem!important + } + + .mt-xxl-4 { + margin-top: 1.5rem!important + } + + .mt-xxl-5 { + margin-top: 3rem!important + } + + .mt-xxl-auto { + margin-top: auto!important + } + + .me-xxl-0 { + margin-right: 0!important + } + + .me-xxl-1 { + margin-right: .25rem!important + } + + .me-xxl-2 { + margin-right: .5rem!important + } + + .me-xxl-3 { + margin-right: 1rem!important + } + + .me-xxl-4 { + margin-right: 1.5rem!important + } + + .me-xxl-5 { + margin-right: 3rem!important + } + + .me-xxl-auto { + margin-right: auto!important + } + + .mb-xxl-0 { + margin-bottom: 0!important + } + + .mb-xxl-1 { + margin-bottom: .25rem!important + } + + .mb-xxl-2 { + margin-bottom: .5rem!important + } + + .mb-xxl-3 { + margin-bottom: 1rem!important + } + + .mb-xxl-4 { + margin-bottom: 1.5rem!important + } + + .mb-xxl-5 { + margin-bottom: 3rem!important + } + + .mb-xxl-auto { + margin-bottom: auto!important + } + + .mb-xxl-6 { + margin-bottom: 3.5rem!important + } + + .mb-xxl-7 { + margin-bottom: 4rem!important + } + + .mb-xxl-8 { + margin-bottom: 5rem!important + } + + .mb-xxl-9 { + margin-bottom: 6rem!important + } + + .mb-xxl-10 { + margin-bottom: 8rem!important + } + + .mb-xxl-11 { + margin-bottom: 10rem!important + } + + .mb-xxl-12 { + margin-bottom: 12rem!important + } + + .mb-xxl-13 { + margin-bottom: 14rem!important + } + + .mb-xxl-14 { + margin-bottom: 16rem!important + } + + .ms-xxl-0 { + margin-left: 0!important + } + + .ms-xxl-1 { + margin-left: .25rem!important + } + + .ms-xxl-2 { + margin-left: .5rem!important + } + + .ms-xxl-3 { + margin-left: 1rem!important + } + + .ms-xxl-4 { + margin-left: 1.5rem!important + } + + .ms-xxl-5 { + margin-left: 3rem!important + } + + .ms-xxl-auto { + margin-left: auto!important + } + + .m-xxl-n1 { + margin: -.25rem!important + } + + .m-xxl-n2 { + margin: -.5rem!important + } + + .m-xxl-n3 { + margin: -1rem!important + } + + .m-xxl-n4 { + margin: -1.5rem!important + } + + .m-xxl-n5 { + margin: -3rem!important + } + + .mx-xxl-n1 { + margin-right: -.25rem!important; + margin-left: -.25rem!important + } + + .mx-xxl-n2 { + margin-right: -.5rem!important; + margin-left: -.5rem!important + } + + .mx-xxl-n3 { + margin-right: -1rem!important; + margin-left: -1rem!important + } + + .mx-xxl-n4 { + margin-right: -1.5rem!important; + margin-left: -1.5rem!important + } + + .mx-xxl-n5 { + margin-right: -3rem!important; + margin-left: -3rem!important + } + + .my-xxl-n1 { + margin-top: -.25rem!important; + margin-bottom: -.25rem!important + } + + .my-xxl-n2 { + margin-top: -.5rem!important; + margin-bottom: -.5rem!important + } + + .my-xxl-n3 { + margin-top: -1rem!important; + margin-bottom: -1rem!important + } + + .my-xxl-n4 { + margin-top: -1.5rem!important; + margin-bottom: -1.5rem!important + } + + .my-xxl-n5 { + margin-top: -3rem!important; + margin-bottom: -3rem!important + } + + .mt-xxl-n1 { + margin-top: -.25rem!important + } + + .mt-xxl-n2 { + margin-top: -.5rem!important + } + + .mt-xxl-n3 { + margin-top: -1rem!important + } + + .mt-xxl-n4 { + margin-top: -1.5rem!important + } + + .mt-xxl-n5 { + margin-top: -3rem!important + } + + .me-xxl-n1 { + margin-right: -.25rem!important + } + + .me-xxl-n2 { + margin-right: -.5rem!important + } + + .me-xxl-n3 { + margin-right: -1rem!important + } + + .me-xxl-n4 { + margin-right: -1.5rem!important + } + + .me-xxl-n5 { + margin-right: -3rem!important + } + + .mb-xxl-n1 { + margin-bottom: -.25rem!important + } + + .mb-xxl-n2 { + margin-bottom: -.5rem!important + } + + .mb-xxl-n3 { + margin-bottom: -1rem!important + } + + .mb-xxl-n4 { + margin-bottom: -1.5rem!important + } + + .mb-xxl-n5 { + margin-bottom: -3rem!important + } + + .ms-xxl-n1 { + margin-left: -.25rem!important + } + + .ms-xxl-n2 { + margin-left: -.5rem!important + } + + .ms-xxl-n3 { + margin-left: -1rem!important + } + + .ms-xxl-n4 { + margin-left: -1.5rem!important + } + + .ms-xxl-n5 { + margin-left: -3rem!important + } + + .p-xxl-0 { + padding: 0!important + } + + .p-xxl-1 { + padding: .25rem!important + } + + .p-xxl-2 { + padding: .5rem!important + } + + .p-xxl-3 { + padding: 1rem!important + } + + .p-xxl-4 { + padding: 1.5rem!important + } + + .p-xxl-5 { + padding: 3rem!important + } + + .px-xxl-0 { + padding-right: 0!important; + padding-left: 0!important + } + + .px-xxl-1 { + padding-right: .25rem!important; + padding-left: .25rem!important + } + + .px-xxl-2 { + padding-right: .5rem!important; + padding-left: .5rem!important + } + + .px-xxl-3 { + padding-right: 1rem!important; + padding-left: 1rem!important + } + + .px-xxl-4 { + padding-right: 1.5rem!important; + padding-left: 1.5rem!important + } + + .px-xxl-5 { + padding-right: 3rem!important; + padding-left: 3rem!important + } + + .py-xxl-0 { + padding-top: 0!important; + padding-bottom: 0!important + } + + .py-xxl-1 { + padding-top: .25rem!important; + padding-bottom: .25rem!important + } + + .py-xxl-2 { + padding-top: .5rem!important; + padding-bottom: .5rem!important + } + + .py-xxl-3 { + padding-top: 1rem!important; + padding-bottom: 1rem!important + } + + .py-xxl-4 { + padding-top: 1.5rem!important; + padding-bottom: 1.5rem!important + } + + .py-xxl-5 { + padding-top: 3rem!important; + padding-bottom: 3rem!important + } + + .pt-xxl-0 { + padding-top: 0!important + } + + .pt-xxl-1 { + padding-top: .25rem!important + } + + .pt-xxl-2 { + padding-top: .5rem!important + } + + .pt-xxl-3 { + padding-top: 1rem!important + } + + .pt-xxl-4 { + padding-top: 1.5rem!important + } + + .pt-xxl-5 { + padding-top: 3rem!important + } + + .pe-xxl-0 { + padding-right: 0!important + } + + .pe-xxl-1 { + padding-right: .25rem!important + } + + .pe-xxl-2 { + padding-right: .5rem!important + } + + .pe-xxl-3 { + padding-right: 1rem!important + } + + .pe-xxl-4 { + padding-right: 1.5rem!important + } + + .pe-xxl-5 { + padding-right: 3rem!important + } + + .pb-xxl-0 { + padding-bottom: 0!important + } + + .pb-xxl-1 { + padding-bottom: .25rem!important + } + + .pb-xxl-2 { + padding-bottom: .5rem!important + } + + .pb-xxl-3 { + padding-bottom: 1rem!important + } + + .pb-xxl-4 { + padding-bottom: 1.5rem!important + } + + .pb-xxl-5 { + padding-bottom: 3rem!important + } + + .ps-xxl-0 { + padding-left: 0!important + } + + .ps-xxl-1 { + padding-left: .25rem!important + } + + .ps-xxl-2 { + padding-left: .5rem!important + } + + .ps-xxl-3 { + padding-left: 1rem!important + } + + .ps-xxl-4 { + padding-left: 1.5rem!important + } + + .ps-xxl-5 { + padding-left: 3rem!important + } + + .gap-xxl-0 { + gap: 0!important + } + + .gap-xxl-1 { + gap: .25rem!important + } + + .gap-xxl-2 { + gap: .5rem!important + } + + .gap-xxl-3 { + gap: 1rem!important + } + + .gap-xxl-4 { + gap: 1.5rem!important + } + + .gap-xxl-5 { + gap: 3rem!important + } + + .text-xxl-start { + text-align: left!important + } + + .text-xxl-end { + text-align: right!important + } + + .text-xxl-center { + text-align: center!important + } +} + +@media(min-width: 1200px) { + .fs-1 { + font-size:2.5rem!important + } + + .fs-2 { + font-size: 2rem!important + } + + .fs-3 { + font-size: 1.75rem!important + } + + .fs-4 { + font-size: 1.5rem!important + } +} + +@media print { + .d-print-inline { + display: inline!important + } + + .d-print-inline-block { + display: inline-block!important + } + + .d-print-block { + display: block!important + } + + .d-print-grid { + display: grid!important + } + + .d-print-table { + display: table!important + } + + .d-print-table-row { + display: table-row!important + } + + .d-print-table-cell { + display: table-cell!important + } + + .d-print-flex { + display: flex!important + } + + .d-print-inline-flex { + display: inline-flex!important + } + + .d-print-none { + display: none!important + } +} + +.diagonal-fractions { + font-variant-numeric: diagonal-fractions +} + +.bg-super-light { + --mdb-bg-super-light: #fbfbfb; + background-color: var(--mdb-bg-super-light) +} + +.bg-local { + background-attachment: local +} + +.bg-scroll { + background-attachment: scroll +} + +.overflow-y-scroll { + overflow-y: scroll +} + +.overflow-x-scroll { + overflow-x: scroll +} + +.table-fixed { + table-layout: fixed +} + +.table-auto { + table-layout: auto +} + +.link-danger,.link-dark,.link-info,.link-light,.link-primary,.link-secondary,.link-success,.link-warning { + transition: color .15s +} + +:root { + --mdb-font-roboto: "Roboto",sans-serif; + --mdb-bg-opacity: 1 +} + +hr:not([size]).hr { + --mdb-divider-height: 2px; + --mdb-divider-bg: #f5f5f5; + --mdb-divider-opacity: 1; + --mdb-divider-blurry-bg: transparent; + --mdb-divider-blurry-bg-image: linear-gradient(90deg,transparent,#666,transparent); + --mdb-divider-blurry-height: 1px; + --mdb-divider-blurry-opacity: 0.25; + height: var(--mdb-divider-height); + background-color: var(--mdb-divider-bg); + opacity: var(--mdb-divider-opacity) +} + +hr:not([size]).hr.hr-blurry { + background-color: var(--mdb-divider-blurry-bg); + background-image: var(--mdb-divider-blurry-bg-image); + height: var(--mdb-divider-blurry-height); + opacity: var(--mdb-divider-blurry-opacity) +} + +hr:not([size]).vr { + height: auto +} + +hr.hr,hr.vr { + border-top: none!important +} + +.vr { + --mdb-divider-width: 2px; + --mdb-divider-bg: #f5f5f5; + --mdb-divider-opacity: 1; + width: var(--mdb-divider-width); + background-color: var(--mdb-divider-bg); + opacity: var(--mdb-divider-opacity) +} + +.vr-blurry { + --mdb-divider-blurry-vr-bg-image: linear-gradient(180deg,transparent,#666,transparent); + --mdb-divider-blurry-vr-width: 1px; + --mdb-divider-blurry-opacity: 0.25; + background-image: var(--mdb-divider-blurry-vr-bg-image); + width: var(--mdb-divider-blurry-vr-width); + opacity: var(--mdb-divider-blurry-opacity) +} + +a { + --mdb-link-decoration: none; + -webkit-text-decoration: var(--mdb-link-decoration); + text-decoration: var(--mdb-link-decoration) +} + +.note { + --mdb-note-padding: 10px; + --mdb-note-border-width: 6px; + --mdb-note-border-radius: 5px; + --mdb-note-strong-font-weight: 600; + padding: var(--mdb-note-padding); + border-left: var(--mdb-note-border-width) solid; + border-radius: var(--mdb-note-border-radius) +} + +.note strong { + font-weight: var(--mdb-note-strong-font-weight) +} + +.note-primary { + background-color: #dfe7f6; + border-color: #376fc8 +} + +.note-secondary { + background-color: #ebedef; + border-color: #565e6c +} + +.note-success { + background-color: #d6f0e0; + border-color: #139647 +} + +.note-danger { + background-color: #f9e1e5; + border-color: #d62e4a +} + +.note-warning { + background-color: #fbf0da; + border-color: #a17112 +} + +.note-info { + background-color: #def1f7; + border-color: #2686a6 +} + +.note-light { + background-color: #f5f5f5; + border-color: #8c8c8c +} + +.note-dark { + background-color: #332e2e; + border-color: #e8e8e8 +} + +@media(min-width: 1199px) { + .w-responsive { + width:75% + } +} + +.bg-primary { + --mdb--bg-opacity: 1; + background-color: rgba(59,113,202,var(--mdb--bg-opacity)) +} + +.bg-secondary { + --mdb--bg-opacity: 1; + background-color: rgba(159,166,178,var(--mdb--bg-opacity)) +} + +.bg-success { + --mdb--bg-opacity: 1; + background-color: rgba(20,164,77,var(--mdb--bg-opacity)) +} + +.bg-danger { + --mdb--bg-opacity: 1; + background-color: rgba(220,76,100,var(--mdb--bg-opacity)) +} + +.bg-warning { + --mdb--bg-opacity: 1; + background-color: rgba(228,161,27,var(--mdb--bg-opacity)) +} + +.bg-info { + background-color: rgba(84,180,211,var(--mdb--bg-opacity)) +} + +.bg-info,.bg-light { + --mdb--bg-opacity: 1 +} + +.bg-light { + background-color: rgba(251,251,251,var(--mdb--bg-opacity)) +} + +.bg-dark { + --mdb--bg-opacity: 1; + background-color: rgba(51,45,45,var(--mdb--bg-opacity)) +} + +/*! + * # Semantic UI 2.4.2 - Flag + * http://github.com/semantic-org/semantic-ui/ + * + * + * Released under the MIT license + * http://opensource.org/licenses/MIT + * + */ +#mdb-table-flag tr { + cursor: pointer +} + +.mdb-flag-selected { + border-top-left-radius: 5px; + border-top-right-radius: 5px; + text-align: center; + max-width: 150px; + margin: 10px auto 0 +} + +.mdb-selected-flag-text { + margin: 0 auto; + max-width: 150px +} + +i.flag:not(.icon) { + margin: 0 .5em 0 0; + line-height: 11px; + text-decoration: inherit; + vertical-align: baseline; + -webkit-backface-visibility: hidden; + backface-visibility: hidden +} + +i.flag:before,i.flag:not(.icon) { + display: inline-block; + width: 16px; + height: 11px +} + +i.flag:before { + content: ""; + background: url(https://mdbootstrap.com/img/svg/flags.png) no-repeat -108px -1976px +} + +i.flag-ad:before,i.flag-andorra:before { + background-position: 0 0!important +} + +i.flag-ae:before,i.flag-uae:before,i.flag-united-arab-emirates:before { + background-position: 0 -26px!important +} + +i.flag-af:before,i.flag-afghanistan:before { + background-position: 0 -52px!important +} + +i.flag-ag:before,i.flag-antigua:before { + background-position: 0 -78px!important +} + +i.flag-ai:before,i.flag-anguilla:before { + background-position: 0 -104px!important +} + +i.flag-al:before,i.flag-albania:before { + background-position: 0 -130px!important +} + +i.flag-am:before,i.flag-armenia:before { + background-position: 0 -156px!important +} + +i.flag-an:before,i.flag-netherlands-antilles:before { + background-position: 0 -182px!important +} + +i.flag-angola:before,i.flag-ao:before { + background-position: 0 -208px!important +} + +i.flag-ar:before,i.flag-argentina:before { + background-position: 0 -234px!important +} + +i.flag-american-samoa:before,i.flag-as:before { + background-position: 0 -260px!important +} + +i.flag-at:before,i.flag-austria:before { + background-position: 0 -286px!important +} + +i.flag-au:before,i.flag-australia:before { + background-position: 0 -312px!important +} + +i.flag-aruba:before,i.flag-aw:before { + background-position: 0 -338px!important +} + +i.flag-aland-islands:before,i.flag-ax:before { + background-position: 0 -364px!important +} + +i.flag-az:before,i.flag-azerbaijan:before { + background-position: 0 -390px!important +} + +i.flag-ba:before,i.flag-bosnia:before { + background-position: 0 -416px!important +} + +i.flag-barbados:before,i.flag-bb:before { + background-position: 0 -442px!important +} + +i.flag-bangladesh:before,i.flag-bd:before { + background-position: 0 -468px!important +} + +i.flag-be:before,i.flag-belgium:before { + background-position: 0 -494px!important +} + +i.flag-bf:before,i.flag-burkina-faso:before { + background-position: 0 -520px!important +} + +i.flag-bg:before,i.flag-bulgaria:before { + background-position: 0 -546px!important +} + +i.flag-bahrain:before,i.flag-bh:before { + background-position: 0 -572px!important +} + +i.flag-bi:before,i.flag-burundi:before { + background-position: 0 -598px!important +} + +i.flag-benin:before,i.flag-bj:before { + background-position: 0 -624px!important +} + +i.flag-bermuda:before,i.flag-bm:before { + background-position: 0 -650px!important +} + +i.flag-bn:before,i.flag-brunei:before { + background-position: 0 -676px!important +} + +i.flag-bo:before,i.flag-bolivia:before { + background-position: 0 -702px!important +} + +i.flag-br:before,i.flag-brazil:before { + background-position: 0 -728px!important +} + +i.flag-bahamas:before,i.flag-bs:before { + background-position: 0 -754px!important +} + +i.flag-bhutan:before,i.flag-bt:before { + background-position: 0 -780px!important +} + +i.flag-bouvet-island:before,i.flag-bv:before { + background-position: 0 -806px!important +} + +i.flag-botswana:before,i.flag-bw:before { + background-position: 0 -832px!important +} + +i.flag-belarus:before,i.flag-by:before { + background-position: 0 -858px!important +} + +i.flag-belize:before,i.flag-bz:before { + background-position: 0 -884px!important +} + +i.flag-ca:before,i.flag-canada:before { + background-position: 0 -910px!important +} + +i.flag-cc:before,i.flag-cocos-islands:before { + background-position: 0 -962px!important +} + +i.flag-cd:before,i.flag-congo:before { + background-position: 0 -988px!important +} + +i.flag-central-african-republic:before,i.flag-cf:before { + background-position: 0 -1014px!important +} + +i.flag-cg:before,i.flag-congo-brazzaville:before { + background-position: 0 -1040px!important +} + +i.flag-ch:before,i.flag-switzerland:before { + background-position: 0 -1066px!important +} + +i.flag-ci:before,i.flag-cote-divoire:before { + background-position: 0 -1092px!important +} + +i.flag-ck:before,i.flag-cook-islands:before { + background-position: 0 -1118px!important +} + +i.flag-chile:before,i.flag-cl:before { + background-position: 0 -1144px!important +} + +i.flag-cameroon:before,i.flag-cm:before { + background-position: 0 -1170px!important +} + +i.flag-china:before,i.flag-cn:before { + background-position: 0 -1196px!important +} + +i.flag-co:before,i.flag-colombia:before { + background-position: 0 -1222px!important +} + +i.flag-costa-rica:before,i.flag-cr:before { + background-position: 0 -1248px!important +} + +i.flag-cs:before,i.flag-serbia:before { + background-position: 0 -1274px!important +} + +i.flag-cu:before,i.flag-cuba:before { + background-position: 0 -1300px!important +} + +i.flag-cape-verde:before,i.flag-cv:before { + background-position: 0 -1326px!important +} + +i.flag-christmas-island:before,i.flag-cx:before { + background-position: 0 -1352px!important +} + +i.flag-cy:before,i.flag-cyprus:before { + background-position: 0 -1378px!important +} + +i.flag-cz:before,i.flag-czech-republic:before { + background-position: 0 -1404px!important +} + +i.flag-de:before,i.flag-germany:before { + background-position: 0 -1430px!important +} + +i.flag-dj:before,i.flag-djibouti:before { + background-position: 0 -1456px!important +} + +i.flag-denmark:before,i.flag-dk:before { + background-position: 0 -1482px!important +} + +i.flag-dm:before,i.flag-dominica:before { + background-position: 0 -1508px!important +} + +i.flag-do:before,i.flag-dominican-republic:before { + background-position: 0 -1534px!important +} + +i.flag-algeria:before,i.flag-dz:before { + background-position: 0 -1560px!important +} + +i.flag-ec:before,i.flag-ecuador:before { + background-position: 0 -1586px!important +} + +i.flag-ee:before,i.flag-estonia:before { + background-position: 0 -1612px!important +} + +i.flag-eg:before,i.flag-egypt:before { + background-position: 0 -1638px!important +} + +i.flag-eh:before,i.flag-western-sahara:before { + background-position: 0 -1664px!important +} + +i.flag-england:before,i.flag-gb-eng:before { + background-position: 0 -1690px!important +} + +i.flag-er:before,i.flag-eritrea:before { + background-position: 0 -1716px!important +} + +i.flag-es:before,i.flag-spain:before { + background-position: 0 -1742px!important +} + +i.flag-et:before,i.flag-ethiopia:before { + background-position: 0 -1768px!important +} + +i.flag-eu:before,i.flag-european-union:before { + background-position: 0 -1794px!important +} + +i.flag-fi:before,i.flag-finland:before { + background-position: 0 -1846px!important +} + +i.flag-fiji:before,i.flag-fj:before { + background-position: 0 -1872px!important +} + +i.flag-falkland-islands:before,i.flag-fk:before { + background-position: 0 -1898px!important +} + +i.flag-fm:before,i.flag-micronesia:before { + background-position: 0 -1924px!important +} + +i.flag-faroe-islands:before,i.flag-fo:before { + background-position: 0 -1950px!important +} + +i.flag-fr:before,i.flag-france:before { + background-position: 0 -1976px!important +} + +i.flag-ga:before,i.flag-gabon:before { + background-position: -36px 0!important +} + +i.flag-gb:before,i.flag-uk:before,i.flag-united-kingdom:before { + background-position: -36px -26px!important +} + +i.flag-gd:before,i.flag-grenada:before { + background-position: -36px -52px!important +} + +i.flag-ge:before,i.flag-georgia:before { + background-position: -36px -78px!important +} + +i.flag-french-guiana:before,i.flag-gf:before { + background-position: -36px -104px!important +} + +i.flag-gh:before,i.flag-ghana:before { + background-position: -36px -130px!important +} + +i.flag-gi:before,i.flag-gibraltar:before { + background-position: -36px -156px!important +} + +i.flag-gl:before,i.flag-greenland:before { + background-position: -36px -182px!important +} + +i.flag-gambia:before,i.flag-gm:before { + background-position: -36px -208px!important +} + +i.flag-gn:before,i.flag-guinea:before { + background-position: -36px -234px!important +} + +i.flag-gp:before,i.flag-guadeloupe:before { + background-position: -36px -260px!important +} + +i.flag-equatorial-guinea:before,i.flag-gq:before { + background-position: -36px -286px!important +} + +i.flag-gr:before,i.flag-greece:before { + background-position: -36px -312px!important +} + +i.flag-gs:before,i.flag-sandwich-islands:before { + background-position: -36px -338px!important +} + +i.flag-gt:before,i.flag-guatemala:before { + background-position: -36px -364px!important +} + +i.flag-gu:before,i.flag-guam:before { + background-position: -36px -390px!important +} + +i.flag-guinea-bissau:before,i.flag-gw:before { + background-position: -36px -416px!important +} + +i.flag-guyana:before,i.flag-gy:before { + background-position: -36px -442px!important +} + +i.flag-hk:before,i.flag-hong-kong:before { + background-position: -36px -468px!important +} + +i.flag-heard-island:before,i.flag-hm:before { + background-position: -36px -494px!important +} + +i.flag-hn:before,i.flag-honduras:before { + background-position: -36px -520px!important +} + +i.flag-croatia:before,i.flag-hr:before { + background-position: -36px -546px!important +} + +i.flag-haiti:before,i.flag-ht:before { + background-position: -36px -572px!important +} + +i.flag-hu:before,i.flag-hungary:before { + background-position: -36px -598px!important +} + +i.flag-id:before,i.flag-indonesia:before { + background-position: -36px -624px!important +} + +i.flag-ie:before,i.flag-ireland:before { + background-position: -36px -650px!important +} + +i.flag-il:before,i.flag-israel:before { + background-position: -36px -676px!important +} + +i.flag-in:before,i.flag-india:before { + background-position: -36px -702px!important +} + +i.flag-indian-ocean-territory:before,i.flag-io:before { + background-position: -36px -728px!important +} + +i.flag-iq:before,i.flag-iraq:before { + background-position: -36px -754px!important +} + +i.flag-ir:before,i.flag-iran:before { + background-position: -36px -780px!important +} + +i.flag-iceland:before,i.flag-is:before { + background-position: -36px -806px!important +} + +i.flag-it:before,i.flag-italy:before { + background-position: -36px -832px!important +} + +i.flag-jamaica:before,i.flag-jm:before { + background-position: -36px -858px!important +} + +i.flag-jo:before,i.flag-jordan:before { + background-position: -36px -884px!important +} + +i.flag-japan:before,i.flag-jp:before { + background-position: -36px -910px!important +} + +i.flag-ke:before,i.flag-kenya:before { + background-position: -36px -936px!important +} + +i.flag-kg:before,i.flag-kyrgyzstan:before { + background-position: -36px -962px!important +} + +i.flag-cambodia:before,i.flag-kh:before { + background-position: -36px -988px!important +} + +i.flag-ki:before,i.flag-kiribati:before { + background-position: -36px -1014px!important +} + +i.flag-comoros:before,i.flag-km:before { + background-position: -36px -1040px!important +} + +i.flag-kn:before,i.flag-saint-kitts-and-nevis:before { + background-position: -36px -1066px!important +} + +i.flag-kp:before,i.flag-north-korea:before { + background-position: -36px -1092px!important +} + +i.flag-kr:before,i.flag-south-korea:before { + background-position: -36px -1118px!important +} + +i.flag-kuwait:before,i.flag-kw:before { + background-position: -36px -1144px!important +} + +i.flag-cayman-islands:before,i.flag-ky:before { + background-position: -36px -1170px!important +} + +i.flag-kazakhstan:before,i.flag-kz:before { + background-position: -36px -1196px!important +} + +i.flag-la:before,i.flag-laos:before { + background-position: -36px -1222px!important +} + +i.flag-lb:before,i.flag-lebanon:before { + background-position: -36px -1248px!important +} + +i.flag-lc:before,i.flag-saint-lucia:before { + background-position: -36px -1274px!important +} + +i.flag-li:before,i.flag-liechtenstein:before { + background-position: -36px -1300px!important +} + +i.flag-lk:before,i.flag-sri-lanka:before { + background-position: -36px -1326px!important +} + +i.flag-liberia:before,i.flag-lr:before { + background-position: -36px -1352px!important +} + +i.flag-lesotho:before,i.flag-ls:before { + background-position: -36px -1378px!important +} + +i.flag-lithuania:before,i.flag-lt:before { + background-position: -36px -1404px!important +} + +i.flag-lu:before,i.flag-luxembourg:before { + background-position: -36px -1430px!important +} + +i.flag-latvia:before,i.flag-lv:before { + background-position: -36px -1456px!important +} + +i.flag-libya:before,i.flag-ly:before { + background-position: -36px -1482px!important +} + +i.flag-ma:before,i.flag-morocco:before { + background-position: -36px -1508px!important +} + +i.flag-mc:before,i.flag-monaco:before { + background-position: -36px -1534px!important +} + +i.flag-md:before,i.flag-moldova:before { + background-position: -36px -1560px!important +} + +i.flag-me:before,i.flag-montenegro:before { + background-position: -36px -1586px!important +} + +i.flag-madagascar:before,i.flag-mg:before { + background-position: -36px -1613px!important +} + +i.flag-marshall-islands:before,i.flag-mh:before { + background-position: -36px -1639px!important +} + +i.flag-macedonia:before,i.flag-mk:before { + background-position: -36px -1665px!important +} + +i.flag-mali:before,i.flag-ml:before { + background-position: -36px -1691px!important +} + +i.flag-burma:before,i.flag-mm:before,i.flag-myanmar:before { + background-position: -73px -1821px!important +} + +i.flag-mn:before,i.flag-mongolia:before { + background-position: -36px -1743px!important +} + +i.flag-macau:before,i.flag-mo:before { + background-position: -36px -1769px!important +} + +i.flag-mp:before,i.flag-northern-mariana-islands:before { + background-position: -36px -1795px!important +} + +i.flag-martinique:before,i.flag-mq:before { + background-position: -36px -1821px!important +} + +i.flag-mauritania:before,i.flag-mr:before { + background-position: -36px -1847px!important +} + +i.flag-montserrat:before,i.flag-ms:before { + background-position: -36px -1873px!important +} + +i.flag-malta:before,i.flag-mt:before { + background-position: -36px -1899px!important +} + +i.flag-mauritius:before,i.flag-mu:before { + background-position: -36px -1925px!important +} + +i.flag-maldives:before,i.flag-mv:before { + background-position: -36px -1951px!important +} + +i.flag-malawi:before,i.flag-mw:before { + background-position: -36px -1977px!important +} + +i.flag-mexico:before,i.flag-mx:before { + background-position: -72px 0!important +} + +i.flag-malaysia:before,i.flag-my:before { + background-position: -72px -26px!important +} + +i.flag-mozambique:before,i.flag-mz:before { + background-position: -72px -52px!important +} + +i.flag-na:before,i.flag-namibia:before { + background-position: -72px -78px!important +} + +i.flag-nc:before,i.flag-new-caledonia:before { + background-position: -72px -104px!important +} + +i.flag-ne:before,i.flag-niger:before { + background-position: -72px -130px!important +} + +i.flag-nf:before,i.flag-norfolk-island:before { + background-position: -72px -156px!important +} + +i.flag-ng:before,i.flag-nigeria:before { + background-position: -72px -182px!important +} + +i.flag-ni:before,i.flag-nicaragua:before { + background-position: -72px -208px!important +} + +i.flag-netherlands:before,i.flag-nl:before { + background-position: -72px -234px!important +} + +i.flag-no:before,i.flag-norway:before { + background-position: -72px -260px!important +} + +i.flag-nepal:before,i.flag-np:before { + background-position: -72px -286px!important +} + +i.flag-nauru:before,i.flag-nr:before { + background-position: -72px -312px!important +} + +i.flag-niue:before,i.flag-nu:before { + background-position: -72px -338px!important +} + +i.flag-new-zealand:before,i.flag-nz:before { + background-position: -72px -364px!important +} + +i.flag-om:before,i.flag-oman:before { + background-position: -72px -390px!important +} + +i.flag-pa:before,i.flag-panama:before { + background-position: -72px -416px!important +} + +i.flag-pe:before,i.flag-peru:before { + background-position: -72px -442px!important +} + +i.flag-french-polynesia:before,i.flag-pf:before { + background-position: -72px -468px!important +} + +i.flag-new-guinea:before,i.flag-pg:before { + background-position: -72px -494px!important +} + +i.flag-ph:before,i.flag-philippines:before { + background-position: -72px -520px!important +} + +i.flag-pakistan:before,i.flag-pk:before { + background-position: -72px -546px!important +} + +i.flag-pl:before,i.flag-poland:before { + background-position: -72px -572px!important +} + +i.flag-pm:before,i.flag-saint-pierre:before { + background-position: -72px -598px!important +} + +i.flag-pitcairn-islands:before,i.flag-pn:before { + background-position: -72px -624px!important +} + +i.flag-pr:before,i.flag-puerto-rico:before { + background-position: -72px -650px!important +} + +i.flag-palestine:before,i.flag-ps:before { + background-position: -72px -676px!important +} + +i.flag-portugal:before,i.flag-pt:before { + background-position: -72px -702px!important +} + +i.flag-palau:before,i.flag-pw:before { + background-position: -72px -728px!important +} + +i.flag-paraguay:before,i.flag-py:before { + background-position: -72px -754px!important +} + +i.flag-qa:before,i.flag-qatar:before { + background-position: -72px -780px!important +} + +i.flag-re:before,i.flag-reunion:before { + background-position: -72px -806px!important +} + +i.flag-ro:before,i.flag-romania:before { + background-position: -72px -832px!important +} + +i.flag-rs:before,i.flag-serbia:before { + background-position: -72px -858px!important +} + +i.flag-ru:before,i.flag-russia:before { + background-position: -72px -884px!important +} + +i.flag-rw:before,i.flag-rwanda:before { + background-position: -72px -910px!important +} + +i.flag-sa:before,i.flag-saudi-arabia:before { + background-position: -72px -936px!important +} + +i.flag-sb:before,i.flag-solomon-islands:before { + background-position: -72px -962px!important +} + +i.flag-sc:before,i.flag-seychelles:before { + background-position: -72px -988px!important +} + +i.flag-gb-sct:before,i.flag-scotland:before { + background-position: -72px -1014px!important +} + +i.flag-sd:before,i.flag-sudan:before { + background-position: -72px -1040px!important +} + +i.flag-se:before,i.flag-sweden:before { + background-position: -72px -1066px!important +} + +i.flag-sg:before,i.flag-singapore:before { + background-position: -72px -1092px!important +} + +i.flag-saint-helena:before,i.flag-sh:before { + background-position: -72px -1118px!important +} + +i.flag-si:before,i.flag-slovenia:before { + background-position: -72px -1144px!important +} + +i.flag-jan-mayen:before,i.flag-sj:before,i.flag-svalbard:before { + background-position: -72px -1170px!important +} + +i.flag-sk:before,i.flag-slovakia:before { + background-position: -72px -1196px!important +} + +i.flag-sierra-leone:before,i.flag-sl:before { + background-position: -72px -1222px!important +} + +i.flag-san-marino:before,i.flag-sm:before { + background-position: -72px -1248px!important +} + +i.flag-senegal:before,i.flag-sn:before { + background-position: -72px -1274px!important +} + +i.flag-so:before,i.flag-somalia:before { + background-position: -72px -1300px!important +} + +i.flag-sr:before,i.flag-suriname:before { + background-position: -72px -1326px!important +} + +i.flag-sao-tome:before,i.flag-st:before { + background-position: -72px -1352px!important +} + +i.flag-el-salvador:before,i.flag-sv:before { + background-position: -72px -1378px!important +} + +i.flag-sy:before,i.flag-syria:before { + background-position: -72px -1404px!important +} + +i.flag-swaziland:before,i.flag-sz:before { + background-position: -72px -1430px!important +} + +i.flag-caicos-islands:before,i.flag-tc:before { + background-position: -72px -1456px!important +} + +i.flag-chad:before,i.flag-td:before { + background-position: -72px -1482px!important +} + +i.flag-french-territories:before,i.flag-tf:before { + background-position: -72px -1508px!important +} + +i.flag-tg:before,i.flag-togo:before { + background-position: -72px -1534px!important +} + +i.flag-th:before,i.flag-thailand:before { + background-position: -72px -1560px!important +} + +i.flag-tajikistan:before,i.flag-tj:before { + background-position: -72px -1586px!important +} + +i.flag-tk:before,i.flag-tokelau:before { + background-position: -72px -1612px!important +} + +i.flag-timorleste:before,i.flag-tl:before { + background-position: -72px -1638px!important +} + +i.flag-tm:before,i.flag-turkmenistan:before { + background-position: -72px -1664px!important +} + +i.flag-tn:before,i.flag-tunisia:before { + background-position: -72px -1690px!important +} + +i.flag-to:before,i.flag-tonga:before { + background-position: -72px -1716px!important +} + +i.flag-tr:before,i.flag-turkey:before { + background-position: -72px -1742px!important +} + +i.flag-trinidad:before,i.flag-tt:before { + background-position: -72px -1768px!important +} + +i.flag-tuvalu:before,i.flag-tv:before { + background-position: -72px -1794px!important +} + +i.flag-taiwan:before,i.flag-tw:before { + background-position: -72px -1820px!important +} + +i.flag-tanzania:before,i.flag-tz:before { + background-position: -72px -1846px!important +} + +i.flag-ua:before,i.flag-ukraine:before { + background-position: -72px -1872px!important +} + +i.flag-ug:before,i.flag-uganda:before { + background-position: -72px -1898px!important +} + +i.flag-um:before,i.flag-us-minor-islands:before { + background-position: -72px -1924px!important +} + +i.flag-america:before,i.flag-united-states:before,i.flag-us:before { + background-position: -72px -1950px!important +} + +i.flag-uruguay:before,i.flag-uy:before { + background-position: -72px -1976px!important +} + +i.flag-uz:before,i.flag-uzbekistan:before { + background-position: -108px 0!important +} + +i.flag-va:before,i.flag-vatican-city:before { + background-position: -108px -26px!important +} + +i.flag-saint-vincent:before,i.flag-vc:before { + background-position: -108px -52px!important +} + +i.flag-ve:before,i.flag-venezuela:before { + background-position: -108px -78px!important +} + +i.flag-british-virgin-islands:before,i.flag-vg:before { + background-position: -108px -104px!important +} + +i.flag-us-virgin-islands:before,i.flag-vi:before { + background-position: -108px -130px!important +} + +i.flag-vietnam:before,i.flag-vn:before { + background-position: -108px -156px!important +} + +i.flag-vanuatu:before,i.flag-vu:before { + background-position: -108px -182px!important +} + +i.flag-gb-wls:before,i.flag-wales:before { + background-position: -108px -208px!important +} + +i.flag-wallis-and-futuna:before,i.flag-wf:before { + background-position: -108px -234px!important +} + +i.flag-samoa:before,i.flag-ws:before { + background-position: -108px -260px!important +} + +i.flag-ye:before,i.flag-yemen:before { + background-position: -108px -286px!important +} + +i.flag-mayotte:before,i.flag-yt:before { + background-position: -108px -312px!important +} + +i.flag-south-africa:before,i.flag-za:before { + background-position: -108px -338px!important +} + +i.flag-zambia:before,i.flag-zm:before { + background-position: -108px -364px!important +} + +i.flag-zimbabwe:before,i.flag-zw:before { + background-position: -108px -390px!important +} + +.bg-fixed { + background-attachment: fixed +} + +.bg-image { + position: relative; + overflow: hidden; + background-repeat: no-repeat; + background-size: cover; + background-position: 50% +} + +.mask { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + width: 100%; + height: 100%; + overflow: hidden; + background-attachment: fixed +} + +.hover-overlay .mask { + --mdb-image-hover-transition: all 0.3s ease-in-out; + opacity: 0; + transition: var(--mdb-image-hover-transition) +} + +.hover-overlay .mask:hover { + opacity: 1 +} + +.hover-zoom { + --mdb-image-hover-zoom-transition: all 0.3s linear; + --mdb-image-hover-zoom-transform: scale(1.1) +} + +.hover-zoom img,.hover-zoom video { + transition: var(--mdb-image-hover-zoom-transition) +} + +.hover-zoom:hover img,.hover-zoom:hover video { + transform: var(--mdb-image-hover-zoom-transform) +} + +.card.hover-shadow,.card.hover-shadow-soft,.hover-shadow,.hover-shadow-soft { + --mdb-image-hover-shadow-transition: all 0.3s ease-in-out; + transition: var(--mdb-image-hover-shadow-transition) +} + +.card.hover-shadow-soft:hover,.card.hover-shadow:hover,.hover-shadow-soft:hover,.hover-shadow:hover { + transition: var(--mdb-image-hover-shadow-transition) +} + +.card.hover-shadow,.hover-shadow { + --mdb-image-hover-shadow-box-shadow: 0 2px 15px -3px rgba(0,0,0,0.16),0 10px 20px -2px rgba(0,0,0,0.1); + box-shadow: none +} + +.card.hover-shadow:hover,.hover-shadow:hover { + box-shadow: var(--mdb-image-hover-shadow-box-shadow) +} + +.card.hover-shadow-soft,.hover-shadow-soft { + --mdb-image-hover-shadow-box-shadow-soft: 0 2px 25px -5px rgba(0,0,0,0.07),0 25px 21px -5px rgba(0,0,0,0.04); + box-shadow: none +} + +.card.hover-shadow-soft:hover,.hover-shadow-soft:hover { + box-shadow: var(--mdb-image-hover-shadow-box-shadow-soft) +} + +.form-control { + min-height: auto; + padding: 4.5px 12px 3.68px +} + +.form-control,.form-control:focus { + transition: all .1s linear; + box-shadow: none +} + +.form-control:focus { + border-color: #3b71ca; + box-shadow: inset 0 0 0 1px #3b71ca +} + +.form-control.form-control-sm { + font-size: .775rem; + line-height: 1.5 +} + +.form-control.form-control-lg { + line-height: 2.15; + border-radius: .25rem +} + +.form-outline { + position: relative; + width: 100% +} + +.form-outline .form-helper { + width: 100%; + position: absolute; + font-size: .875em; + color: #757575 +} + +.form-outline .form-helper .form-counter { + text-align: right +} + +.form-outline .trailing { + position: absolute; + right: 10px; + left: auto; + top: 50%; + transform: translateY(-50%); + pointer-events: none +} + +.form-outline .form-icon-trailing { + padding-right: 2rem!important +} + +.form-outline .form-control { + min-height: auto; + padding: .32rem .75rem; + border: 0; + background: transparent; + transition: all .2s linear +} + +.form-outline .form-control~.form-label { + position: absolute; + top: 0; + max-width: 90%; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + left: .75rem; + padding-top: .37rem; + pointer-events: none; + transform-origin: 0 0; + transition: all .2s ease-out; + color: rgba(0,0,0,.6); + margin-bottom: 0 +} + +.form-outline .form-control~.form-notch { + display: flex; + position: absolute; + left: 0; + top: 0; + width: 100%; + max-width: 100%; + height: 100%; + text-align: left; + pointer-events: none +} + +.form-outline .form-control~.form-notch div { + pointer-events: none; + border: 1px solid #bdbdbd; + box-sizing: border-box; + background: transparent; + transition: all .2s linear +} + +.form-outline .form-control~.form-notch .form-notch-leading { + left: 0; + top: 0; + height: 100%; + width: .5rem; + border-right: none; + border-radius: .25rem 0 0 .25rem +} + +.form-outline .form-control~.form-notch .form-notch-middle { + flex: 0 0 auto; + width: auto; + max-width: calc(100% - 1rem); + height: 100%; + border-right: none; + border-left: none +} + +.form-outline .form-control~.form-notch .form-notch-trailing { + flex-grow: 1; + height: 100%; + border-left: none; + border-radius: 0 .25rem .25rem 0 +} + +.form-outline .form-control:not(.placeholder-active)::-moz-placeholder { + opacity: 0 +} + +.form-outline .form-control:not(.placeholder-active)::placeholder { + opacity: 0 +} + +.form-outline .form-control.active::-moz-placeholder,.form-outline .form-control:focus::-moz-placeholder { + opacity: 1 +} + +.form-outline .form-control.active::placeholder,.form-outline .form-control:focus::placeholder { + opacity: 1 +} + +.form-outline .form-control:focus { + box-shadow: none!important +} + +.form-outline .form-control.active~.form-label,.form-outline .form-control:focus~.form-label { + transform: translateY(-1rem) translateY(.1rem) scale(.8) +} + +.form-outline .form-control:focus~.form-label { + color: #3b71ca +} + +.form-outline .form-control.active~.form-notch .form-notch-middle,.form-outline .form-control:focus~.form-notch .form-notch-middle { + border-right: none; + border-left: none; + border-top: 1px solid transparent +} + +.form-outline .form-control:focus~.form-notch .form-notch-middle { + border-color: #3b71ca; + box-shadow: 0 1px 0 0 #3b71ca; + border-top: 1px solid transparent +} + +.form-outline .form-control.active~.form-notch .form-notch-leading,.form-outline .form-control:focus~.form-notch .form-notch-leading { + border-right: none +} + +.form-outline .form-control:focus~.form-notch .form-notch-leading { + border-color: #3b71ca; + box-shadow: -1px 0 0 0 #3b71ca,0 1px 0 0 #3b71ca,0 -1px 0 0 #3b71ca +} + +.form-outline .form-control.active~.form-notch .form-notch-trailing,.form-outline .form-control:focus~.form-notch .form-notch-trailing { + border-left: none +} + +.form-outline .form-control:focus~.form-notch .form-notch-trailing { + border-color: #3b71ca; + box-shadow: 1px 0 0 0 #3b71ca,0 -1px 0 0 #3b71ca,0 1px 0 0 #3b71ca +} + +.form-outline .form-control.disabled,.form-outline .form-control:disabled,.form-outline .form-control[readonly] { + background-color: #e9ecef +} + +.form-outline .form-control.form-control-lg { + font-size: 1rem; + line-height: 2.15 +} + +.form-outline .form-control.form-control-lg~.form-label { + padding-top: .7rem +} + +.form-outline .form-control.form-control-lg.active~.form-label,.form-outline .form-control.form-control-lg:focus~.form-label { + transform: translateY(-1.25rem) translateY(.1rem) scale(.8) +} + +.form-outline .form-control.form-control-sm { + padding-top: .32rem; + padding-bottom: .32rem; + font-size: .775rem; + line-height: 1.5 +} + +.form-outline .form-control.form-control-sm~.form-label { + padding-top: .33rem; + font-size: .775rem +} + +.form-outline .form-control.form-control-sm.active~.form-label,.form-outline .form-control.form-control-sm:focus~.form-label { + transform: translateY(-.85rem) translateY(.1rem) scale(.8) +} + +.form-outline.form-white .form-control { + color: #fff +} + +.form-outline.form-white .form-control~.form-label { + color: #fbfbfb +} + +.form-outline.form-white .form-control~.form-notch div { + border-color: #fbfbfb +} + +.form-outline.form-white .form-control:focus~.form-label { + color: #fff +} + +.form-outline.form-white .form-control:focus~.form-notch .form-notch-middle { + border-color: #fff; + box-shadow: 0 1px 0 0 #fff; + border-top: 1px solid transparent +} + +.form-outline.form-white .form-control:focus~.form-notch .form-notch-leading { + border-color: #fff; + box-shadow: -1px 0 0 0 #fff,0 1px 0 0 #fff,0 -1px 0 0 #fff +} + +.form-outline.form-white .form-control:focus~.form-notch .form-notch-trailing { + border-color: #fff; + box-shadow: 1px 0 0 0 #fff,0 -1px 0 0 #fff,0 1px 0 0 #fff +} + +.form-outline.form-white .form-control::-moz-placeholder { + color: hsla(0,0%,100%,.7) +} + +.form-outline.form-white .form-control::placeholder { + color: hsla(0,0%,100%,.7) +} + +.form-outline.form-white .form-control.disabled,.form-outline.form-white .form-control:disabled,.form-outline.form-white .form-control[readonly] { + background-color: hsla(0,0%,100%,.45) +} + +.select-input.form-control[readonly]:not([disabled]) { + background-color: transparent +} + +.form-select { + transition: all .2s linear +} + +.form-select:focus { + border-color: #3b71ca; + outline: 0; + box-shadow: inset 0 0 0 1px #3b71ca +} + +.form-check { + min-height: 1.5rem +} + +.form-check-input { + position: relative; + width: 1.125rem; + height: 1.125rem; + background-color: #fff; + border: .125rem solid rgba(0,0,0,.25) +} + +.form-check-input:before { + content: ""; + position: absolute; + box-shadow: 0 0 0 13px transparent; + border-radius: 50%; + width: .875rem; + height: .875rem; + background-color: transparent; + opacity: 0; + pointer-events: none; + transform: scale(0) +} + +.form-check-input:hover { + cursor: pointer +} + +.form-check-input:hover:before { + opacity: .04; + box-shadow: 0 0 0 13px rgba(0,0,0,.6) +} + +.form-check-input:focus { + box-shadow: none; + border-color: rgba(0,0,0,.25); + transition: border-color .2s +} + +.form-check-input:focus:before { + opacity: .12; + box-shadow: 0 0 0 13px rgba(0,0,0,.6); + transform: scale(1); + transition: box-shadow .2s,transform .2s +} + +.form-check-input:checked { + border-color: #3b71ca +} + +.form-check-input:checked:before { + opacity: .16 +} + +.form-check-input:checked:after { + content: ""; + position: absolute +} + +.form-check-input:checked:focus { + border-color: #3b71ca +} + +.form-check-input:checked:focus:before { + box-shadow: 0 0 0 13px #3b71ca; + transform: scale(1); + transition: box-shadow .2s,transform .2s +} + +.form-check-input:indeterminate:focus:before { + box-shadow: 0 0 0 13px #3b71ca +} + +.form-check-input[type=checkbox] { + border-radius: .25rem; + margin-top: .19em; + margin-right: 6px +} + +.form-check-input[type=checkbox]:focus:after { + content: ""; + position: absolute; + width: .875rem; + height: .875rem; + z-index: 1; + display: block; + border-radius: 0; + background-color: #fff +} + +.form-check-input[type=checkbox]:checked { + background-image: none; + background-color: #3b71ca +} + +.form-check-input[type=checkbox]:checked:after { + display: block; + transform: rotate(45deg) /*!rtl:ignore*/; + width: .375rem; + height: .8125rem; + border: .125rem solid #fff; + border-top: 0; + border-left: 0 /*!rtl:ignore*/; + margin-left: .25rem; + margin-top: -1px; + background-color: transparent +} + +.form-check-input[type=checkbox]:checked:focus { + background-color: #3b71ca +} + +.form-check-input[type=checkbox]:indeterminate { + border-color: #3b71ca +} + +.form-check-input[type=radio] { + border-radius: 50%; + width: 1.25rem; + height: 1.25rem; + margin-top: .125em; + margin-right: 4px +} + +.form-check-input[type=radio]:before { + width: 1rem; + height: 1rem +} + +.form-check-input[type=radio]:after { + content: ""; + position: absolute; + width: 1rem; + height: 1rem; + z-index: 1; + display: block; + border-radius: 50%; + background-color: #fff +} + +.form-check-input[type=radio]:checked { + background-image: none; + background-color: #fff +} + +.form-check-input[type=radio]:checked:after { + border-radius: 50%; + width: .625rem; + height: .625rem; + border-color: #3b71ca; + background-color: #3b71ca; + transition: border-color; + transform: translate(-50%,-50%); + position: absolute; + left: 50%; + top: 50% +} + +.form-check-input[type=radio]:checked:focus { + background-color: #fff +} + +.form-check-label { + padding-left: .15rem +} + +.form-check-label:hover { + cursor: pointer +} + +.form-switch .form-check-input { + background-image: none; + border-width: 0; + border-radius: .4375rem; + width: 2rem; + height: .875rem; + background-color: rgba(0,0,0,.25); + margin-top: .3em; + margin-right: 8px +} + +.form-switch .form-check-input:after { + content: ""; + position: absolute; + border: none; + z-index: 2; + border-radius: 50%; + width: 1.25rem; + height: 1.25rem; + background-color: #fff; + margin-top: -.1875rem; + box-shadow: 0 0 3px 0 rgba(0,0,0,.07),0 2px 2px 0 rgba(0,0,0,.04); + transition: background-color .2s,transform .2s +} + +.form-switch .form-check-input:focus { + background-image: none +} + +.form-switch .form-check-input:focus:before { + box-shadow: 3px -1px 0 13px rgba(0,0,0,.6); + transform: scale(1); + transition: box-shadow .2s,transform .2s +} + +.form-switch .form-check-input:focus:after { + border-radius: 50%; + width: 1.25rem; + height: 1.25rem +} + +.form-switch .form-check-input:checked,.form-switch .form-check-input:checked:focus { + background-image: none +} + +.form-switch .form-check-input:checked:focus:before { + margin-left: 1.0625rem; + box-shadow: 3px -1px 0 13px #3b71ca; + transform: scale(1); + transition: box-shadow .2s,transform .2s +} + +.form-switch .form-check-input:checked[type=checkbox] { + background-image: none +} + +.form-switch .form-check-input:checked[type=checkbox]:after { + content: ""; + position: absolute; + border: none; + z-index: 2; + border-radius: 50%; + width: 1.25rem; + height: 1.25rem; + background-color: #3b71ca; + margin-top: -3px; + margin-left: 1.0625rem; + box-shadow: 0 3px 1px -2px rgba(0,0,0,.2),0 2px 2px 0 rgba(0,0,0,.14),0 1px 5px 0 rgba(0,0,0,.12); + transition: background-color .2s,transform .2s +} + +.form-control:hover:not(:disabled):not([readonly])::-webkit-file-upload-button,.form-control[type=file]::-webkit-file-upload-button { + background-color: transparent +} + +.input-group { + flex-wrap: nowrap +} + +.input-group>.form-control { + min-height: calc(2.08rem + 2px); + height: calc(2.08rem + 2px); + padding-top: .27rem; + padding-bottom: .27rem; + transition: all .2s linear +} + +.input-group>.form-control:focus { + transition: all .2s linear; + border-color: #3b71ca; + outline: 0; + box-shadow: inset 0 0 0 1px #3b71ca +} + +.input-group-text { + background-color: transparent; + padding-top: .26rem; + padding-bottom: .26rem +} + +.input-group-text>.form-check-input[type=checkbox] { + margin-left: 1px; + margin-right: 1px +} + +.input-group-text>.form-check-input[type=radio] { + margin-right: 0 +} + +.input-group-lg>.form-control { + height: calc(2.645rem + 2px); + font-size: 1rem; + padding-top: .33rem; + padding-bottom: .33rem +} + +.input-group-lg .input-group-text { + font-size: 1rem +} + +.input-group-sm>.form-control { + min-height: calc(1.66rem + 2px); + height: calc(1.66rem + 2px); + font-size: .775rem; + padding-top: .33rem; + padding-bottom: .33rem +} + +.input-group-sm .input-group-text { + font-size: .775rem; + line-height: 1.5 +} + +.input-group.form-outline .input-group-text { + border-left: 0 +} + +.input-group.form-outline input+.input-group-text { + border: 0; + border-left: 1px solid #bdbdbd +} + +.input-group .form-outline:not(:first-child),.input-group .form-outline:not(:first-child) .form-notch-leading,.input-group .select-wrapper:not(:first-child),.input-group .select-wrapper:not(:first-child) .form-notch-leading { + border-top-left-radius: 0!important; + border-bottom-left-radius: 0!important +} + +.input-group .form-outline:not(:last-child),.input-group .form-outline:not(:last-child) .form-notch-trailing,.input-group .select-wrapper:not(:last-child),.input-group .select-wrapper:not(:last-child) .form-notch-trailing { + border-top-right-radius: 0!important; + border-bottom-right-radius: 0!important +} + +.input-group>[class*=btn-outline-]+[class*=btn-outline-] { + border-left: 0 +} + +.input-group>.btn[class*=btn-outline-] { + padding-top: .47rem +} + +.input-group>.btn { + padding-top: .59rem +} + +.input-group.input-group-lg .input-group-text { + height: calc(2.645rem + 2px) +} + +.input-group .input-group-text { + height: calc(2.08rem + 2px) +} + +.input-group .btn { + line-height: 1 +} + +.input-group.input-group-sm .input-group-text { + height: calc(1.66rem + 2px) +} + +.input-group .invalid-feedback,.input-group .valid-feedback,.was-validated .input-group .invalid-feedback,.was-validated .input-group .valid-feedback { + margin-top: 2.5rem +} + +.valid-feedback { + width: auto; + color: #14a44d; + margin-top: -.75rem +} + +.valid-feedback,.valid-tooltip { + position: absolute; + display: none; + font-size: .875rem +} + +.valid-tooltip { + top: 100%; + z-index: 5; + max-width: 100%; + padding: 6px 16px; + margin-top: .1rem; + background-color: rgba(20,164,77,.9); + border-radius: .25rem!important; + color: #fff +} + +.is-valid~.valid-feedback,.is-valid~.valid-tooltip,.was-validated :valid~.valid-feedback,.was-validated :valid~.valid-tooltip { + display: block +} + +.form-control.is-valid,.was-validated .form-control:valid { + margin-bottom: 1rem; + background-image: none; + border-color: #14a44d +} + +.form-control.is-valid:focus,.was-validated .form-control:valid:focus { + border-color: #14a44d; + box-shadow: 0 0 0 .25rem rgba(20,164,77,.25) +} + +.form-outline .form-control.is-valid~.form-label,.was-validated .form-outline .form-control:valid~.form-label { + color: #14a44d +} + +.form-outline .form-control.is-valid~.form-notch .form-notch-leading,.form-outline .form-control.is-valid~.form-notch .form-notch-middle,.form-outline .form-control.is-valid~.form-notch .form-notch-trailing,.was-validated .form-outline .form-control:valid~.form-notch .form-notch-leading,.was-validated .form-outline .form-control:valid~.form-notch .form-notch-middle,.was-validated .form-outline .form-control:valid~.form-notch .form-notch-trailing { + border-color: #14a44d +} + +.form-outline .form-control.is-valid.active~.form-notch .form-notch-middle,.form-outline .form-control.is-valid:focus~.form-notch .form-notch-middle,.was-validated .form-outline .form-control:valid.active~.form-notch .form-notch-middle,.was-validated .form-outline .form-control:valid:focus~.form-notch .form-notch-middle { + border-top: 1px solid transparent +} + +.form-outline .form-control.is-valid:focus~.form-notch .form-notch-middle,.was-validated .form-outline .form-control:valid:focus~.form-notch .form-notch-middle { + box-shadow: 0 1px 0 0 #14a44d +} + +.form-outline .form-control.is-valid:focus~.form-notch .form-notch-leading,.was-validated .form-outline .form-control:valid:focus~.form-notch .form-notch-leading { + box-shadow: -1px 0 0 0 #14a44d,0 1px 0 0 #14a44d,0 -1px 0 0 #14a44d +} + +.form-outline .form-control.is-valid:focus~.form-notch .form-notch-trailing,.was-validated .form-outline .form-control:valid:focus~.form-notch .form-notch-trailing { + box-shadow: 1px 0 0 0 #14a44d,0 -1px 0 0 #14a44d,0 1px 0 0 #14a44d +} + +.form-outline .form-control.is-valid.select-input.focused~.form-notch .form-notch-leading,.was-validated .form-outline .form-control:valid.select-input.focused~.form-notch .form-notch-leading { + box-shadow: -1px 0 0 0 #14a44d,0 1px 0 0 #14a44d,0 -1px 0 0 #14a44d +} + +.form-outline .form-control.is-valid.select-input.focused~.form-notch .form-notch-middle,.was-validated .form-outline .form-control:valid.select-input.focused~.form-notch .form-notch-middle { + box-shadow: 0 1px 0 0 #14a44d; + border-top: 1px solid transparent +} + +.form-outline .form-control.is-valid.select-input.focused~.form-notch .form-notch-trailing,.was-validated .form-outline .form-control:valid.select-input.focused~.form-notch .form-notch-trailing { + box-shadow: 1px 0 0 0 #14a44d,0 -1px 0 0 #14a44d,0 1px 0 0 #14a44d +} + +.form-select.is-valid,.was-validated .form-select:valid { + border-color: #14a44d +} + +.form-select.is-valid:focus,.was-validated .form-select:valid:focus { + border-color: #14a44d; + box-shadow: 0 0 0 .25rem rgba(20,164,77,.25) +} + +.form-select.is-valid~.valid-feedback,.was-validated .form-select:valid~.valid-feedback { + margin-top: 0 +} + +.input-group .form-control.is-valid,.was-validated .input-group .form-control:valid { + margin-bottom: 0 +} + +.was-validated input[type=file].form-control:valid .valid-feedback,input[type=file].form-control.is-valid .valid-feedback { + margin-top: 0 +} + +.was-validated input[type=file].form-control:valid:focus,input[type=file].form-control.is-valid:focus { + box-shadow: inset 0 0 0 1px #14a44d; + border-color: #14a44d +} + +.was-validated input[type=file].form-control:valid:focus~.form-file-label,input[type=file].form-control.is-valid:focus~.form-file-label { + box-shadow: none +} + +.was-validated input[type=file].form-control:valid:focus-within~.form-file-label .form-file-button,.was-validated input[type=file].form-control:valid:focus-within~.form-file-label .form-file-text,input[type=file].form-control.is-valid:focus-within~.form-file-label .form-file-button,input[type=file].form-control.is-valid:focus-within~.form-file-label .form-file-text { + border-color: #14a44d +} + +.form-check-input.is-valid,.was-validated .form-check-input:valid { + border-color: #14a44d +} + +.form-check-input.is-valid:checked,.was-validated .form-check-input:valid:checked { + background-color: #14a44d +} + +.form-check-input.is-valid:checked:focus:before,.was-validated .form-check-input:valid:checked:focus:before { + box-shadow: 0 0 0 13px #14a44d +} + +.form-check-input.is-valid:focus,.was-validated .form-check-input:valid:focus { + box-shadow: none +} + +.form-check-input.is-valid:focus:before,.was-validated .form-check-input:valid:focus:before { + box-shadow: 0 0 0 13px #14a44d +} + +.form-check-input.is-valid~.form-check-label,.was-validated .form-check-input:valid~.form-check-label { + color: #14a44d; + margin-bottom: 1rem +} + +.form-check-input.is-valid[type=checkbox]:checked:focus,.was-validated .form-check-input:valid[type=checkbox]:checked:focus { + background-color: #14a44d; + border-color: #14a44d +} + +.form-check-input.is-valid[type=radio]:checked,.was-validated .form-check-input:valid[type=radio]:checked { + border-color: #14a44d; + background-color: #fff +} + +.form-check-input.is-valid[type=radio]:checked:focus:before,.was-validated .form-check-input:valid[type=radio]:checked:focus:before { + box-shadow: 0 0 0 13px #14a44d +} + +.form-check-input.is-valid[type=radio]:checked:after,.was-validated .form-check-input:valid[type=radio]:checked:after { + border-color: #14a44d; + background-color: #14a44d +} + +.form-check-inline .form-check-input~.valid-feedback { + margin-left: .5em +} + +.form-switch .form-check-input.is-valid:focus:before,.was-validated .form-switch .form-check-input:valid:focus:before { + box-shadow: 3px -1px 0 13px rgba(0,0,0,.6) +} + +.form-switch .form-check-input.is-valid:checked[type=checkbox]:after,.was-validated .form-switch .form-check-input:valid:checked[type=checkbox]:after { + background-color: #14a44d; + box-shadow: 0 3px 1px -2px rgba(0,0,0,.2),0 2px 2px 0 rgba(0,0,0,.14),0 1px 5px 0 rgba(0,0,0,.12) +} + +.form-switch .form-check-input.is-valid:checked:focus:before,.was-validated .form-switch .form-check-input:valid:checked:focus:before { + box-shadow: 3px -1px 0 13px #14a44d +} + +.invalid-feedback { + width: auto; + color: #dc4c64; + margin-top: -.75rem +} + +.invalid-feedback,.invalid-tooltip { + position: absolute; + display: none; + font-size: .875rem +} + +.invalid-tooltip { + top: 100%; + z-index: 5; + max-width: 100%; + padding: 6px 16px; + margin-top: .1rem; + background-color: rgba(220,76,100,.9); + border-radius: .25rem!important; + color: #fff +} + +.is-invalid~.invalid-feedback,.is-invalid~.invalid-tooltip,.was-validated :invalid~.invalid-feedback,.was-validated :invalid~.invalid-tooltip { + display: block +} + +.form-control.is-invalid,.was-validated .form-control:invalid { + margin-bottom: 1rem; + background-image: none; + border-color: #dc4c64 +} + +.form-control.is-invalid:focus,.was-validated .form-control:invalid:focus { + border-color: #dc4c64; + box-shadow: 0 0 0 .25rem rgba(220,76,100,.25) +} + +.form-outline .form-control.is-invalid~.form-label,.was-validated .form-outline .form-control:invalid~.form-label { + color: #dc4c64 +} + +.form-outline .form-control.is-invalid~.form-notch .form-notch-leading,.form-outline .form-control.is-invalid~.form-notch .form-notch-middle,.form-outline .form-control.is-invalid~.form-notch .form-notch-trailing,.was-validated .form-outline .form-control:invalid~.form-notch .form-notch-leading,.was-validated .form-outline .form-control:invalid~.form-notch .form-notch-middle,.was-validated .form-outline .form-control:invalid~.form-notch .form-notch-trailing { + border-color: #dc4c64 +} + +.form-outline .form-control.is-invalid.active~.form-notch .form-notch-middle,.form-outline .form-control.is-invalid:focus~.form-notch .form-notch-middle,.was-validated .form-outline .form-control:invalid.active~.form-notch .form-notch-middle,.was-validated .form-outline .form-control:invalid:focus~.form-notch .form-notch-middle { + border-top: 1px solid transparent +} + +.form-outline .form-control.is-invalid:focus~.form-notch .form-notch-middle,.was-validated .form-outline .form-control:invalid:focus~.form-notch .form-notch-middle { + box-shadow: 0 1px 0 0 #dc4c64 +} + +.form-outline .form-control.is-invalid:focus~.form-notch .form-notch-leading,.was-validated .form-outline .form-control:invalid:focus~.form-notch .form-notch-leading { + box-shadow: -1px 0 0 0 #dc4c64,0 1px 0 0 #dc4c64,0 -1px 0 0 #dc4c64 +} + +.form-outline .form-control.is-invalid:focus~.form-notch .form-notch-trailing,.was-validated .form-outline .form-control:invalid:focus~.form-notch .form-notch-trailing { + box-shadow: 1px 0 0 0 #dc4c64,0 -1px 0 0 #dc4c64,0 1px 0 0 #dc4c64 +} + +.form-outline .form-control.is-invalid.select-input.focused~.form-notch .form-notch-leading,.was-validated .form-outline .form-control:invalid.select-input.focused~.form-notch .form-notch-leading { + box-shadow: -1px 0 0 0 #dc4c64,0 1px 0 0 #dc4c64,0 -1px 0 0 #dc4c64 +} + +.form-outline .form-control.is-invalid.select-input.focused~.form-notch .form-notch-middle,.was-validated .form-outline .form-control:invalid.select-input.focused~.form-notch .form-notch-middle { + box-shadow: 0 1px 0 0 #dc4c64; + border-top: 1px solid transparent +} + +.form-outline .form-control.is-invalid.select-input.focused~.form-notch .form-notch-trailing,.was-validated .form-outline .form-control:invalid.select-input.focused~.form-notch .form-notch-trailing { + box-shadow: 1px 0 0 0 #dc4c64,0 -1px 0 0 #dc4c64,0 1px 0 0 #dc4c64 +} + +.form-select.is-invalid,.was-validated .form-select:invalid { + border-color: #dc4c64 +} + +.form-select.is-invalid:focus,.was-validated .form-select:invalid:focus { + border-color: #dc4c64; + box-shadow: 0 0 0 .25rem rgba(220,76,100,.25) +} + +.form-select.is-invalid~.invalid-feedback,.was-validated .form-select:invalid~.invalid-feedback { + margin-top: 0 +} + +.input-group .form-control.is-invalid,.was-validated .input-group .form-control:invalid { + margin-bottom: 0 +} + +.was-validated input[type=file].form-control:invalid .invalid-feedback,input[type=file].form-control.is-invalid .invalid-feedback { + margin-top: 0 +} + +.was-validated input[type=file].form-control:invalid:focus,input[type=file].form-control.is-invalid:focus { + box-shadow: inset 0 0 0 1px #dc4c64; + border-color: #dc4c64 +} + +.was-validated input[type=file].form-control:invalid:focus~.form-file-label,input[type=file].form-control.is-invalid:focus~.form-file-label { + box-shadow: none +} + +.was-validated input[type=file].form-control:invalid:focus-within~.form-file-label .form-file-button,.was-validated input[type=file].form-control:invalid:focus-within~.form-file-label .form-file-text,input[type=file].form-control.is-invalid:focus-within~.form-file-label .form-file-button,input[type=file].form-control.is-invalid:focus-within~.form-file-label .form-file-text { + border-color: #dc4c64 +} + +.form-check-input.is-invalid,.was-validated .form-check-input:invalid { + border-color: #dc4c64 +} + +.form-check-input.is-invalid:checked,.was-validated .form-check-input:invalid:checked { + background-color: #dc4c64 +} + +.form-check-input.is-invalid:checked:focus:before,.was-validated .form-check-input:invalid:checked:focus:before { + box-shadow: 0 0 0 13px #dc4c64 +} + +.form-check-input.is-invalid:focus,.was-validated .form-check-input:invalid:focus { + box-shadow: none +} + +.form-check-input.is-invalid:focus:before,.was-validated .form-check-input:invalid:focus:before { + box-shadow: 0 0 0 13px #dc4c64 +} + +.form-check-input.is-invalid~.form-check-label,.was-validated .form-check-input:invalid~.form-check-label { + color: #dc4c64; + margin-bottom: 1rem +} + +.form-check-input.is-invalid[type=checkbox]:checked:focus,.was-validated .form-check-input:invalid[type=checkbox]:checked:focus { + background-color: #dc4c64; + border-color: #dc4c64 +} + +.form-check-input.is-invalid[type=radio]:checked,.was-validated .form-check-input:invalid[type=radio]:checked { + border-color: #dc4c64; + background-color: #fff +} + +.form-check-input.is-invalid[type=radio]:checked:focus:before,.was-validated .form-check-input:invalid[type=radio]:checked:focus:before { + box-shadow: 0 0 0 13px #dc4c64 +} + +.form-check-input.is-invalid[type=radio]:checked:after,.was-validated .form-check-input:invalid[type=radio]:checked:after { + border-color: #dc4c64; + background-color: #dc4c64 +} + +.form-check-inline .form-check-input~.invalid-feedback { + margin-left: .5em +} + +.form-switch .form-check-input.is-invalid:focus:before,.was-validated .form-switch .form-check-input:invalid:focus:before { + box-shadow: 3px -1px 0 13px rgba(0,0,0,.6) +} + +.form-switch .form-check-input.is-invalid:checked[type=checkbox]:after,.was-validated .form-switch .form-check-input:invalid:checked[type=checkbox]:after { + background-color: #dc4c64; + box-shadow: 0 3px 1px -2px rgba(0,0,0,.2),0 2px 2px 0 rgba(0,0,0,.14),0 1px 5px 0 rgba(0,0,0,.12) +} + +.form-switch .form-check-input.is-invalid:checked:focus:before,.was-validated .form-switch .form-check-input:invalid:checked:focus:before { + box-shadow: 3px -1px 0 13px #dc4c64 +} + +.form-range:focus { + box-shadow: none +} + +.form-range:focus::-webkit-slider-thumb { + box-shadow: none +} + +.form-range:focus::-moz-range-thumb { + box-shadow: none +} + +.form-range:focus::-ms-thumb { + box-shadow: none +} + +.form-range::-moz-focus-outer { + border: 0 +} + +.form-range::-webkit-slider-thumb { + margin-top: -6px; + box-shadow: none; + -webkit-appearance: none; + appearance: none +} + +.form-range::-webkit-slider-runnable-track { + height: 4px; + border-radius: 0; + box-shadow: none +} + +.form-range::-moz-range-thumb { + box-shadow: none; + -moz-appearance: none; + appearance: none +} + +.form-range::-moz-range-track { + box-shadow: none +} + +.table { + --mdb-table-font-size: 0.9rem; + --mdb-table-divider-color: rgba(0,0,0,0.1); + font-size: var(--mdb-table-font-size) +} + +.table th { + font-weight: 500 +} + +.table tbody { + font-weight: 400 +} + +.table>:not(:last-child)>:last-child>* { + border-bottom-color: inherit +} + +.table-primary { + --mdb-table-color: #000; + --mdb-table-bg: #d8e3f4; + --mdb-table-border-color: #c2ccdc; + --mdb-table-striped-bg: #cdd8e8; + --mdb-table-striped-color: #000; + --mdb-table-active-bg: #c2ccdc; + --mdb-table-active-color: #000; + --mdb-table-hover-bg: #c8d2e2; + --mdb-table-hover-color: #000 +} + +.table-primary,.table-secondary { + color: var(--mdb-table-color); + border-color: var(--mdb-table-border-color) +} + +.table-secondary { + --mdb-table-color: #000; + --mdb-table-bg: #ecedf0; + --mdb-table-border-color: #d4d5d8; + --mdb-table-striped-bg: #e0e1e4; + --mdb-table-striped-color: #000; + --mdb-table-active-bg: #d4d5d8; + --mdb-table-active-color: #000; + --mdb-table-hover-bg: #dadbde; + --mdb-table-hover-color: #000 +} + +.table-success { + --mdb-table-color: #000; + --mdb-table-bg: #d0eddb; + --mdb-table-border-color: #bbd5c5; + --mdb-table-striped-bg: #c6e1d0; + --mdb-table-striped-color: #000; + --mdb-table-active-bg: #bbd5c5; + --mdb-table-active-color: #000; + --mdb-table-hover-bg: #c0dbcb; + --mdb-table-hover-color: #000 +} + +.table-info,.table-success { + color: var(--mdb-table-color); + border-color: var(--mdb-table-border-color) +} + +.table-info { + --mdb-table-color: #000; + --mdb-table-bg: #ddf0f6; + --mdb-table-border-color: #c7d8dd; + --mdb-table-striped-bg: #d2e4ea; + --mdb-table-striped-color: #000; + --mdb-table-active-bg: #c7d8dd; + --mdb-table-active-color: #000; + --mdb-table-hover-bg: #ccdee4; + --mdb-table-hover-color: #000 +} + +.table-warning { + --mdb-table-color: #000; + --mdb-table-bg: #faecd1; + --mdb-table-border-color: #e1d4bc; + --mdb-table-striped-bg: #eee0c7; + --mdb-table-striped-color: #000; + --mdb-table-active-bg: #e1d4bc; + --mdb-table-active-color: #000; + --mdb-table-hover-bg: #e7dac1; + --mdb-table-hover-color: #000 +} + +.table-danger,.table-warning { + color: var(--mdb-table-color); + border-color: var(--mdb-table-border-color) +} + +.table-danger { + --mdb-table-color: #000; + --mdb-table-bg: #f8dbe0; + --mdb-table-border-color: #dfc5ca; + --mdb-table-striped-bg: #ecd0d5; + --mdb-table-striped-color: #000; + --mdb-table-active-bg: #dfc5ca; + --mdb-table-active-color: #000; + --mdb-table-hover-bg: #e5cbcf; + --mdb-table-hover-color: #000 +} + +.table-light { + --mdb-table-color: #000; + --mdb-table-bg: #fbfbfb; + --mdb-table-border-color: #e2e2e2; + --mdb-table-striped-bg: #eee; + --mdb-table-striped-color: #000; + --mdb-table-active-bg: #e2e2e2; + --mdb-table-active-color: #000; + --mdb-table-hover-bg: #e8e8e8; + --mdb-table-hover-color: #000 +} + +.table-dark,.table-light { + color: var(--mdb-table-color); + border-color: var(--mdb-table-border-color) +} + +.table-dark { + --mdb-table-color: #fff; + --mdb-table-bg: #332d2d; + --mdb-table-border-color: #474242; + --mdb-table-striped-bg: #3d3838; + --mdb-table-striped-color: #fff; + --mdb-table-active-bg: #474242; + --mdb-table-active-color: #fff; + --mdb-table-hover-bg: #423d3d; + --mdb-table-hover-color: #fff +} + +.table-hover>tbody>tr { + transition: .5s +} + +.table-hover>tbody>tr:hover { + --mdb-table-accent-bg: transparent; + background-color: var(--mdb-table-hover-bg) +} + +.table-group-divider { + border-top: 2px solid; + border-top-color: inherit +} + +.table-divider-color { + border-top-color: var(--mdb-table-divider-color) +} + +.btn { + --mdb-btn-padding-top: 0.625rem; + --mdb-btn-padding-bottom: 0.5rem; + --mdb-btn-border-width: 0; + --mdb-btn-border-color: none; + --mdb-btn-border-radius: 0.25rem; + --mdb-btn-box-shadow: 0 4px 9px -4px rgba(0,0,0,0.35); + --mdb-btn-hover-box-shadow: 0 8px 9px -4px rgba(0,0,0,0.15),0 4px 18px 0 rgba(0,0,0,0.1); + --mdb-btn-focus-box-shadow: 0 8px 9px -4px rgba(0,0,0,0.15),0 4px 18px 0 rgba(0,0,0,0.1); + --mdb-btn-active-box-shadow: 0 8px 9px -4px rgba(0,0,0,0.15),0 4px 18px 0 rgba(0,0,0,0.1); + padding-top: var(--mdb-btn-padding-top); + padding-bottom: var(--mdb-btn-padding-bottom); + text-transform: uppercase; + vertical-align: bottom; + border: 0; + border-radius: var(--mdb-btn-border-radius); + box-shadow: var(--mdb-btn-box-shadow) +} + +.btn:first-child:hover,.btn:focus-visible,.btn:hover,:not(.btn-check)+.btn:hover { + box-shadow: var(--mdb-btn-hover-box-shadow) +} + +.btn-check:focus+.btn,.btn-check:focus-visible+.btn,.btn:focus { + box-shadow: var(--mdb-btn-focus-box-shadow) +} + +.btn-check:active+.btn,.btn-check:checked+.btn,.btn.active,.btn.show,.btn:active { + box-shadow: var(--mdb-btn-active-box-shadow) +} + +.btn-check:active+.btn:focus,.btn-check:checked+.btn:focus,.btn.active:focus,.btn.show:focus,.btn:active:focus { + box-shadow: var(--mdb-btn-focus-box-shadow) +} + +.btn.disabled,.btn:disabled,fieldset:disabled .btn { + box-shadow: var(--mdb-btn-box-shadow) +} + +[class*=btn-outline-] { + --mdb-btn-padding-top: 0.5rem; + --mdb-btn-padding-bottom: 0.375rem; + --mdb-btn-padding-x: 1.375rem; + --mdb-btn-border-width: 2px; + --mdb-btn-line-height: 1.5; + padding: var(--mdb-btn-padding-top) var(--mdb-btn-padding-x) var(--mdb-btn-padding-bottom); + border-width: var(--mdb-btn-border-width); + border-style: solid; + box-shadow: none +} + +.btn-check:active+[class*=btn-outline-],.btn-check:active+[class*=btn-outline-]:focus,.btn-check:checked+[class*=btn-outline-],.btn-check:checked+[class*=btn-outline-]:focus,.btn-check:focus+[class*=btn-outline-],.btn-check:focus-visible+[class*=btn-outline-],:not(.btn-check)+[class*=btn-outline-]:hover,[class*=btn-outline-].active,[class*=btn-outline-].active:focus,[class*=btn-outline-].disabled,[class*=btn-outline-].show,[class*=btn-outline-].show:focus,[class*=btn-outline-]:active,[class*=btn-outline-]:active:focus,[class*=btn-outline-]:disabled,[class*=btn-outline-]:first-child:hover,[class*=btn-outline-]:focus,[class*=btn-outline-]:focus-visible,[class*=btn-outline-]:hover,fieldset:disabled [class*=btn-outline-] { + box-shadow: none +} + +.btn-group-lg>[class*=btn-outline-].btn,[class*=btn-outline-].btn-lg { + --mdb-btn-padding-top: 0.625rem; + --mdb-btn-padding-bottom: 0.5625rem; + --mdb-btn-padding-x: 1.5625rem; + --mdb-btn-font-size: 0.875rem; + --mdb-btn-line-height: 1.6 +} + +.btn-group-sm>[class*=btn-outline-].btn,[class*=btn-outline-].btn-sm { + --mdb-btn-padding-top: 0.25rem; + --mdb-btn-padding-bottom: 0.1875rem; + --mdb-btn-padding-x: 0.875rem; + --mdb-btn-font-size: 0.75rem; + --mdb-btn-line-height: 1.5 +} + +.btn-secondary { + box-shadow: none +} + +.btn-secondary:first-child:hover,.btn-secondary:focus-visible,.btn-secondary:hover,:not(.btn-check)+.btn-secondary:hover { + box-shadow: none!important +} + +.btn-check:active+.btn-secondary,.btn-check:active+.btn-secondary:focus,.btn-check:checked+.btn-secondary,.btn-check:checked+.btn-secondary:focus,.btn-check:focus+.btn-secondary,.btn-check:focus-visible+.btn-secondary,.btn-secondary.active,.btn-secondary.active:focus,.btn-secondary.disabled,.btn-secondary.show,.btn-secondary.show:focus,.btn-secondary:active,.btn-secondary:active:focus,.btn-secondary:disabled,.btn-secondary:focus,fieldset:disabled .btn-secondary { + box-shadow: none +} + +.btn-primary { + --mdb-btn-bg: #3b71ca; + --mdb-btn-color: #fff; + --mdb-btn-box-shadow: 0 4px 9px -4px #3b71ca; + --mdb-btn-hover-bg: #386bc0; + --mdb-btn-hover-color: #fff; + --mdb-btn-focus-bg: #386bc0; + --mdb-btn-focus-color: #fff; + --mdb-btn-active-bg: #3566b6; + --mdb-btn-active-color: #fff; + --mdb-btn-box-shadow-state: 0 8px 9px -4px rgba(59,113,202,0.3),0 4px 18px 0 rgba(59,113,202,0.2) +} + +.btn-primary:first-child:hover,.btn-primary:focus-visible,.btn-primary:hover,:not(.btn-check)+.btn-primary:hover { + box-shadow: var(--mdb-btn-box-shadow-state) +} + +.btn-check:focus+.btn-primary,.btn-check:focus-visible+.btn-primary,.btn-primary:focus { + box-shadow: var(--mdb-btn-box-shadow-state); + background-color: var(--mdb-btn-focus-bg) +} + +.btn-check:active+.btn-primary,.btn-check:active+.btn-primary:focus,.btn-check:checked+.btn-primary,.btn-check:checked+.btn-primary:focus,.btn-primary.active,.btn-primary.active:focus,.btn-primary.show,.btn-primary.show:focus,.btn-primary:active,.btn-primary:active:focus { + box-shadow: var(--mdb-btn-box-shadow-state) +} + +.btn-check:active+.btn-primary:hover,.btn-check:checked+.btn-primary:hover,.btn-primary.active:hover,.btn-primary.show:hover,.btn-primary:active:hover { + background-color: var(--mdb-btn-active-bg) +} + +.btn-primary.disabled,.btn-primary:disabled,fieldset:disabled .btn-primary { + box-shadow: var(--mdb-btn-box-shadow) +} + +.btn-secondary { + --mdb-btn-bg: #e3ebf7; + --mdb-btn-color: #285192; + --mdb-btn-box-shadow: 0 4px 9px -4px #e3ebf7; + --mdb-btn-hover-bg: #d8dfeb; + --mdb-btn-hover-color: #285192; + --mdb-btn-focus-bg: #d8dfeb; + --mdb-btn-focus-color: #285192; + --mdb-btn-active-bg: #ccd4de; + --mdb-btn-active-color: #285192; + --mdb-btn-box-shadow-state: 0 8px 9px -4px rgba(227,235,247,0.3),0 4px 18px 0 rgba(227,235,247,0.2) +} + +.btn-secondary:first-child:hover,.btn-secondary:focus-visible,.btn-secondary:hover,:not(.btn-check)+.btn-secondary:hover { + box-shadow: var(--mdb-btn-box-shadow-state) +} + +.btn-check:focus+.btn-secondary,.btn-check:focus-visible+.btn-secondary,.btn-secondary:focus { + box-shadow: var(--mdb-btn-box-shadow-state); + background-color: var(--mdb-btn-focus-bg) +} + +.btn-check:active+.btn-secondary,.btn-check:active+.btn-secondary:focus,.btn-check:checked+.btn-secondary,.btn-check:checked+.btn-secondary:focus,.btn-secondary.active,.btn-secondary.active:focus,.btn-secondary.show,.btn-secondary.show:focus,.btn-secondary:active,.btn-secondary:active:focus { + box-shadow: var(--mdb-btn-box-shadow-state) +} + +.btn-check:active+.btn-secondary:hover,.btn-check:checked+.btn-secondary:hover,.btn-secondary.active:hover,.btn-secondary.show:hover,.btn-secondary:active:hover { + background-color: var(--mdb-btn-active-bg) +} + +.btn-secondary.disabled,.btn-secondary:disabled,fieldset:disabled .btn-secondary { + box-shadow: var(--mdb-btn-box-shadow) +} + +.btn-success { + --mdb-btn-bg: #14a44d; + --mdb-btn-color: #fff; + --mdb-btn-box-shadow: 0 4px 9px -4px #14a44d; + --mdb-btn-hover-bg: #139c49; + --mdb-btn-hover-color: #fff; + --mdb-btn-focus-bg: #139c49; + --mdb-btn-focus-color: #fff; + --mdb-btn-active-bg: #129445; + --mdb-btn-active-color: #fff; + --mdb-btn-box-shadow-state: 0 8px 9px -4px rgba(20,164,77,0.3),0 4px 18px 0 rgba(20,164,77,0.2) +} + +.btn-success:first-child:hover,.btn-success:focus-visible,.btn-success:hover,:not(.btn-check)+.btn-success:hover { + box-shadow: var(--mdb-btn-box-shadow-state) +} + +.btn-check:focus+.btn-success,.btn-check:focus-visible+.btn-success,.btn-success:focus { + box-shadow: var(--mdb-btn-box-shadow-state); + background-color: var(--mdb-btn-focus-bg) +} + +.btn-check:active+.btn-success,.btn-check:active+.btn-success:focus,.btn-check:checked+.btn-success,.btn-check:checked+.btn-success:focus,.btn-success.active,.btn-success.active:focus,.btn-success.show,.btn-success.show:focus,.btn-success:active,.btn-success:active:focus { + box-shadow: var(--mdb-btn-box-shadow-state) +} + +.btn-check:active+.btn-success:hover,.btn-check:checked+.btn-success:hover,.btn-success.active:hover,.btn-success.show:hover,.btn-success:active:hover { + background-color: var(--mdb-btn-active-bg) +} + +.btn-success.disabled,.btn-success:disabled,fieldset:disabled .btn-success { + box-shadow: var(--mdb-btn-box-shadow) +} + +.btn-danger { + --mdb-btn-bg: #dc4c64; + --mdb-btn-color: #fff; + --mdb-btn-box-shadow: 0 4px 9px -4px #dc4c64; + --mdb-btn-hover-bg: #d1485f; + --mdb-btn-hover-color: #fff; + --mdb-btn-focus-bg: #d1485f; + --mdb-btn-focus-color: #fff; + --mdb-btn-active-bg: #c6445a; + --mdb-btn-active-color: #fff; + --mdb-btn-box-shadow-state: 0 8px 9px -4px rgba(220,76,100,0.3),0 4px 18px 0 rgba(220,76,100,0.2) +} + +.btn-danger:first-child:hover,.btn-danger:focus-visible,.btn-danger:hover,:not(.btn-check)+.btn-danger:hover { + box-shadow: var(--mdb-btn-box-shadow-state) +} + +.btn-check:focus+.btn-danger,.btn-check:focus-visible+.btn-danger,.btn-danger:focus { + box-shadow: var(--mdb-btn-box-shadow-state); + background-color: var(--mdb-btn-focus-bg) +} + +.btn-check:active+.btn-danger,.btn-check:active+.btn-danger:focus,.btn-check:checked+.btn-danger,.btn-check:checked+.btn-danger:focus,.btn-danger.active,.btn-danger.active:focus,.btn-danger.show,.btn-danger.show:focus,.btn-danger:active,.btn-danger:active:focus { + box-shadow: var(--mdb-btn-box-shadow-state) +} + +.btn-check:active+.btn-danger:hover,.btn-check:checked+.btn-danger:hover,.btn-danger.active:hover,.btn-danger.show:hover,.btn-danger:active:hover { + background-color: var(--mdb-btn-active-bg) +} + +.btn-danger.disabled,.btn-danger:disabled,fieldset:disabled .btn-danger { + box-shadow: var(--mdb-btn-box-shadow) +} + +.btn-warning { + --mdb-btn-bg: #e4a11b; + --mdb-btn-color: #fff; + --mdb-btn-box-shadow: 0 4px 9px -4px #e4a11b; + --mdb-btn-hover-bg: #d9991a; + --mdb-btn-hover-color: #fff; + --mdb-btn-focus-bg: #d9991a; + --mdb-btn-focus-color: #fff; + --mdb-btn-active-bg: #cd9118; + --mdb-btn-active-color: #fff; + --mdb-btn-box-shadow-state: 0 8px 9px -4px rgba(228,161,27,0.3),0 4px 18px 0 rgba(228,161,27,0.2) +} + +.btn-warning:first-child:hover,.btn-warning:focus-visible,.btn-warning:hover,:not(.btn-check)+.btn-warning:hover { + box-shadow: var(--mdb-btn-box-shadow-state) +} + +.btn-check:focus+.btn-warning,.btn-check:focus-visible+.btn-warning,.btn-warning:focus { + box-shadow: var(--mdb-btn-box-shadow-state); + background-color: var(--mdb-btn-focus-bg) +} + +.btn-check:active+.btn-warning,.btn-check:active+.btn-warning:focus,.btn-check:checked+.btn-warning,.btn-check:checked+.btn-warning:focus,.btn-warning.active,.btn-warning.active:focus,.btn-warning.show,.btn-warning.show:focus,.btn-warning:active,.btn-warning:active:focus { + box-shadow: var(--mdb-btn-box-shadow-state) +} + +.btn-check:active+.btn-warning:hover,.btn-check:checked+.btn-warning:hover,.btn-warning.active:hover,.btn-warning.show:hover,.btn-warning:active:hover { + background-color: var(--mdb-btn-active-bg) +} + +.btn-warning.disabled,.btn-warning:disabled,fieldset:disabled .btn-warning { + box-shadow: var(--mdb-btn-box-shadow) +} + +.btn-info { + --mdb-btn-bg: #54b4d3; + --mdb-btn-color: #fff; + --mdb-btn-box-shadow: 0 4px 9px -4px #54b4d3; + --mdb-btn-hover-bg: #50abc8; + --mdb-btn-hover-color: #fff; + --mdb-btn-focus-bg: #50abc8; + --mdb-btn-focus-color: #fff; + --mdb-btn-active-bg: #4ca2be; + --mdb-btn-active-color: #fff; + --mdb-btn-box-shadow-state: 0 8px 9px -4px rgba(84,180,211,0.3),0 4px 18px 0 rgba(84,180,211,0.2) +} + +.btn-info:first-child:hover,.btn-info:focus-visible,.btn-info:hover,:not(.btn-check)+.btn-info:hover { + box-shadow: var(--mdb-btn-box-shadow-state) +} + +.btn-check:focus+.btn-info,.btn-check:focus-visible+.btn-info,.btn-info:focus { + box-shadow: var(--mdb-btn-box-shadow-state); + background-color: var(--mdb-btn-focus-bg) +} + +.btn-check:active+.btn-info,.btn-check:active+.btn-info:focus,.btn-check:checked+.btn-info,.btn-check:checked+.btn-info:focus,.btn-info.active,.btn-info.active:focus,.btn-info.show,.btn-info.show:focus,.btn-info:active,.btn-info:active:focus { + box-shadow: var(--mdb-btn-box-shadow-state) +} + +.btn-check:active+.btn-info:hover,.btn-check:checked+.btn-info:hover,.btn-info.active:hover,.btn-info.show:hover,.btn-info:active:hover { + background-color: var(--mdb-btn-active-bg) +} + +.btn-info.disabled,.btn-info:disabled,fieldset:disabled .btn-info { + box-shadow: var(--mdb-btn-box-shadow) +} + +.btn-light { + --mdb-btn-bg: #fbfbfb; + --mdb-btn-color: #4f4f4f; + --mdb-btn-box-shadow: 0 4px 9px -4px #fbfbfb; + --mdb-btn-hover-bg: #eee; + --mdb-btn-hover-color: #4f4f4f; + --mdb-btn-focus-bg: #eee; + --mdb-btn-focus-color: #4f4f4f; + --mdb-btn-active-bg: #e2e2e2; + --mdb-btn-active-color: #4f4f4f; + --mdb-btn-box-shadow-state: 0 8px 9px -4px hsla(0,0%,98.4%,0.3),0 4px 18px 0 hsla(0,0%,98.4%,0.2) +} + +.btn-light:first-child:hover,.btn-light:focus-visible,.btn-light:hover,:not(.btn-check)+.btn-light:hover { + box-shadow: var(--mdb-btn-box-shadow-state) +} + +.btn-check:focus+.btn-light,.btn-check:focus-visible+.btn-light,.btn-light:focus { + box-shadow: var(--mdb-btn-box-shadow-state); + background-color: var(--mdb-btn-focus-bg) +} + +.btn-check:active+.btn-light,.btn-check:active+.btn-light:focus,.btn-check:checked+.btn-light,.btn-check:checked+.btn-light:focus,.btn-light.active,.btn-light.active:focus,.btn-light.show,.btn-light.show:focus,.btn-light:active,.btn-light:active:focus { + box-shadow: var(--mdb-btn-box-shadow-state) +} + +.btn-check:active+.btn-light:hover,.btn-check:checked+.btn-light:hover,.btn-light.active:hover,.btn-light.show:hover,.btn-light:active:hover { + background-color: var(--mdb-btn-active-bg) +} + +.btn-light.disabled,.btn-light:disabled,fieldset:disabled .btn-light { + box-shadow: var(--mdb-btn-box-shadow) +} + +.btn-dark { + --mdb-btn-bg: #332d2d; + --mdb-btn-color: #fff; + --mdb-btn-box-shadow: 0 4px 9px -4px #332d2d; + --mdb-btn-hover-bg: #302b2b; + --mdb-btn-hover-color: #fff; + --mdb-btn-focus-bg: #302b2b; + --mdb-btn-focus-color: #fff; + --mdb-btn-active-bg: #2e2929; + --mdb-btn-active-color: #fff; + --mdb-btn-box-shadow-state: 0 8px 9px -4px rgba(51,45,45,0.3),0 4px 18px 0 rgba(51,45,45,0.2) +} + +.btn-dark:first-child:hover,.btn-dark:focus-visible,.btn-dark:hover,:not(.btn-check)+.btn-dark:hover { + box-shadow: var(--mdb-btn-box-shadow-state) +} + +.btn-check:focus+.btn-dark,.btn-check:focus-visible+.btn-dark,.btn-dark:focus { + box-shadow: var(--mdb-btn-box-shadow-state); + background-color: var(--mdb-btn-focus-bg) +} + +.btn-check:active+.btn-dark,.btn-check:active+.btn-dark:focus,.btn-check:checked+.btn-dark,.btn-check:checked+.btn-dark:focus,.btn-dark.active,.btn-dark.active:focus,.btn-dark.show,.btn-dark.show:focus,.btn-dark:active,.btn-dark:active:focus { + box-shadow: var(--mdb-btn-box-shadow-state) +} + +.btn-check:active+.btn-dark:hover,.btn-check:checked+.btn-dark:hover,.btn-dark.active:hover,.btn-dark.show:hover,.btn-dark:active:hover { + background-color: var(--mdb-btn-active-bg) +} + +.btn-dark.disabled,.btn-dark:disabled,fieldset:disabled .btn-dark { + box-shadow: var(--mdb-btn-box-shadow) +} + +.btn-white { + --mdb-btn-bg: #fff; + --mdb-btn-color: #000; + --mdb-btn-box-shadow: 0 4px 9px -4px #fff; + --mdb-btn-hover-bg: #f2f2f2; + --mdb-btn-hover-color: #000; + --mdb-btn-focus-bg: #f2f2f2; + --mdb-btn-focus-color: #000; + --mdb-btn-active-bg: #e6e6e6; + --mdb-btn-active-color: #000; + --mdb-btn-box-shadow-state: 0 8px 9px -4px hsla(0,0%,100%,0.3),0 4px 18px 0 hsla(0,0%,100%,0.2) +} + +.btn-white:first-child:hover,.btn-white:focus-visible,.btn-white:hover,:not(.btn-check)+.btn-white:hover { + box-shadow: var(--mdb-btn-box-shadow-state) +} + +.btn-check:focus+.btn-white,.btn-check:focus-visible+.btn-white,.btn-white:focus { + box-shadow: var(--mdb-btn-box-shadow-state); + background-color: var(--mdb-btn-focus-bg) +} + +.btn-check:active+.btn-white,.btn-check:active+.btn-white:focus,.btn-check:checked+.btn-white,.btn-check:checked+.btn-white:focus,.btn-white.active,.btn-white.active:focus,.btn-white.show,.btn-white.show:focus,.btn-white:active,.btn-white:active:focus { + box-shadow: var(--mdb-btn-box-shadow-state) +} + +.btn-check:active+.btn-white:hover,.btn-check:checked+.btn-white:hover,.btn-white.active:hover,.btn-white.show:hover,.btn-white:active:hover { + background-color: var(--mdb-btn-active-bg) +} + +.btn-white.disabled,.btn-white:disabled,fieldset:disabled .btn-white { + box-shadow: var(--mdb-btn-box-shadow) +} + +.btn-black { + --mdb-btn-bg: #000; + --mdb-btn-color: #fff; + --mdb-btn-box-shadow: 0 4px 9px -4px #000; + --mdb-btn-hover-bg: #000; + --mdb-btn-hover-color: #fff; + --mdb-btn-focus-bg: #000; + --mdb-btn-focus-color: #fff; + --mdb-btn-active-bg: #000; + --mdb-btn-active-color: #fff; + --mdb-btn-box-shadow-state: 0 8px 9px -4px rgba(0,0,0,0.3),0 4px 18px 0 rgba(0,0,0,0.2) +} + +.btn-black:first-child:hover,.btn-black:focus-visible,.btn-black:hover,:not(.btn-check)+.btn-black:hover { + box-shadow: var(--mdb-btn-box-shadow-state) +} + +.btn-black:focus,.btn-check:focus+.btn-black,.btn-check:focus-visible+.btn-black { + box-shadow: var(--mdb-btn-box-shadow-state); + background-color: var(--mdb-btn-focus-bg) +} + +.btn-black.active,.btn-black.active:focus,.btn-black.show,.btn-black.show:focus,.btn-black:active,.btn-black:active:focus,.btn-check:active+.btn-black,.btn-check:active+.btn-black:focus,.btn-check:checked+.btn-black,.btn-check:checked+.btn-black:focus { + box-shadow: var(--mdb-btn-box-shadow-state) +} + +.btn-black.active:hover,.btn-black.show:hover,.btn-black:active:hover,.btn-check:active+.btn-black:hover,.btn-check:checked+.btn-black:hover { + background-color: var(--mdb-btn-active-bg) +} + +.btn-black.disabled,.btn-black:disabled,fieldset:disabled .btn-black { + box-shadow: var(--mdb-btn-box-shadow) +} + +.btn-outline-primary { + --mdb-btn-bg: transparent; + --mdb-btn-color: #3b71ca; + --mdb-btn-hover-bg: transparent; + --mdb-btn-hover-color: #386bc0; + --mdb-btn-focus-bg: transparent; + --mdb-btn-focus-color: #386bc0; + --mdb-btn-active-bg: transparent; + --mdb-btn-active-color: #3566b6; + --mdb-btn-border-color: #3b71ca; + --mdb-btn-focus-border-color: #386bc0; + --mdb-btn-hover-border-color: #386bc0; + border-color: var(--mdb-btn-border-color) +} + +.btn-outline-primary:first-child:hover,.btn-outline-primary:focus-visible,.btn-outline-primary:hover,:not(.btn-check)+.btn-outline-primary:hover { + border-color: var(--mdb-btn-hover-border-color) +} + +.btn-check:focus+.btn-outline-primary,.btn-check:focus-visible+.btn-outline-primary,.btn-outline-primary:focus { + border-color: var(--mdb-btn-focus-border-color) +} + +.btn-check:active+.btn-outline-primary,.btn-check:checked+.btn-outline-primary,.btn-outline-primary.active,.btn-outline-primary.show,.btn-outline-primary:active { + border-color: var(--mdb-btn-active-border-color) +} + +.btn-check:active+.btn-outline-primary:focus,.btn-check:checked+.btn-outline-primary:focus,.btn-outline-primary.active:focus,.btn-outline-primary.show:focus,.btn-outline-primary:active:focus { + border-color: var(--mdb-btn-focus-border-color) +} + +.btn-outline-primary.disabled,.btn-outline-primary:disabled,.btn-outline-secondary,fieldset:disabled .btn-outline-primary { + border-color: var(--mdb-btn-border-color) +} + +.btn-outline-secondary { + --mdb-btn-bg: transparent; + --mdb-btn-color: #285192; + --mdb-btn-hover-bg: transparent; + --mdb-btn-hover-color: #264d8b; + --mdb-btn-focus-bg: transparent; + --mdb-btn-focus-color: #264d8b; + --mdb-btn-active-bg: transparent; + --mdb-btn-active-color: #244983; + --mdb-btn-border-color: #e3ebf7; + --mdb-btn-focus-border-color: #d8dfeb; + --mdb-btn-hover-border-color: #d8dfeb +} + +.btn-outline-secondary:first-child:hover,.btn-outline-secondary:focus-visible,.btn-outline-secondary:hover,:not(.btn-check)+.btn-outline-secondary:hover { + border-color: var(--mdb-btn-hover-border-color) +} + +.btn-check:focus+.btn-outline-secondary,.btn-check:focus-visible+.btn-outline-secondary,.btn-outline-secondary:focus { + border-color: var(--mdb-btn-focus-border-color) +} + +.btn-check:active+.btn-outline-secondary,.btn-check:checked+.btn-outline-secondary,.btn-outline-secondary.active,.btn-outline-secondary.show,.btn-outline-secondary:active { + border-color: var(--mdb-btn-active-border-color) +} + +.btn-check:active+.btn-outline-secondary:focus,.btn-check:checked+.btn-outline-secondary:focus,.btn-outline-secondary.active:focus,.btn-outline-secondary.show:focus,.btn-outline-secondary:active:focus { + border-color: var(--mdb-btn-focus-border-color) +} + +.btn-outline-secondary.disabled,.btn-outline-secondary:disabled,.btn-outline-success,fieldset:disabled .btn-outline-secondary { + border-color: var(--mdb-btn-border-color) +} + +.btn-outline-success { + --mdb-btn-bg: transparent; + --mdb-btn-color: #14a44d; + --mdb-btn-hover-bg: transparent; + --mdb-btn-hover-color: #139c49; + --mdb-btn-focus-bg: transparent; + --mdb-btn-focus-color: #139c49; + --mdb-btn-active-bg: transparent; + --mdb-btn-active-color: #129445; + --mdb-btn-border-color: #14a44d; + --mdb-btn-focus-border-color: #139c49; + --mdb-btn-hover-border-color: #139c49 +} + +.btn-outline-success:first-child:hover,.btn-outline-success:focus-visible,.btn-outline-success:hover,:not(.btn-check)+.btn-outline-success:hover { + border-color: var(--mdb-btn-hover-border-color) +} + +.btn-check:focus+.btn-outline-success,.btn-check:focus-visible+.btn-outline-success,.btn-outline-success:focus { + border-color: var(--mdb-btn-focus-border-color) +} + +.btn-check:active+.btn-outline-success,.btn-check:checked+.btn-outline-success,.btn-outline-success.active,.btn-outline-success.show,.btn-outline-success:active { + border-color: var(--mdb-btn-active-border-color) +} + +.btn-check:active+.btn-outline-success:focus,.btn-check:checked+.btn-outline-success:focus,.btn-outline-success.active:focus,.btn-outline-success.show:focus,.btn-outline-success:active:focus { + border-color: var(--mdb-btn-focus-border-color) +} + +.btn-outline-danger,.btn-outline-success.disabled,.btn-outline-success:disabled,fieldset:disabled .btn-outline-success { + border-color: var(--mdb-btn-border-color) +} + +.btn-outline-danger { + --mdb-btn-bg: transparent; + --mdb-btn-color: #dc4c64; + --mdb-btn-hover-bg: transparent; + --mdb-btn-hover-color: #d1485f; + --mdb-btn-focus-bg: transparent; + --mdb-btn-focus-color: #d1485f; + --mdb-btn-active-bg: transparent; + --mdb-btn-active-color: #c6445a; + --mdb-btn-border-color: #dc4c64; + --mdb-btn-focus-border-color: #d1485f; + --mdb-btn-hover-border-color: #d1485f +} + +.btn-outline-danger:first-child:hover,.btn-outline-danger:focus-visible,.btn-outline-danger:hover,:not(.btn-check)+.btn-outline-danger:hover { + border-color: var(--mdb-btn-hover-border-color) +} + +.btn-check:focus+.btn-outline-danger,.btn-check:focus-visible+.btn-outline-danger,.btn-outline-danger:focus { + border-color: var(--mdb-btn-focus-border-color) +} + +.btn-check:active+.btn-outline-danger,.btn-check:checked+.btn-outline-danger,.btn-outline-danger.active,.btn-outline-danger.show,.btn-outline-danger:active { + border-color: var(--mdb-btn-active-border-color) +} + +.btn-check:active+.btn-outline-danger:focus,.btn-check:checked+.btn-outline-danger:focus,.btn-outline-danger.active:focus,.btn-outline-danger.show:focus,.btn-outline-danger:active:focus { + border-color: var(--mdb-btn-focus-border-color) +} + +.btn-outline-danger.disabled,.btn-outline-danger:disabled,.btn-outline-warning,fieldset:disabled .btn-outline-danger { + border-color: var(--mdb-btn-border-color) +} + +.btn-outline-warning { + --mdb-btn-bg: transparent; + --mdb-btn-color: #e4a11b; + --mdb-btn-hover-bg: transparent; + --mdb-btn-hover-color: #d9991a; + --mdb-btn-focus-bg: transparent; + --mdb-btn-focus-color: #d9991a; + --mdb-btn-active-bg: transparent; + --mdb-btn-active-color: #cd9118; + --mdb-btn-border-color: #e4a11b; + --mdb-btn-focus-border-color: #d9991a; + --mdb-btn-hover-border-color: #d9991a +} + +.btn-outline-warning:first-child:hover,.btn-outline-warning:focus-visible,.btn-outline-warning:hover,:not(.btn-check)+.btn-outline-warning:hover { + border-color: var(--mdb-btn-hover-border-color) +} + +.btn-check:focus+.btn-outline-warning,.btn-check:focus-visible+.btn-outline-warning,.btn-outline-warning:focus { + border-color: var(--mdb-btn-focus-border-color) +} + +.btn-check:active+.btn-outline-warning,.btn-check:checked+.btn-outline-warning,.btn-outline-warning.active,.btn-outline-warning.show,.btn-outline-warning:active { + border-color: var(--mdb-btn-active-border-color) +} + +.btn-check:active+.btn-outline-warning:focus,.btn-check:checked+.btn-outline-warning:focus,.btn-outline-warning.active:focus,.btn-outline-warning.show:focus,.btn-outline-warning:active:focus { + border-color: var(--mdb-btn-focus-border-color) +} + +.btn-outline-info,.btn-outline-warning.disabled,.btn-outline-warning:disabled,fieldset:disabled .btn-outline-warning { + border-color: var(--mdb-btn-border-color) +} + +.btn-outline-info { + --mdb-btn-bg: transparent; + --mdb-btn-color: #54b4d3; + --mdb-btn-hover-bg: transparent; + --mdb-btn-hover-color: #50abc8; + --mdb-btn-focus-bg: transparent; + --mdb-btn-focus-color: #50abc8; + --mdb-btn-active-bg: transparent; + --mdb-btn-active-color: #4ca2be; + --mdb-btn-border-color: #54b4d3; + --mdb-btn-focus-border-color: #50abc8; + --mdb-btn-hover-border-color: #50abc8 +} + +.btn-outline-info:first-child:hover,.btn-outline-info:focus-visible,.btn-outline-info:hover,:not(.btn-check)+.btn-outline-info:hover { + border-color: var(--mdb-btn-hover-border-color) +} + +.btn-check:focus+.btn-outline-info,.btn-check:focus-visible+.btn-outline-info,.btn-outline-info:focus { + border-color: var(--mdb-btn-focus-border-color) +} + +.btn-check:active+.btn-outline-info,.btn-check:checked+.btn-outline-info,.btn-outline-info.active,.btn-outline-info.show,.btn-outline-info:active { + border-color: var(--mdb-btn-active-border-color) +} + +.btn-check:active+.btn-outline-info:focus,.btn-check:checked+.btn-outline-info:focus,.btn-outline-info.active:focus,.btn-outline-info.show:focus,.btn-outline-info:active:focus { + border-color: var(--mdb-btn-focus-border-color) +} + +.btn-outline-info.disabled,.btn-outline-info:disabled,.btn-outline-light,fieldset:disabled .btn-outline-info { + border-color: var(--mdb-btn-border-color) +} + +.btn-outline-light { + --mdb-btn-bg: transparent; + --mdb-btn-color: #fbfbfb; + --mdb-btn-hover-bg: transparent; + --mdb-btn-hover-color: #eee; + --mdb-btn-focus-bg: transparent; + --mdb-btn-focus-color: #eee; + --mdb-btn-active-bg: transparent; + --mdb-btn-active-color: #e2e2e2; + --mdb-btn-border-color: #fbfbfb; + --mdb-btn-focus-border-color: #eee; + --mdb-btn-hover-border-color: #eee +} + +.btn-outline-light:first-child:hover,.btn-outline-light:focus-visible,.btn-outline-light:hover,:not(.btn-check)+.btn-outline-light:hover { + border-color: var(--mdb-btn-hover-border-color) +} + +.btn-check:focus+.btn-outline-light,.btn-check:focus-visible+.btn-outline-light,.btn-outline-light:focus { + border-color: var(--mdb-btn-focus-border-color) +} + +.btn-check:active+.btn-outline-light,.btn-check:checked+.btn-outline-light,.btn-outline-light.active,.btn-outline-light.show,.btn-outline-light:active { + border-color: var(--mdb-btn-active-border-color) +} + +.btn-check:active+.btn-outline-light:focus,.btn-check:checked+.btn-outline-light:focus,.btn-outline-light.active:focus,.btn-outline-light.show:focus,.btn-outline-light:active:focus { + border-color: var(--mdb-btn-focus-border-color) +} + +.btn-outline-dark,.btn-outline-light.disabled,.btn-outline-light:disabled,fieldset:disabled .btn-outline-light { + border-color: var(--mdb-btn-border-color) +} + +.btn-outline-dark { + --mdb-btn-bg: transparent; + --mdb-btn-color: #332d2d; + --mdb-btn-hover-bg: transparent; + --mdb-btn-hover-color: #302b2b; + --mdb-btn-focus-bg: transparent; + --mdb-btn-focus-color: #302b2b; + --mdb-btn-active-bg: transparent; + --mdb-btn-active-color: #2e2929; + --mdb-btn-border-color: #332d2d; + --mdb-btn-focus-border-color: #302b2b; + --mdb-btn-hover-border-color: #302b2b +} + +.btn-outline-dark:first-child:hover,.btn-outline-dark:focus-visible,.btn-outline-dark:hover,:not(.btn-check)+.btn-outline-dark:hover { + border-color: var(--mdb-btn-hover-border-color) +} + +.btn-check:focus+.btn-outline-dark,.btn-check:focus-visible+.btn-outline-dark,.btn-outline-dark:focus { + border-color: var(--mdb-btn-focus-border-color) +} + +.btn-check:active+.btn-outline-dark,.btn-check:checked+.btn-outline-dark,.btn-outline-dark.active,.btn-outline-dark.show,.btn-outline-dark:active { + border-color: var(--mdb-btn-active-border-color) +} + +.btn-check:active+.btn-outline-dark:focus,.btn-check:checked+.btn-outline-dark:focus,.btn-outline-dark.active:focus,.btn-outline-dark.show:focus,.btn-outline-dark:active:focus { + border-color: var(--mdb-btn-focus-border-color) +} + +.btn-outline-dark.disabled,.btn-outline-dark:disabled,.btn-outline-white,fieldset:disabled .btn-outline-dark { + border-color: var(--mdb-btn-border-color) +} + +.btn-outline-white { + --mdb-btn-bg: transparent; + --mdb-btn-color: #fff; + --mdb-btn-hover-bg: transparent; + --mdb-btn-hover-color: #f2f2f2; + --mdb-btn-focus-bg: transparent; + --mdb-btn-focus-color: #f2f2f2; + --mdb-btn-active-bg: transparent; + --mdb-btn-active-color: #e6e6e6; + --mdb-btn-border-color: #fff; + --mdb-btn-focus-border-color: #f2f2f2; + --mdb-btn-hover-border-color: #f2f2f2 +} + +.btn-outline-white:first-child:hover,.btn-outline-white:focus-visible,.btn-outline-white:hover,:not(.btn-check)+.btn-outline-white:hover { + border-color: var(--mdb-btn-hover-border-color) +} + +.btn-check:focus+.btn-outline-white,.btn-check:focus-visible+.btn-outline-white,.btn-outline-white:focus { + border-color: var(--mdb-btn-focus-border-color) +} + +.btn-check:active+.btn-outline-white,.btn-check:checked+.btn-outline-white,.btn-outline-white.active,.btn-outline-white.show,.btn-outline-white:active { + border-color: var(--mdb-btn-active-border-color) +} + +.btn-check:active+.btn-outline-white:focus,.btn-check:checked+.btn-outline-white:focus,.btn-outline-white.active:focus,.btn-outline-white.show:focus,.btn-outline-white:active:focus { + border-color: var(--mdb-btn-focus-border-color) +} + +.btn-outline-black,.btn-outline-white.disabled,.btn-outline-white:disabled,fieldset:disabled .btn-outline-white { + border-color: var(--mdb-btn-border-color) +} + +.btn-outline-black { + --mdb-btn-bg: transparent; + --mdb-btn-color: #000; + --mdb-btn-hover-bg: transparent; + --mdb-btn-hover-color: #000; + --mdb-btn-focus-bg: transparent; + --mdb-btn-focus-color: #000; + --mdb-btn-active-bg: transparent; + --mdb-btn-active-color: #000; + --mdb-btn-border-color: #000; + --mdb-btn-focus-border-color: #000; + --mdb-btn-hover-border-color: #000 +} + +.btn-outline-black:first-child:hover,.btn-outline-black:focus-visible,.btn-outline-black:hover,:not(.btn-check)+.btn-outline-black:hover { + border-color: var(--mdb-btn-hover-border-color) +} + +.btn-check:focus+.btn-outline-black,.btn-check:focus-visible+.btn-outline-black,.btn-outline-black:focus { + border-color: var(--mdb-btn-focus-border-color) +} + +.btn-check:active+.btn-outline-black,.btn-check:checked+.btn-outline-black,.btn-outline-black.active,.btn-outline-black.show,.btn-outline-black:active { + border-color: var(--mdb-btn-active-border-color) +} + +.btn-check:active+.btn-outline-black:focus,.btn-check:checked+.btn-outline-black:focus,.btn-outline-black.active:focus,.btn-outline-black.show:focus,.btn-outline-black:active:focus { + border-color: var(--mdb-btn-focus-border-color) +} + +.btn-outline-black.disabled,.btn-outline-black:disabled,fieldset:disabled .btn-outline-black { + border-color: var(--mdb-btn-border-color) +} + +.btn-link { + --mdb-btn-font-weight: 500; + --mdb-btn-color: #3b71ca; + --mdb-btn-hover-color: #386bc0; + --mdb-btn-hover-bg: #f5f5f5; + --mdb-btn-focus-color: #3566b6; + --mdb-btn-active-color: #3260ac; + --mdb-btn-disabled-color: #9e9e9e; + --mdb-btn-box-shadow: none +} + +.btn-link,.btn-link:first-child:hover,.btn-link:focus-visible,.btn-link:hover,:not(.btn-check)+.btn-link:hover { + text-decoration: none; + box-shadow: var(--mdb-btn-box-shadow) +} + +.btn-check:focus+.btn-link,.btn-check:focus-visible+.btn-link,.btn-link:focus { + color: var(--mdb-btn-focus-color); + box-shadow: var(--mdb-btn-box-shadow) +} + +.btn-check:active+.btn-link,.btn-check:checked+.btn-link,.btn-link.active,.btn-link.show,.btn-link:active { + color: var(--mdb-btn-active-color); + box-shadow: var(--mdb-btn-box-shadow) +} + +.btn-check:active+.btn-link:focus,.btn-check:checked+.btn-link:focus,.btn-link.active:focus,.btn-link.show:focus,.btn-link:active:focus { + color: var(--mdb-btn-focus-color); + box-shadow: var(--mdb-btn-box-shadow) +} + +.btn-link.disabled,.btn-link:disabled,fieldset:disabled .btn-link { + box-shadow: var(--mdb-btn-box-shadow) +} + +.btn-tertiary { + --mdb-btn-font-weight: 500; + --mdb-btn-color: #3b71ca; + --mdb-btn-hover-color: #386bc0; + --mdb-btn-hover-bg: transparent; + --mdb-btn-focus-color: #3566b6; + --mdb-btn-active-color: #3260ac; + --mdb-btn-disabled-color: #9e9e9e; + --mdb-btn-box-shadow: none; + padding-left: 0; + padding-right: 0 +} + +.btn-tertiary,.btn-tertiary:first-child:hover,.btn-tertiary:focus-visible,.btn-tertiary:hover,:not(.btn-check)+.btn-tertiary:hover { + text-decoration: none; + box-shadow: var(--mdb-btn-box-shadow) +} + +.btn-check:focus+.btn-tertiary,.btn-check:focus-visible+.btn-tertiary,.btn-tertiary:focus { + color: var(--mdb-btn-focus-color); + box-shadow: var(--mdb-btn-box-shadow) +} + +.btn-check:active+.btn-tertiary,.btn-check:checked+.btn-tertiary,.btn-tertiary.active,.btn-tertiary.show,.btn-tertiary:active { + color: var(--mdb-btn-active-color); + box-shadow: var(--mdb-btn-box-shadow) +} + +.btn-check:active+.btn-tertiary:focus,.btn-check:checked+.btn-tertiary:focus,.btn-tertiary.active:focus,.btn-tertiary.show:focus,.btn-tertiary:active:focus { + color: var(--mdb-btn-focus-color); + box-shadow: var(--mdb-btn-box-shadow) +} + +.btn-tertiary.disabled,.btn-tertiary:disabled,fieldset:disabled .btn-tertiary { + box-shadow: var(--mdb-btn-box-shadow) +} + +.btn-group-lg>.btn,.btn-lg { + --mdb-btn-padding-top: 0.75rem; + --mdb-btn-padding-bottom: 0.6875rem; + --mdb-btn-padding-x: 1.6875rem; + --mdb-btn-font-size: 0.875rem; + --mdb-btn-line-height: 1.6 +} + +.btn-group-sm>.btn,.btn-sm { + --mdb-btn-padding-top: 0.375rem; + --mdb-btn-padding-bottom: 0.3125rem; + --mdb-btn-padding-x: 1rem; + --mdb-btn-font-size: 0.75rem; + --mdb-btn-line-height: 1.5 +} + +.btn-rounded { + --mdb-btn-border-radius: 10rem; + border-radius: var(--mdb-btn-border-radius) +} + +.btn-floating,[class*=btn-outline-].btn-floating { + --mdb-btn-border-radius: 50%; + border-radius: var(--mdb-btn-border-radius); + padding: 0; + position: relative; + display: inline-flex; + align-items: center; + justify-content: center +} + +.btn-floating { + --mdb-btn-width: 2.3125rem; + --mdb-btn-height: 2.3125rem; + --mdb-btn-icon-width: 2.3125rem; + --mdb-btn-icon-line-height: 2.3125rem; + --mdb-btn-width-lg: 2.8125rem; + --mdb-btn-height-lg: 2.8125rem; + --mdb-btn-icon-width-lg: 2.8125rem; + --mdb-btn-icon-line-height-lg: 2.8125rem; + --mdb-btn-width-sm: 1.8125rem; + --mdb-btn-height-sm: 1.8125rem; + --mdb-btn-icon-width-sm: 1.8125rem; + --mdb-btn-icon-line-height-sm: 1.8125rem; + width: var(--mdb-btn-width); + height: var(--mdb-btn-height) +} + +.btn-floating .fab,.btn-floating .far,.btn-floating .fas { + width: var(--mdb-btn-icon-width); + line-height: var(--mdb-btn-icon-line-height) +} + +.btn-floating.btn-lg,.btn-group-lg>.btn-floating.btn { + width: var(--mdb-btn-width-lg); + height: var(--mdb-btn-height-lg) +} + +.btn-floating.btn-lg .fab,.btn-floating.btn-lg .far,.btn-floating.btn-lg .fas,.btn-group-lg>.btn-floating.btn .fab,.btn-group-lg>.btn-floating.btn .far,.btn-group-lg>.btn-floating.btn .fas { + width: var(--mdb-btn-icon-width-lg); + line-height: var(--mdb-btn-icon-line-height-lg) +} + +.btn-floating.btn-sm,.btn-group-sm>.btn-floating.btn { + width: var(--mdb-btn-width-sm); + height: var(--mdb-btn-height-sm) +} + +.btn-floating.btn-sm .fab,.btn-floating.btn-sm .far,.btn-floating.btn-sm .fas,.btn-group-sm>.btn-floating.btn .fab,.btn-group-sm>.btn-floating.btn .far,.btn-group-sm>.btn-floating.btn .fas { + width: var(--mdb-btn-icon-width-sm); + line-height: var(--mdb-btn-icon-line-height-sm) +} + +[class*=btn-outline-].btn-floating { + --mdb-btn-icon-width: 2.0625rem; + --mdb-btn-icon-width-lg: 2.5625rem; + --mdb-btn-icon-width-sm: 1.5625rem; + --mdb-btn-icon-line-height: 2.0625rem; + --mdb-btn-icon-line-height-lg: 2.5625rem; + --mdb-btn-icon-line-height-sm: 1.5625rem +} + +[class*=btn-outline-].btn-floating .fab,[class*=btn-outline-].btn-floating .far,[class*=btn-outline-].btn-floating .fas { + width: var(--mdb-btn-icon-width); + line-height: var(--mdb-btn-icon-line-height) +} + +.btn-group-lg>[class*=btn-outline-].btn-floating.btn .fab,.btn-group-lg>[class*=btn-outline-].btn-floating.btn .far,.btn-group-lg>[class*=btn-outline-].btn-floating.btn .fas,[class*=btn-outline-].btn-floating.btn-lg .fab,[class*=btn-outline-].btn-floating.btn-lg .far,[class*=btn-outline-].btn-floating.btn-lg .fas { + width: var(--mdb-btn-icon-width-lg); + line-height: var(--mdb-btn-icon-line-height-lg) +} + +.btn-group-sm>[class*=btn-outline-].btn-floating.btn .fab,.btn-group-sm>[class*=btn-outline-].btn-floating.btn .far,.btn-group-sm>[class*=btn-outline-].btn-floating.btn .fas,[class*=btn-outline-].btn-floating.btn-sm .fab,[class*=btn-outline-].btn-floating.btn-sm .far,[class*=btn-outline-].btn-floating.btn-sm .fas { + width: var(--mdb-btn-icon-width-sm); + line-height: var(--mdb-btn-icon-line-height-sm) +} + +.fixed-action-btn { + --mdb-btn-right: 2.1875rem; + --mdb-btn-bottom: 2.1875rem; + --mdb-btn-zindex: 1030; + --mdb-btn-padding-top: 0.9375rem; + --mdb-btn-padding-bottom: 1.25rem; + --mdb-btn-padding-x: 1.25rem; + --mdb-btn-margin-bottom: 1.5rem; + position: fixed; + right: var(--mdb-btn-right); + bottom: var(--mdb-btn-bottom); + z-index: var(--mdb-btn-zindex); + display: flex; + flex-flow: column-reverse nowrap; + align-items: center; + padding: var(--mdb-btn-padding-top) var(--mdb-btn-padding-x) var(--mdb-btn-padding-bottom); + margin-bottom: 0; + height: auto; + overflow: hidden +} + +.fixed-action-btn>.btn-floating { + position: relative; + transform: scale(1.2); + z-index: 10 +} + +.fixed-action-btn ul { + position: absolute; + bottom: 0; + left: 0; + right: 0; + display: flex; + flex-direction: column; + padding: 0; + margin: 0; + text-align: center; + opacity: 0; + transition: transform .4s,opacity .4s; + z-index: -1 +} + +.fixed-action-btn ul li { + z-index: 0; + display: flex; + margin-right: auto; + margin-bottom: var(--mdb-btn-margin-bottom); + margin-left: auto +} + +.fixed-action-btn ul li:first-of-type { + margin-top: calc(var(--mdb-btn-margin-bottom)*0.5) +} + +.fixed-action-btn ul a.btn { + opacity: 0; + transition: opacity .4s ease-in +} + +.fixed-action-btn.active ul,.fixed-action-btn ul a.btn.shown { + opacity: 1 +} + +.btn-block { + --mdb-btn-margin-top: 0.5rem; + display: block; + width: 100% +} + +.btn-block+.btn-block { + margin-top: var(--mdb-btn-margin-top) +} + +hr.divider-horizontal:not([size]) { + height: 2px +} + +.divider-horizontal { + opacity: 1; + background-color: #f5f5f5; + height: 2px +} + +.divider-vertical { + opacity: 1; + background-color: #f5f5f5; + display: inline-block; + width: 2px; + margin: 0 1rem +} + +hr.divider-horizontal-blurry { + background-image: linear-gradient(90deg,transparent,#666,transparent); + background-color: transparent +} + +hr.divider-vertical-blurry { + background-image: linear-gradient(180deg,transparent,#666,transparent); + background-color: transparent; + width: 1px; + top: 0; + right: 0 +} + +.dropdown-menu { + --mdb-dropdown-item-border-radius: 0.5rem; + color: var(--mdb-dropdown-color); + margin: 0; + padding-top: 0; + padding-bottom: 0; + border: 0; + box-shadow: var(--mdb-dropdown-box-shadow); + font-size: var(--mdb-dropdown-font-size); + top: 100%; + left: 0; + margin-top: var(--mdb-dropdown-spacer) +} + +.dropdown-menu>li { + border-radius: 0 +} + +.dropdown-menu>li:first-child,.dropdown-menu>li:first-child .dropdown-item { + border-top-left-radius: var(--mdb-dropdown-item-border-radius); + border-top-right-radius: var(--mdb-dropdown-item-border-radius); + border-bottom-left-radius: 0; + border-bottom-right-radius: 0 +} + +.dropdown-menu>li:not(:first-child):not(:last-child) .dropdown-item { + border-radius: 0 +} + +.dropdown-menu>li:last-child,.dropdown-menu>li:last-child .dropdown-item { + border-top-left-radius: 0; + border-top-right-radius: 0; + border-bottom-left-radius: var(--mdb-dropdown-item-border-radius); + border-bottom-right-radius: var(--mdb-dropdown-item-border-radius) +} + +.dropdown-menu.animation { + --mdb-dropdown-menu-animated-animation-duration: 0.55s; + --mdb-dropdown-menu-animated-animation-timing-function: ease; + display: block; + animation-duration: var(--mdb-dropdown-menu-animated-animation-duration); + animation-timing-function: var(--mdb-dropdown-menu-animated-animation-timing-function) +} + +.dropdown-item { + --mdb-dropdown-state-color: #16181b; + --mdb-dropdown-state-background-color: #eee; + padding: var(--mdb-dropdown-item-padding-y) var(--mdb-dropdown-item-padding-x); + color: var(--mdb-dropdown-color); + border-radius: 0 +} + +.dropdown-item.active,.dropdown-item:active,.dropdown-item:focus,.dropdown-item:hover { + color: var(--mdb-dropdown-state-color); + background-color: var(--mdb-dropdown-state-background-color) +} + +.hidden-arrow.dropdown-toggle:after { + display: none +} + +.animation { + animation-duration: 1s; + animation-fill-mode: both; + padding: auto +} + +@media(prefers-reduced-motion) { + .animation { + transition: none!important; + animation: unset!important + } +} + +@keyframes fade-in { + 0% { + opacity: 0 + } + + to { + opacity: 1 + } +} + +.fade-in { + animation-name: fade-in +} + +@keyframes fade-out { + 0% { + opacity: 1 + } + + to { + opacity: 0 + } +} + +.fade-out { + animation-name: fade-out +} + +.dropdown-divider { + --mdb-dropdown-divider-border-top-width: 2px; + --mdb-dropdown-divider-border-top-bg: #f5f5f5; + border-top: var(--mdb-dropdown-divider-border-top-width) solid var(--mdb-dropdown-divider-border-top-bg); + opacity: 1 +} + +.dropdown-menu INPUT:not(:-webkit-autofill),.dropdown-menu SELECT:not(:-webkit-autofill),.dropdown-menu TEXTAREA:not(:-webkit-autofill) { + animation-name: none!important +} + +.btn-group,.btn-group-vertical { + --mdb-btn-box-shadow: 0 4px 9px -4px rgba(0,0,0,0.35); + --mdb-btn-hover-box-shadow: 0 8px 9px -4px rgba(0,0,0,0.15),0 4px 18px 0 rgba(0,0,0,0.1); + --mdb-btn-focus-box-shadow: 0 8px 9px -4px rgba(0,0,0,0.15),0 4px 18px 0 rgba(0,0,0,0.1); + --mdb-btn-active-box-shadow: 0 8px 9px -4px rgba(0,0,0,0.15),0 4px 18px 0 rgba(0,0,0,0.1); + --mdb-btn-group-transition: color 0.15s ease-in-out,background-color 0.15s ease-in-out,border-color 0.15s ease-in-out,box-shadow 0.15s ease-in-out; + box-shadow: var(--mdb-btn-box-shadow); + transition: var(--mdb-btn-group-transition) +} + +.btn-group-vertical:hover,.btn-group:hover { + box-shadow: var(--mdb-btn-hover-box-shadow) +} + +.btn-group-vertical.focus,.btn-group-vertical:focus,.btn-group.focus,.btn-group:focus { + box-shadow: var(--mdb-btn-focus-box-shadow) +} + +.btn-group-vertical.active,.btn-group-vertical:active,.btn-group.active,.btn-group:active { + box-shadow: var(--mdb-btn-active-box-shadow) +} + +.btn-group-vertical.active:focus,.btn-group-vertical:active:focus,.btn-group.active:focus,.btn-group:active:focus { + box-shadow: var(--mdb-btn-focus-box-shadow) +} + +.btn-group-vertical.disabled,.btn-group-vertical:disabled,.btn-group.disabled,.btn-group:disabled,fieldset:disabled .btn-group,fieldset:disabled .btn-group-vertical { + box-shadow: var(--mdb-btn-box-shadow); + border: 0 +} + +.btn-group-vertical>.btn,.btn-group>.btn { + box-shadow: none +} + +.btn-group-vertical>.btn:first-child:hover,.btn-group-vertical>.btn:focus-visible,.btn-group-vertical>.btn:hover,.btn-group>.btn:first-child:hover,.btn-group>.btn:focus-visible,.btn-group>.btn:hover,:not(.btn-check)+.btn-group-vertical>.btn:hover,:not(.btn-check)+.btn-group>.btn:hover { + box-shadow: none!important +} + +.btn-check:active+.btn-group-vertical>.btn,.btn-check:active+.btn-group-vertical>.btn:focus,.btn-check:active+.btn-group>.btn,.btn-check:active+.btn-group>.btn:focus,.btn-check:checked+.btn-group-vertical>.btn,.btn-check:checked+.btn-group-vertical>.btn:focus,.btn-check:checked+.btn-group>.btn,.btn-check:checked+.btn-group>.btn:focus,.btn-check:focus+.btn-group-vertical>.btn,.btn-check:focus+.btn-group>.btn,.btn-check:focus-visible+.btn-group-vertical>.btn,.btn-check:focus-visible+.btn-group>.btn,.btn-group-vertical>.btn-group,.btn-group-vertical>.btn.active,.btn-group-vertical>.btn.active:focus,.btn-group-vertical>.btn.disabled,.btn-group-vertical>.btn.show,.btn-group-vertical>.btn.show:focus,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:active:focus,.btn-group-vertical>.btn:disabled,.btn-group-vertical>.btn:focus,.btn-group>.btn-group,.btn-group>.btn.active,.btn-group>.btn.active:focus,.btn-group>.btn.disabled,.btn-group>.btn.show,.btn-group>.btn.show:focus,.btn-group>.btn:active,.btn-group>.btn:active:focus,.btn-group>.btn:disabled,.btn-group>.btn:focus,fieldset:disabled .btn-group-vertical>.btn,fieldset:disabled .btn-group>.btn { + box-shadow: none +} + +.btn-group-vertical>.btn-link:first-child,.btn-group-vertical>.btn-tertiary:first-child,.btn-group>.btn-link:first-child,.btn-group>.btn-tertiary:first-child { + border-top-left-radius: 0; + border-bottom-left-radius: 0 +} + +.btn-group-vertical>.btn-link:last-child,.btn-group-vertical>.btn-tertiary:last-child,.btn-group>.btn-link:last-child,.btn-group>.btn-tertiary:last-child { + border-top-right-radius: 0; + border-bottom-right-radius: 0 +} + +.btn-group,.btn-group-lg>.btn,.btn-group-sm>.btn { + --mdb-btn-border-radius: 0.25rem; + border-radius: var(--mdb-btn-border-radius) +} + +.nav-tabs { + border-bottom: 0 +} + +.nav-tabs .nav-link { + --mdb-nav-tabs-link-font-weight: 500; + --mdb-nav-tabs-link-font-size: 12px; + --mdb-nav-tabs-link-color: rgba(0,0,0,0.55); + --mdb-nav-tabs-link-padding-top: 17px; + --mdb-nav-tabs-link-padding-bottom: 16px; + --mdb-nav-tabs-link-padding-x: 29px; + --mdb-nav-tabs-link-hover-bgc: #f7f7f7; + --mdb-nav-tabs-link-border-bottom-width: 2px; + --mdb-nav-tabs-link-active-color: #3b71ca; + --mdb-nav-tabs-link-active-border-color: #3b71ca; + border-width: 0; + border-bottom: var(--mdb-nav-tabs-link-border-bottom-width) solid transparent; + border-radius: 0; + text-transform: uppercase; + line-height: 1; + font-weight: var(--mdb-nav-tabs-link-font-weight); + font-size: var(--mdb-nav-tabs-link-font-size); + color: var(--mdb-nav-tabs-link-color); + padding: var(--mdb-nav-tabs-link-padding-top) var(--mdb-nav-tabs-link-padding-x) var(--mdb-nav-tabs-link-padding-bottom) var(--mdb-nav-tabs-link-padding-x) +} + +.nav-tabs .nav-link:hover { + background-color: var(--mdb-nav-tabs-link-hover-bgc); + border-color: transparent +} + +.nav-tabs .nav-link:focus { + border-color: transparent +} + +.nav-tabs .nav-item.show .nav-link,.nav-tabs .nav-link.active { + color: var(--mdb-nav-tabs-link-active-color); + border-color: var(--mdb-nav-tabs-link-active-border-color) +} + +.nav-pills { + margin-left: -.5rem +} + +.nav-pills .nav-link { + --mdb-nav-pills-link-border-radius: 0.25rem; + --mdb-nav-pills-link-font-size: 12px; + --mdb-nav-pills-link-padding-top: 17px; + --mdb-nav-pills-link-padding-bottom: 16px; + --mdb-nav-pills-link-padding-x: 29px; + --mdb-nav-pills-link-line-height: 1; + --mdb-nav-pills-link-hover-bg: #f7f7f7; + --mdb-nav-pills-link-font-weight: 500; + --mdb-nav-pills-link-color: rgba(0,0,0,0.55); + --mdb-nav-pills-margin: 0.5rem; + border-radius: var(--mdb-nav-pills-link-border-radius); + font-size: var(--mdb-nav-pills-link-font-size); + text-transform: uppercase; + padding: var(--mdb-nav-pills-link-padding-top) var(--mdb-nav-pills-link-padding-x) var(--mdb-nav-pills-link-padding-bottom) var(--mdb-nav-pills-link-padding-x); + line-height: var(--mdb-nav-pills-link-line-height); + background-color: var(--mdb-nav-pills-link-hover-bg); + font-weight: var(--mdb-nav-pills-link-font-weight); + color: var(--mdb-nav-pills-link-color); + margin: var(--mdb-nav-pills-margin) +} + +.nav-pills .nav-link.active,.nav-pills .show>.nav-link { + --mdb-nav-pills-link-active-bg: #e3ebf7; + --mdb-nav-pills-link-active-color: #285192; + background-color: var(--mdb-nav-pills-link-active-bg); + color: var(--mdb-nav-pills-link-active-color) +} + +.nav-fill .nav-item .nav-link,.nav-justified .nav-item .nav-link { + width: auto +} + +.navbar { + --mdb-navbar-box-shadow: 0 4px 12px 0 rgba(0,0,0,0.07),0 2px 4px rgba(0,0,0,0.05); + --mdb-navbar-padding-top: 0.5625rem; + --mdb-navbar-brand-img-margin-right: 0.25rem; + box-shadow: var(--mdb-navbar-box-shadow); + padding-top: var(--mdb-navbar-padding-top) +} + +.navbar-toggler { + border: 0 +} + +.navbar-toggler:focus { + box-shadow: none +} + +.navbar-dark .navbar-toggler,.navbar-light .navbar-toggler { + border: 0 +} + +.navbar-brand { + display: flex; + align-items: center +} + +.navbar-brand img { + margin-right: var(--mdb-navbar-brand-img-margin-right) +} + +.navbar-nav .dropdown-menu { + position: absolute +} + +.navbar-dark .navbar-toggler-icon,.navbar-light .navbar-toggler-icon { + background-image: none +} + +.card { + border: 0 +} + +.card .bg-image { + border-top-left-radius: var(--mdb-card-border-radius); + border-top-right-radius: var(--mdb-card-border-radius) +} + +.card[class*=bg-] .card-header { + --mdb-card-header-border-bottom-color: var(--mdb-border-color-translucent); + border-bottom-color: var(--mdb-card-header-border-bottom-color) +} + +.card[class*=bg-] .card-footer { + --mdb-card-footer-border-top-color: var(--mdb-border-color-translucent); + border-top-color: var(--mdb-card-footer-border-top-color) +} + +.card-header { + --mdb-card-header-border-width: 2px; + --mdb-card-header-border-color: #f5f5f5; + border-bottom: var(--mdb-card-header-border-width) solid var(--mdb-card-header-border-color) +} + +.card-body[class*=bg-] { + border-bottom-left-radius: var(--mdb-card-border-radius); + border-bottom-right-radius: var(--mdb-card-border-radius) +} + +.card-footer { + --mdb-card-footer-border-color: #f5f5f5; + --mdb-card-footer-border-width: 2px; + border-top: var(--mdb-card-footer-border-width) solid var(--mdb-card-footer-border-color) +} + +.card-img-left { + border-top-left-radius: var(--mdb-card-border-radius); + border-bottom-left-radius: var(--mdb-card-border-radius) +} + +.navbar .breadcrumb { + --mdb-breadcrumb-item-color: rgba(0,0,0,0.55); + --mdb-breadcrumb-item-hover-color: rgba(0,0,0,0.7); + --mdb-breadcrumb-item-before-color: rgba(0,0,0,0.55); + --mdb-breadcrumb-item-transition: color 0.15s ease-in-out; + background-color: transparent; + margin-bottom: 0 +} + +.navbar .breadcrumb .breadcrumb-item a { + color: var(--mdb-breadcrumb-item-color); + transition: var(--mdb-breadcrumb-item-transition) +} + +.navbar .breadcrumb .breadcrumb-item a:focus,.navbar .breadcrumb .breadcrumb-item a:hover { + color: var(--mdb-breadcrumb-item-hover-color) +} + +.navbar .breadcrumb .breadcrumb-item+.breadcrumb-item:before { + color: var(--mdb-breadcrumb-item-before-color) +} + +.pagination { + --mdb-pagination-border-radius: 0.25rem; + --mdb-pagination-active-box-shadow: 0 4px 9px -4px #e3ebf7; + --mdb-pagination-active-transition: all 0.2s linear; + --mdb-pagination-active-font-weight: 500; + --mdb-pagination-circle-border-radius: 50%; + --mdb-pagination-circle-padding-x: 0.841rem; + --mdb-pagination-circle-padding-l-lg: 1.399414rem; + --mdb-pagination-circle-padding-r-lg: 1.399415rem; + --mdb-pagination-circle-padding-l-sm: 0.696rem; + --mdb-pagination-circle-padding-r-sm: 0.688rem +} + +.page-link { + background-color: transparent; + border: 0; + outline: 0; + border-radius: var(--mdb-pagination-border-radius) +} + +.page-link:focus { + box-shadow: none +} + +.active>.page-link,.page-link.active { + border: 0; + box-shadow: var(--mdb-pagination-active-box-shadow); + transition: var(--mdb-pagination-active-transition); + font-weight: var(--mdb-pagination-active-font-weight) +} + +.page-item:not(:first-child) .page-link { + margin-left: 0 +} + +.page-item:first-child .page-link { + border-top-left-radius: var(--mdb-pagination-border-radius); + border-bottom-left-radius: var(--mdb-pagination-border-radius) +} + +.page-item:last-child .page-link { + border-top-right-radius: var(--mdb-pagination-border-radius); + border-bottom-right-radius: var(--mdb-pagination-border-radius) +} + +.pagination-circle .page-item:first-child .page-link,.pagination-circle .page-item:last-child .page-link,.pagination-circle .page-link { + border-radius: var(--mdb-pagination-circle-border-radius) +} + +.pagination-circle .page-link { + padding-left: var(--mdb-pagination-circle-padding-x); + padding-right: var(--mdb-pagination-circle-padding-x) +} + +.pagination-circle.pagination-lg .page-link { + padding-left: var(--mdb-pagination-circle-padding-l-lg); + padding-right: var(--mdb-pagination-circle-padding-r-lg) +} + +.pagination-circle.pagination-sm .page-link { + padding-left: var(--mdb-pagination-circle-padding-l-sm); + padding-right: var(--mdb-pagination-circle-padding-r-sm) +} + +.badge-dot { + --mdb-badge-border-radius: 4.5px; + --mdb-badge-height: 9px; + --mdb-badge-width: 9px; + --mdb-badge-margin-left: -0.3125rem; + position: absolute; + min-width: 0; + width: var(--mdb-badge-width); + height: var(--mdb-badge-height); + border-radius: var(--mdb-badge-border-radius); + padding: 0; + margin-left: var(--mdb-badge-margin-left) +} + +.badge-dot:empty { + display: inline-block +} + +.badge-notification { + --mdb-badge-font-size: 0.6rem; + --mdb-badge-padding-x: 0.45em; + --mdb-badge-padding-y: 0.2em; + --mdb-badge-margin-top: -0.1rem; + --mdb-badge-margin-left: -0.5rem; + position: absolute; + font-size: var(--mdb-badge-font-size); + padding: var(--mdb-badge-padding-y) var(--mdb-badge-padding-x); + margin-top: var(--mdb-badge-margin-top); + margin-left: var(--mdb-badge-margin-left) +} + +.badge-primary { + background-color: #dfe7f6; + color: #2c58a0 +} + +.badge-primary i { + color: #376fc8 +} + +.badge-secondary { + background-color: #ebedef; + color: #40464f +} + +.badge-secondary i { + color: #565e6c +} + +.badge-success { + background-color: #d6f0e0; + color: #0d6832 +} + +.badge-success i { + color: #139647 +} + +.badge-danger { + background-color: #f9e1e5; + color: #af233a +} + +.badge-danger i { + color: #d62e4a +} + +.badge-warning { + background-color: #fbf0da; + color: #73510d +} + +.badge-warning i { + color: #a17112 +} + +.badge-info { + background-color: #def1f7; + color: #1c657d +} + +.badge-info i { + color: #2686a6 +} + +.badge-light { + background-color: #f5f5f5; + color: #4f4f4f +} + +.badge-light i { + color: #8c8c8c +} + +.badge-dark { + background-color: #332e2e; + color: #f5f5f5 +} + +.badge-dark i { + color: #e8e8e8 +} + +.alert { + border: 0 +} + +.alert-absolute { + position: absolute +} + +.alert-fixed { + --mdb-alert-fixed-z-index: 1070; + position: fixed; + z-index: var(--mdb-alert-fixed-z-index) +} + +.parent-alert-relative { + position: relative +} + +.alert-primary { + background-color: #dfe7f6; + color: #2c58a0 +} + +.alert-primary i { + color: #376fc8 +} + +.alert-primary .alert-link { + color: #2c58a0 +} + +.alert-primary .alert-link:hover { + color: #234680 +} + +.alert-secondary { + background-color: #ebedef; + color: #40464f +} + +.alert-secondary i { + color: #565e6c +} + +.alert-secondary .alert-link { + color: #40464f +} + +.alert-secondary .alert-link:hover { + color: #33383f +} + +.alert-success { + background-color: #d6f0e0; + color: #0d6832 +} + +.alert-success i { + color: #139647 +} + +.alert-success .alert-link { + color: #0d6832 +} + +.alert-success .alert-link:hover { + color: #0a5328 +} + +.alert-danger { + background-color: #f9e1e5; + color: #af233a +} + +.alert-danger i { + color: #d62e4a +} + +.alert-danger .alert-link { + color: #af233a +} + +.alert-danger .alert-link:hover { + color: #8c1c2e +} + +.alert-warning { + background-color: #fbf0da; + color: #73510d +} + +.alert-warning i { + color: #a17112 +} + +.alert-warning .alert-link { + color: #73510d +} + +.alert-warning .alert-link:hover { + color: #5c410a +} + +.alert-info { + background-color: #def1f7; + color: #1c657d +} + +.alert-info i { + color: #2686a6 +} + +.alert-info .alert-link { + color: #1c657d +} + +.alert-info .alert-link:hover { + color: #165164 +} + +.alert-light { + background-color: #f5f5f5; + color: #4f4f4f +} + +.alert-light i { + color: #8c8c8c +} + +.alert-light .alert-link { + color: #4f4f4f +} + +.alert-light .alert-link:hover { + color: #3f3f3f +} + +.alert-dark { + background-color: #332e2e; + color: #f5f5f5 +} + +.alert-dark i { + color: #e8e8e8 +} + +.alert-dark .alert-link { + color: #f5f5f5 +} + +.alert-dark .alert-link:hover { + color: #c4c4c4 +} + +.progress { + border-radius: 0; + box-shadow: none +} + +.list-group { + --mdb-list-group-item-transition-time: 0.5s +} + +.list-group-item-action,.list-group-item-action:hover { + transition: var(--mdb-list-group-item-transition-time) +} + +.list-group-light { + --mdb-list-group-light-item-py: 1rem; + --mdb-list-group-light-item-border: 2px solid #f5f5f5; + --mdb-list-group-light-item-border-width: 2px; + --mdb-list-group-light-active-border-radius: 0.5rem; + --mdb-list-group-light-active-bg: #dfe7f6; + --mdb-list-group-light-active-color: #2c58a0 +} + +.list-group-light .list-group-item { + padding: var(--mdb-list-group-light-item-py) 0; + border: var(--mdb-list-group-light-item-border) +} + +.list-group-light>.list-group-item { + border-left-width: 0; + border-bottom-width: var(--mdb-list-group-light-item-border-width); + border-right-width: 0; + border-top-width: 0 +} + +.list-group-light>.list-group-item:last-of-type { + border: none +} + +.list-group-light .active { + border: none; + border-radius: var(--mdb-list-group-light-active-border-radius); + background-color: var(--mdb-list-group-light-active-bg); + color: var(--mdb-list-group-light-active-color) +} + +.list-group-light .list-group-item-action:focus,.list-group-light .list-group-item-action:hover { + border-radius: var(--mdb-list-group-light-active-border-radius) +} + +.list-group-small { + --mdb-list-group-small-item-py: 0.5rem +} + +.list-group-small .list-group-item { + padding: var(--mdb-list-group-small-item-py) 0 +} + +.list-group-item-primary { + background-color: #dfe7f6; + color: #2c58a0 +} + +.list-group-item-primary i { + color: #376fc8 +} + +.list-group-item-secondary { + background-color: #ebedef; + color: #40464f +} + +.list-group-item-secondary i { + color: #565e6c +} + +.list-group-item-success { + background-color: #d6f0e0; + color: #0d6832 +} + +.list-group-item-success i { + color: #139647 +} + +.list-group-item-danger { + background-color: #f9e1e5; + color: #af233a +} + +.list-group-item-danger i { + color: #d62e4a +} + +.list-group-item-warning { + background-color: #fbf0da; + color: #73510d +} + +.list-group-item-warning i { + color: #a17112 +} + +.list-group-item-info { + background-color: #def1f7; + color: #1c657d +} + +.list-group-item-info i { + color: #2686a6 +} + +.list-group-item-light { + background-color: #f5f5f5; + color: #4f4f4f +} + +.list-group-item-light i { + color: #8c8c8c +} + +.list-group-item-dark { + background-color: #332e2e; + color: #f5f5f5 +} + +.list-group-item-dark i { + color: #e8e8e8 +} + +.btn-close:focus { + box-shadow: none +} + +.modal-content { + --mdb-modal-box-shadow: 0 2px 15px -3px rgba(0,0,0,0.07),0 10px 20px -2px rgba(0,0,0,0.04); + border: 0; + box-shadow: var(--mdb-modal-box-shadow) +} + +.toast { + --mdb-toast-border-bottom-width: 2px; + --mdb-toast-btn-close-width: 1.3em; + --mdb-toast-btn-close-mr: -0.375rem; + --mdb-toast-btn-close-ml: 0.75rem; + border: 0 +} + +.toast .btn-close { + width: var(--mdb-toast-btn-close-width) +} + +.toast-header { + border-bottom-width: var(--mdb-toast-border-bottom-width) +} + +.toast-header .btn-close { + margin-right: var(--mdb-toast-btn-close-mr); + margin-left: var(--mdb-toast-btn-close-ml) +} + +.parent-toast-relative { + position: relative +} + +.toast-absolute { + position: absolute +} + +.toast-fixed { + position: fixed; + z-index: var(--mdb-toast-zindex) +} + +.toast-primary { + background-color: #dfe7f6; + color: #2c58a0; + border-color: #c7d6f0 +} + +.toast-primary i { + color: #376fc8 +} + +.toast-secondary { + background-color: #ebedef; + color: #40464f; + border-color: #dadee1 +} + +.toast-secondary i { + color: #565e6c +} + +.toast-success { + background-color: #d6f0e0; + color: #0d6831; + border-color: #c0e7d0 +} + +.toast-success i { + color: #139647 +} + +.toast-danger { + background-color: #f9e1e5; + color: #af233a; + border-color: #f4c8cf +} + +.toast-danger i { + color: #d62e4a +} + +.toast-warning { + background-color: #fbf0da; + color: #73510d; + border-color: #f9e4be +} + +.toast-warning i { + color: #a17112 +} + +.toast-info { + background-color: #def1f7; + color: #1c657d; + border-color: #c6e6f1 +} + +.toast-info i { + color: #2686a6 +} + +.toast-light { + background-color: #f5f5f5; + color: #4f4f4f; + border-color: #e6e6e6 +} + +.toast-light i { + color: #8c8c8c +} + +.toast-dark { + background-color: #332e2e; + color: #f5f5f5; + border-color: #443c3c +} + +.toast-dark i { + color: #e8e8e8 +} + +.tooltip { + --mdb-tooltip-font-size: 14px +} + +.tooltip.show { + opacity: 1 +} + +.tooltip .tooltip-arrow { + display: none +} + +.tooltip-inner { + font-size: var(--mdb-tooltip-font-size) +} + +.popover { + --mdb-popover-border-bottom-width: 2px +} + +.popover .popover-arrow { + display: none +} + +.popover-header { + border-bottom: var(--mdb-popover-border-bottom-width) solid var(--mdb-popover-border-color) +} + +.nav-pills.menu-sidebar .nav-link { + --mdb-scrollspy-menu-sidebar-font-size: 0.8rem; + --mdb-scrollspy-menu-sidebar-color: #262626; + --mdb-scrollspy-menu-sidebar-line-height: 1.1rem; + --mdb-scrollspy-menu-sidebar-padding-x: 5px; + --mdb-scrollspy-menu-sidebar-font-weight: 400; + --mdb-scrollspy-menu-sidebar-transition: all 0.2s ease-in-out; + --mdb-scrollspy-menu-sidebar-margin-y: 3px; + font-size: var(--mdb-scrollspy-menu-sidebar-font-size); + background-color: transparent; + color: var(--mdb-scrollspy-menu-sidebar-color); + line-height: var(--mdb-scrollspy-menu-sidebar-line-height); + padding: 0 var(--mdb-scrollspy-menu-sidebar-padding-x); + font-weight: var(--mdb-scrollspy-menu-sidebar-font-weight); + transition: var(--mdb-scrollspy-menu-sidebar-transition); + text-transform: none; + margin-top: var(--mdb-scrollspy-menu-sidebar-margin-y); + margin-bottom: var(--mdb-scrollspy-menu-sidebar-margin-y) +} + +.nav-pills.menu-sidebar .nav-link.active,.nav-pills.menu-sidebar .show>.nav-link { + --mdb-scrollspy-menu-sidebar-active-color: #3b71ca; + --mdb-scrollspy-menu-sidebar-active-font-weight: 600; + --mdb-scrollspy-menu-sidebar-active-border-width: 0.125rem; + --mdb-scrollspy-menu-sidebar-active-border-color: #3b71ca; + background-color: transparent; + box-shadow: none; + color: var(--mdb-scrollspy-menu-sidebar-active-color); + font-weight: var(--mdb-scrollspy-menu-sidebar-active-font-weight); + border-left: var(--mdb-scrollspy-menu-sidebar-active-border-width) solid var(--mdb-scrollspy-menu-sidebar-active-border-color); + border-radius: 0 +} + +.nav-pills.menu-sidebar .collapsible-scrollspy~.nav { + --mdb-scrollspy-collapsible-nav-transition-time: 0.5s; + transition: height var(--mdb-scrollspy-collapsible-nav-transition-time) ease; + flex-wrap: nowrap +} + +.ripple-surface { + position: relative; + overflow: hidden; + display: inline-block; + vertical-align: bottom +} + +.ripple-surface-unbound { + overflow: visible +} + +.ripple-wave { + --mdb-ripple-wave-cubicBezier: cubic-bezier(0,0,0.15,1); + --mdb-ripple-wave-border-radius: 50%; + --mdb-ripple-wave-opacity: 0.5; + --mdb-ripple-wave-transform: scale(0); + --mdb-ripple-wave-z-index: 999; + --mdb-ripple-wave-active-transform: scale(1); + background-image: radial-gradient(circle,rgba(0,0,0,.2) 0,rgba(0,0,0,.3) 40%,rgba(0,0,0,.4) 50%,rgba(0,0,0,.5) 60%,transparent 70%); + border-radius: var(--mdb-ripple-wave-border-radius); + opacity: var(--mdb-ripple-wave-opacity); + pointer-events: none; + position: absolute; + touch-action: none; + transform: var(--mdb-ripple-wave-transform); + transition-property: transform,opacity; + transition-timing-function: var(--mdb-ripple-wave-cubicBezier),var(--mdb-ripple-wave-cubicBezier); + z-index: var(--mdb-ripple-wave-z-index) +} + +.ripple-wave.active { + transform: var(--mdb-ripple-wave-active-transform); + opacity: 0 +} + +.btn .ripple-wave,.input-wrapper .ripple-wave { + background-image: radial-gradient(circle,hsla(0,0%,100%,.2) 0,hsla(0,0%,100%,.3) 40%,hsla(0,0%,100%,.4) 50%,hsla(0,0%,100%,.5) 60%,hsla(0,0%,100%,0) 70%) +} + +.ripple-surface-primary .ripple-wave { + background-image: radial-gradient(circle,rgba(59,113,202,.2) 0,rgba(59,113,202,.3) 40%,rgba(59,113,202,.4) 50%,rgba(59,113,202,.5) 60%,rgba(59,113,202,0) 70%) +} + +.ripple-surface-secondary .ripple-wave { + background-image: radial-gradient(circle,rgba(227,235,247,.2) 0,rgba(227,235,247,.3) 40%,rgba(227,235,247,.4) 50%,rgba(227,235,247,.5) 60%,rgba(227,235,247,0) 70%) +} + +.ripple-surface-success .ripple-wave { + background-image: radial-gradient(circle,rgba(20,164,77,.2) 0,rgba(20,164,77,.3) 40%,rgba(20,164,77,.4) 50%,rgba(20,164,77,.5) 60%,rgba(20,164,77,0) 70%) +} + +.ripple-surface-danger .ripple-wave { + background-image: radial-gradient(circle,rgba(220,76,100,.2) 0,rgba(220,76,100,.3) 40%,rgba(220,76,100,.4) 50%,rgba(220,76,100,.5) 60%,rgba(220,76,100,0) 70%) +} + +.ripple-surface-warning .ripple-wave { + background-image: radial-gradient(circle,rgba(228,161,27,.2) 0,rgba(228,161,27,.3) 40%,rgba(228,161,27,.4) 50%,rgba(228,161,27,.5) 60%,rgba(228,161,27,0) 70%) +} + +.ripple-surface-info .ripple-wave { + background-image: radial-gradient(circle,rgba(84,180,211,.2) 0,rgba(84,180,211,.3) 40%,rgba(84,180,211,.4) 50%,rgba(84,180,211,.5) 60%,rgba(84,180,211,0) 70%) +} + +.ripple-surface-light .ripple-wave { + background-image: radial-gradient(circle,hsla(0,0%,98.4%,.2) 0,hsla(0,0%,98.4%,.3) 40%,hsla(0,0%,98.4%,.4) 50%,hsla(0,0%,98.4%,.5) 60%,hsla(0,0%,98.4%,0) 70%) +} + +.ripple-surface-dark .ripple-wave { + background-image: radial-gradient(circle,rgba(51,45,45,.2) 0,rgba(51,45,45,.3) 40%,rgba(51,45,45,.4) 50%,rgba(51,45,45,.5) 60%,rgba(51,45,45,0) 70%) +} + +.range { + --mdb-range-thumb-height: 30px; + --mdb-range-thumb-width: 30px; + --mdb-range-thumb-top: -35px; + --mdb-range-thumb-margin-left: -15px; + --mdb-range-thumb-border-radius: 50% 50% 50% 0; + --mdb-range-thumb-transform: scale(0); + --mdb-range-thumb-transition: transform 0.2s ease-in-out; + --mdb-range-thumb-value-font-size: 12px; + --mdb-range-thumb-value-line-height: 30px; + --mdb-range-thumb-value-color: #fff; + --mdb-range-thumb-value-font-weight: 500; + --mdb-range-thumb-background: #3b71ca; + position: relative +} + +.range .thumb { + height: var(--mdb-range-thumb-height); + width: var(--mdb-range-thumb-width); + top: var(--mdb-range-thumb-top); + margin-left: var(--mdb-range-thumb-margin-left); + text-align: center; + transform: var(--mdb-range-thumb-transform); + transform-origin: bottom; + transition: var(--mdb-range-thumb-transition) +} + +.range .thumb,.range .thumb:after { + position: absolute; + display: block; + border-radius: var(--mdb-range-thumb-border-radius) +} + +.range .thumb:after { + content: ""; + transform: translateX(-50%); + width: 100%; + height: 100%; + top: 0; + transform: rotate(-45deg); + background: var(--mdb-range-thumb-background); + z-index: -1 +} + +.range .thumb .thumb-value { + display: block; + font-size: var(--mdb-range-thumb-value-font-size); + line-height: var(--mdb-range-thumb-value-line-height); + color: var(--mdb-range-thumb-value-color); + font-weight: var(--mdb-range-thumb-value-font-weight); + z-index: 2 +} + +.range .thumb.thumb-active { + transform: scale(1) +} + +.accordion-button:not(.collapsed):focus { + box-shadow: var(--mdb-accordion-btn-focus-box-shadow) +} + +.accordion-button:focus { + border-color: var(--mdb-accordion-btn-focus-border-color); + outline: 0; + box-shadow: none +} + +.accordion-flush { + --mdb-accordion-flush-btn-box-shadow: inset 0 -2px 0 #f5f5f5; + --mdb-accordion-flush-border-bottom: 2px solid #f5f5f5 +} + +.accordion-flush .accordion-button:not(.collapsed) { + box-shadow: var(--mdb-accordion-flush-btn-box-shadow) +} + +.accordion-flush .accordion-item { + border-bottom: var(--mdb-accordion-flush-border-bottom) +} + +.accordion.accordion-borderless,.accordion.accordion-flush { + --mdb-accordion-bg: transparent; + background-color: var(--mdb-accordion-bg) +} + +.accordion-borderless { + --mdb-accordion-borderless-btn-border-radius: 0.5rem; + --mdb-accordion-borderless-btn-bg: #dfe7f6; + --mdb-accordion-borderless-btn-color: #2c58a0 +} + +.accordion-borderless .accordion-item { + border: 0 +} + +.accordion-borderless .accordion-item .accordion-button { + border-radius: var(--mdb-accordion-borderless-btn-border-radius) +} + +.accordion-borderless .accordion-item .accordion-button:not(.collapsed) { + background-color: var(--mdb-accordion-borderless-btn-bg); + color: var(--mdb-accordion-borderless-btn-color); + box-shadow: none +} + +.modal { + --mdb-modal-top-left-top: 10px; + --mdb-modal-top-left-left: 10px; + --mdb-modal-top-right-top: 10px; + --mdb-modal-top-right-right: 10px; + --mdb-modal-bottom-left-bottom: 10px; + --mdb-modal-bottom-left-left: 10px; + --mdb-modal-bottom-right-bottom: 10px; + --mdb-modal-bottom-right-right: 10px; + --mdb-modal-fade-top-transform: translate3d(0,-25%,0); + --mdb-modal-fade-right-transform: translate3d(25%,0,0); + --mdb-modal-fade-bottom-transform: translate3d(0,25%,0); + --mdb-modal-fade-left-transform: translate3d(-25%,0,0); + --mdb-modal-side-right: 10px; + --mdb-modal-side-bottom: 10px; + --mdb-modal-non-invasive-box-shadow: 0 2px 6px -1px rgba(0,0,0,0.07),0 6px 18px -1px rgba(0,0,0,0.04); + --mdb-modal-non-invasive-box-shadow-top: 0 -10px 20px 0 rgba(0,0,0,0.05) +} + +@media(min-width: 768px) { + .modal .modal-dialog.modal-top { + top:0 + } + + .modal .modal-dialog.modal-left { + left: 0 + } + + .modal .modal-dialog.modal-right { + right: 0 + } + + .modal .modal-dialog.modal-top-left { + top: var(--mdb-modal-top-left-top); + left: var(--mdb-modal-top-left-left) + } + + .modal .modal-dialog.modal-top-right { + top: var(--mdb-modal-top-right-top); + right: var(--mdb-modal-top-right-right) + } + + .modal .modal-dialog.modal-bottom-left { + bottom: var(--mdb-modal-bottom-left-bottom); + left: var(--mdb-modal-bottom-left-left) + } + + .modal .modal-dialog.modal-bottom-right { + right: var(--mdb-modal-bottom-right-right); + bottom: var(--mdb-modal-bottom-right-bottom) + } +} + +.modal .modal-dialog.modal-bottom { + bottom: 0 +} + +.modal.fade.top:not(.show) .modal-dialog { + transform: var(--mdb-modal-fade-top-transform) +} + +.modal.fade.right:not(.show) .modal-dialog { + transform: var(--mdb-modal-fade-right-transform) +} + +.modal.fade.bottom:not(.show) .modal-dialog { + transform: var(--mdb-modal-fade-bottom-transform) +} + +.modal.fade.left:not(.show) .modal-dialog { + transform: var(--mdb-modal-fade-left-transform) +} + +@media(min-width: 992px) { + .modal .modal-side { + position:absolute; + width: 100%; + right: var(--mdb-modal-side-right); + bottom: var(--mdb-modal-side-bottom); + margin: 0 + } +} + +.modal .modal-frame { + position: absolute; + max-width: 100%; + width: 100%; + margin: 0 +} + +.modal-open .modal.frame { + overflow-y: hidden +} + +.modal-non-invasive-open { + overflow-y: auto +} + +.modal-non-invasive-open .modal.modal-non-invasive-show { + display: table +} + +@media(min-width: 992px) { + .modal-non-invasive-open .modal.modal-non-invasive-show .modal-dialog.modal-bottom-left,.modal-non-invasive-open .modal.modal-non-invasive-show .modal-dialog.modal-bottom-right,.modal-non-invasive-open .modal.modal-non-invasive-show .modal-side { + bottom:0 + } + + .modal-non-invasive-open .modal.modal-non-invasive-show.modal.frame.bottom,.modal-non-invasive-open .modal.modal-non-invasive-show.modal.frame.bottom .modal-content { + box-shadow: var(--mdb-modal-non-invasive-box-shadow-top) + } + + .modal-non-invasive-open .modal.modal-non-invasive-show.modal.frame.top { + box-shadow: var(--mdb-modal-non-invasive-box-shadow) + } + + .modal-non-invasive-open .modal.modal-non-invasive-show .modal-side.modal-bottom-left .modal-content,.modal-non-invasive-open .modal.modal-non-invasive-show .modal-side.modal-bottom-right .modal-content { + box-shadow: var(--mdb-modal-non-invasive-box-shadow-top) + } +} + +.modal-non-invasive-open .modal.modal-non-invasive-show .modal-dialog.modal-bottom-right { + right: 0 +} + +.modal-non-invasive-open .modal.modal-non-invasive-show .modal-dialog.modal-bottom-left,.modal-non-invasive-open .modal.modal-non-invasive-show .modal-dialog.modal-top-left { + left: 0 +} + +.modal-non-invasive-open .modal.modal-non-invasive-show .modal-side { + right: 0 +} + +.ps { + --mdb-scrollbar-rail-x-y-transition-opacity-bg: background-color 0.2s linear,opacity 0.2s linear; + --mdb-scrollbar-z-index: 1035; + --mdb-scrollbar-rail-x-y-length: 0.9375rem; + --mdb-scrollbar-rail-x-y-opacity: 0.6; + --mdb-scrollbar-rail-x-y-hover-opacity: 0.9; + --mdb-scrollbar-rail-x-y-bg-color: #eee; + --mdb-scrollbar-rail-x-y-clicking: #999; + --mdb-scrollbar-rail-x-y-clicking-length: 0.6875rem; + --mdb-scrollbar-rail-x-transition-height-bg: background-color 0.2s linear,height 0.2s ease-in-out; + --mdb-scrollbar-rail-y-transition-width-bg: background-color 0.2s linear,width 0.2s ease-in-out; + --mdb-scrollbar-thumb-x-y-color: #aaa; + --mdb-scrollbar-thumb-x-y-border-radius: 0.375rem; + --mdb-scrollbar-thumb-x-y-length: 0.375rem; + --mdb-scrollbar-thumb-x-y-position-length: 0.125rem; + overflow: hidden!important; + overflow-anchor: none; + touch-action: auto +} + +.ps__rail-x,.ps__rail-y { + display: none; + opacity: 0; + transition: var(--mdb-scrollbar-rail-x-y-transition-opacity-bg); + position: absolute; + z-index: var(--mdb-scrollbar-z-index) +} + +.ps__rail-x { + height: var(--mdb-scrollbar-rail-x-y-length); + bottom: 0 +} + +.ps__rail-y { + width: var(--mdb-scrollbar-rail-x-y-length); + right: 0 +} + +.ps--active-x>.ps__rail-x,.ps--active-y>.ps__rail-y { + display: block; + background-color: transparent +} + +.ps--focus>.ps__rail-x,.ps--focus>.ps__rail-y,.ps--scrolling-x>.ps__rail-x,.ps--scrolling-y>.ps__rail-y,.ps:hover>.ps__rail-x,.ps:hover>.ps__rail-y { + opacity: var(--mdb-scrollbar-rail-x-y-opacity) +} + +.ps .ps__rail-x.ps--clicking,.ps .ps__rail-x:focus,.ps .ps__rail-x:hover,.ps .ps__rail-y.ps--clicking,.ps .ps__rail-y:focus,.ps .ps__rail-y:hover { + background-color: var(--mdb-scrollbar-rail-x-y-bg-color); + opacity: var(--mdb-scrollbar-rail-x-y-hover-opacity) +} + +.ps__thumb-x,.ps__thumb-y { + background-color: var(--mdb-scrollbar-thumb-x-y-color); + border-radius: var(--mdb-scrollbar-thumb-x-y-border-radius); + position: absolute +} + +.ps__thumb-x { + transition: var(--mdb-scrollbar-rail-x-transition-height-bg); + height: var(--mdb-scrollbar-thumb-x-y-length); + bottom: var(--mdb-scrollbar-thumb-x-y-position-length) +} + +.ps__thumb-y { + transition: var(--mdb-scrollbar-rail-y-transition-width-bg); + width: var(--mdb-scrollbar-thumb-x-y-length); + right: var(--mdb-scrollbar-thumb-x-y-position-length) +} + +.ps__rail-x.ps--clicking .ps__thumb-x,.ps__rail-x:focus>.ps__thumb-x,.ps__rail-x:hover>.ps__thumb-x { + background-color: var(--mdb-scrollbar-rail-x-y-clicking); + height: var(--mdb-scrollbar-rail-x-y-clicking-length) +} + +.ps__rail-y.ps--clicking .ps__thumb-y,.ps__rail-y:focus>.ps__thumb-y,.ps__rail-y:hover>.ps__thumb-y { + background-color: var(--mdb-scrollbar-rail-x-y-clicking); + width: var(--mdb-scrollbar-rail-x-y-clicking-length) +} + +@supports(-ms-overflow-style: none) { + .ps { + overflow:auto!important + } +} + +@media (-ms-high-contrast:none),screen and (-ms-high-contrast:active) { + .ps { + overflow: auto!important + } +} + +.sidenav { + --mdb-sidenav-transform: translateX(-100%); + --mdb-sidenav-zindex: 1035; + --mdb-sidenav-background-color: #fff; + --mdb-sidenav-width: 240px; + --mdb-sidenav-height: 100vh; + --mdb-sidenav-box-shadow: 0 4px 12px 0 rgba(0,0,0,0.07),0 2px 4px rgba(0,0,0,0.05); + --mdb-sidenav-data-hidden-false-transform: translateX(0%); + --mdb-sidenav-data-color-light-color: hsla(0,0%,100%,0.6); + --mdb-sidenav-data-right-true-transform: translateX(100%); + --mdb-sidenav-data-slim-collapsed-true-width: 77px; + --mdb-sidenav-menu-padding: 0.2rem; + --mdb-sidenav-collapse-sidenav-link-font-size: 0.78rem; + --mdb-sidenav-collapse-sidenav-link-height: 1.5rem; + --mdb-sidenav-link-font-size: 0.89rem; + --mdb-sidenav-link-padding-y: 1rem; + --mdb-sidenav-link-padding-x: 1.5rem; + --mdb-sidenav-collapse-sidenav-link-padding-left: 3.4rem; + --mdb-sidenav-link-height: 3rem; + --mdb-sidenav-link-border-radius: 5px; + --mdb-sidenav-link-transition: all 0.3s linear; + --mdb-sidenav-link-hover-background-color: #f6f9fc; + --mdb-sidenav-link-active-focus-background-color: #f6f9fc; + --mdb-sidenav-link-active-color: #3b71ca; + --mdb-sidenav-subheading-font-size: 0.6rem; + --mdb-sidenav-subheading-padding-y: 1rem; + --mdb-sidenav-subheading-padding-x: 1.5rem; + --mdb-sidenav-subheading-fw: 700; + --mdb-sidenav-sm-link-pt: 0.4rem; + --mdb-sidenav-sm-link-pb: 0.4rem; + --mdb-sidenav-rotate-icon-margin-right: 0.8rem; + --mdb-sidenav-rotate-icon-transition: transform 0.3s; + --mdb-sidenav-light-color: hsla(0,0%,100%,0.6); + top: 0; + left: 0; + transform: var(--mdb-sidenav-transform); + position: fixed; + z-index: var(--mdb-sidenav-zindex); + background-color: var(--mdb-sidenav-background-color); + overflow: hidden; + width: var(--mdb-sidenav-width); + height: var(--mdb-sidenav-height); + box-shadow: var(--mdb-sidenav-box-shadow) +} + +.sidenav[data-mdb-hidden=false] { + transform: var(--mdb-sidenav-data-hidden-false-transform) +} + +.sidenav[data-mdb-color=light] { + color: var(--mdb-sidenav-data-color-light-color) +} + +.sidenav[data-mdb-right=true] { + right: 0; + left: unset; + transform: var(--mdb-sidenav-data-right-true-transform) +} + +.sidenav[data-mdb-position=absolute] { + position: absolute; + height: 100% +} + +.sidenav[data-mdb-position=relative] { + position: relative; + height: 100% +} + +.sidenav [data-mdb-slim=true] { + display: none +} + +.sidenav[data-mdb-slim-collapsed=true] { + width: var(--mdb-sidenav-data-slim-collapsed-true-width) +} + +.sidenav[data-mdb-slim-collapsed=true] [data-mdb-slim=false] { + display: none +} + +.sidenav[data-mdb-slim-collapsed=true] [data-mdb-slim=true] { + display: unset +} + +.sidenav-collapse,.sidenav-menu { + list-style: none; + position: relative; + padding: 0 var(--mdb-sidenav-menu-padding); + margin: 0 +} + +.sidenav-collapse { + display: none; + padding: 0 +} + +.sidenav-collapse.collapsing,.sidenav-collapse.show { + display: block +} + +.sidenav-collapse .sidenav-link { + font-size: var(--mdb-sidenav-collapse-sidenav-link-font-size); + height: var(--mdb-sidenav-collapse-sidenav-link-height); + padding-left: var(--mdb-sidenav-collapse-sidenav-link-padding-left) +} + +.sidenav-item { + position: relative +} + +.sidenav-link { + display: flex; + align-items: center; + cursor: pointer; + font-size: var(--mdb-sidenav-link-font-size); + padding: var(--mdb-sidenav-link-padding-y) var(--mdb-sidenav-link-padding-x); + height: var(--mdb-sidenav-link-height); + color: unset; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + border-radius: var(--mdb-sidenav-link-border-radius); + transition: var(--mdb-sidenav-link-transition) +} + +.sidenav-link:hover { + color: inherit; + background-color: var(--mdb-sidenav-link-hover-background-color); + outline: none +} + +.sidenav-link:active,.sidenav-link:focus { + color: inherit; + background-color: var(--mdb-sidenav-link-active-focus-background-color); + outline: none +} + +.sidenav-link.active { + color: var(--mdb-sidenav-link-active-color) +} + +.sidenav-link i { + color: #9fa6b2 +} + +.sidenav-subheading { + color: unset; + text-transform: uppercase; + font-size: var(--mdb-sidenav-subheading-font-size); + padding: var(--mdb-sidenav-subheading-padding-y) var(--mdb-sidenav-subheading-padding-x); + font-weight: var(--mdb-sidenav-subheading-fw) +} + +.sidenav-sm .sidenav-link { + padding-top: var(--mdb-sidenav-sm-link-pt); + padding-bottom: var(--mdb-sidenav-sm-link-pb); + height: auto +} + +.rotate-icon { + position: absolute; + right: 0; + margin-left: auto; + margin-right: var(--mdb-sidenav-rotate-icon-margin-right); + transition: var(--mdb-sidenav-rotate-icon-transition) +} + +.sidenav-backdrop { + --mdb-sidenav-backdrop-zindex: 1034; + --mdb-sidenav-backdrop-background-color: rgba(0,0,0,0.1); + z-index: var(--mdb-sidenav-backdrop-zindex); + top: 0; + left: 0; + background-color: var(--mdb-sidenav-backdrop-background-color) +} + +.sidenav-light { + color: var(--mdb-sidenav-light-color) +} + +.sidenav-slim { + --mdb-sidenav-slim-link-padding-left: 1rem +} + +.sidenav-slim .sidenav-link { + padding-left: var(--mdb-sidenav-slim-link-padding-left) +} + +.sidenav-primary .sidenav-item .sidenav-link:hover,.sidenav-primary .sidenav-link:active,.sidenav-primary .sidenav-link:focus { + color: inherit; + background-color: rgba(59,113,202,.05) +} + +.sidenav-primary .sidenav-link.active { + color: inherit +} + +.sidenav-secondary .sidenav-item .sidenav-link:hover,.sidenav-secondary .sidenav-link:active,.sidenav-secondary .sidenav-link:focus { + color: inherit; + background-color: rgba(159,166,178,.05) +} + +.sidenav-secondary .sidenav-link.active { + color: inherit +} + +.sidenav-success .sidenav-item .sidenav-link:hover,.sidenav-success .sidenav-link:active,.sidenav-success .sidenav-link:focus { + color: inherit; + background-color: rgba(20,164,77,.05) +} + +.sidenav-success .sidenav-link.active { + color: inherit +} + +.sidenav-danger .sidenav-item .sidenav-link:hover,.sidenav-danger .sidenav-link:active,.sidenav-danger .sidenav-link:focus { + color: inherit; + background-color: rgba(220,76,100,.05) +} + +.sidenav-danger .sidenav-link.active { + color: inherit +} + +.sidenav-warning .sidenav-item .sidenav-link:hover,.sidenav-warning .sidenav-link:active,.sidenav-warning .sidenav-link:focus { + color: inherit; + background-color: rgba(228,161,27,.05) +} + +.sidenav-warning .sidenav-link.active { + color: inherit +} + +.sidenav-info .sidenav-item .sidenav-link:hover,.sidenav-info .sidenav-link:active,.sidenav-info .sidenav-link:focus { + color: inherit; + background-color: rgba(84,180,211,.05) +} + +.sidenav-info .sidenav-link.active { + color: inherit +} + +.sidenav-light .sidenav-item .sidenav-link:hover,.sidenav-light .sidenav-link:active,.sidenav-light .sidenav-link:focus { + color: inherit; + background-color: hsla(0,0%,98.4%,.05) +} + +.sidenav-light .sidenav-link.active { + color: inherit +} + +.sidenav-dark .sidenav-item .sidenav-link:hover,.sidenav-dark .sidenav-link:active,.sidenav-dark .sidenav-link:focus { + color: inherit; + background-color: rgba(51,45,45,.05) +} + +.sidenav-dark .sidenav-link.active { + color: inherit +} + +.animation { + --mdb-animation-delay-1s: 1s; + --mdb-animation-delay-2s: 3s; + --mdb-animation-delay-3s: 3s; + --mdb-animation-delay-4s: 4s; + --mdb-animation-delay-5s: 5s; + --mdb-animation-fast-duration: 800ms; + --mdb-animation-faster-duration: 500ms; + --mdb-animation-slow-duration: 2s; + --mdb-animation-slower-duration: 3s +} + +.animation.infinite { + animation-iteration-count: infinite +} + +.animation.delay-1s { + animation-delay: var(--mdb-animation-delay-1s) +} + +.animation.delay-2s { + animation-delay: var(--mdb-animation-delay-2s) +} + +.animation.delay-3s { + animation-delay: var(--mdb-animation-delay-3s) +} + +.animation.delay-4s { + animation-delay: var(--mdb-animation-delay-4s) +} + +.animation.delay-5s { + animation-delay: var(--mdb-animation-delay-5s) +} + +.animation.fast { + animation-duration: var(--mdb-animation-fast-duration) +} + +.animation.faster { + animation-duration: var(--mdb-animation-faster-duration) +} + +.animation.slow { + animation-duration: var(--mdb-animation-slow-duration) +} + +.animation.slower { + animation-duration: var(--mdb-animation-slower-duration) +} + +@keyframes fade-in-down { + 0% { + opacity: 0; + transform: var(--mdb-animation-fade-in-down-transform-from) + } + + to { + opacity: 1; + transform: var(--mdb-animation-fade-in-down-transform-to) + } +} + +.fade-in-down { + --mdb-animation-fade-in-down-transform-from: translate3d(0,-100%,0); + --mdb-animation-fade-in-down-transform-to: translate3d(0,0,0); + animation-name: fade-in-down +} + +@keyframes fade-in-left { + 0% { + opacity: 0; + transform: var(--mdb-animation-fade-in-left-transform-from) + } + + to { + opacity: 1; + transform: var(--mdb-animation-fade-in-left-transform-to) + } +} + +.fade-in-left { + --mdb-animation-fade-in-left-transform-from: translate3d(-100%,0,0); + --mdb-animation-fade-in-left-transform-to: translate3d(0,0,0); + animation-name: fade-in-left +} + +@keyframes fade-in-right { + 0% { + opacity: 0; + transform: var(--mdb-animation-fade-in-right-transform-from) + } + + to { + opacity: 1; + transform: var(--mdb-animation-fade-in-right-transform-to) + } +} + +.fade-in-right { + --mdb-animation-fade-in-right-transform-from: translate3d(100%,0,0); + --mdb-animation-fade-in-right-transform-to: translate3d(0,0,0); + animation-name: fade-in-right +} + +@keyframes fade-in-up { + 0% { + opacity: 0; + transform: var(--mdb-animation-fade-in-up-transform-from) + } + + to { + opacity: 1; + transform: var(--mdb-animation-fade-in-up-transform-to) + } +} + +.fade-in-up { + --mdb-animation-fade-in-up-transform-from: translate3d(0,100%,0); + --mdb-animation-fade-in-up-transform-to: translate3d(0,0,0); + animation-name: fade-in-up +} + +@keyframes fade-out-down { + 0% { + opacity: 1 + } + + to { + opacity: 0; + transform: var(--mdb-animation-fade-out-down-transform-to) + } +} + +.fade-out-down { + --mdb-animation-fade-out-down-transform-to: translate3d(0,100%,0); + animation-name: fade-out-down +} + +@keyframes fade-out-left { + 0% { + opacity: 1 + } + + to { + opacity: 0; + transform: var(--mdb-animation-fade-out-left-transform-to) + } +} + +.fade-out-left { + --mdb-animation-fade-out-left-transform-to: translate3d(-100%,0,0); + animation-name: fade-out-left +} + +@keyframes fade-out-right { + 0% { + opacity: 1 + } + + to { + opacity: 0; + transform: var(--mdb-animation-fade-out-right-transform-to) + } +} + +.fade-out-right { + --mdb-animation-fade-out-right-transform-to: translate3d(100%,0,0); + animation-name: fade-out-right +} + +@keyframes fade-out-up { + 0% { + opacity: 1 + } + + to { + opacity: 0; + transform: var(--mdb-animation-fade-out-up-transform-to) + } +} + +.fade-out-up { + --mdb-animation-fade-out-up-transform-to: translate3d(0,-100%,0); + animation-name: fade-out-up +} + +@keyframes slide-in-down { + 0% { + visibility: visible; + transform: var(--mdb-animation-slide-in-down-transform-from) + } + + to { + transform: var(--mdb-animation-slide-in-down-transform-to) + } +} + +.slide-in-down { + --mdb-animation-slide-in-down-transform-from: translate3d(0,-100%,0); + --mdb-animation-slide-in-down-transform-to: translate3d(0,0,0); + animation-name: slide-in-down +} + +@keyframes slide-in-left { + 0% { + visibility: visible; + transform: var(--mdb-animation-slide-in-left-transform-from) + } + + to { + transform: var(--mdb-animation-slide-in-left-transform-to) + } +} + +.slide-in-left { + --mdb-animation-slide-in-left-transform-from: translate3d(-100%,0,0); + --mdb-animation-slide-in-left-transform-to: translate3d(0,0,0); + animation-name: slide-in-left +} + +@keyframes slide-in-right { + 0% { + visibility: visible; + transform: var(--mdb-animation-slide-in-right-transform-from) + } + + to { + transform: var(--mdb-animation-slide-in-right-transform-to) + } +} + +.slide-in-right { + --mdb-animation-slide-in-right-transform-from: translate3d(100%,0,0); + --mdb-animation-slide-in-right-transform-to: translate3d(0,0,0); + animation-name: slide-in-right +} + +@keyframes slide-in-up { + 0% { + visibility: visible; + transform: var(--mdb-animation-slide-in-up-transform-from) + } + + to { + transform: var(--mdb-animation-slide-in-up-transform-to) + } +} + +.slide-in-up { + --mdb-animation-slide-in-up-transform-from: translate3d(0,100%,0); + --mdb-animation-slide-in-up-transform-to: translate3d(0,0,0); + animation-name: slide-in-up +} + +@keyframes slide-out-down { + 0% { + transform: var(--mdb-animation-slide-out-down-transform-from) + } + + to { + visibility: hidden; + transform: var(--mdb-animation-slide-out-down-transform-to) + } +} + +.slide-out-down { + --mdb-animation-slide-out-down-transform-from: translate3d(0,0,0); + --mdb-animation-slide-out-down-transform-to: translate3d(0,100%,0); + animation-name: slide-out-down +} + +@keyframes slide-out-left { + 0% { + transform: var(--mdb-animation-slide-out-left-transform-from) + } + + to { + visibility: hidden; + transform: var(--mdb-animation-slide-out-left-transform-to) + } +} + +.slide-out-left { + --mdb-animation-slide-out-left-transform-from: translate3d(0,0,0); + --mdb-animation-slide-out-left-transform-to: translate3d(-100%,0,0); + animation-name: slide-out-left +} + +@keyframes slide-out-right { + 0% { + transform: var(--mdb-animation-slide-out-right-transform-from) + } + + to { + visibility: hidden; + transform: var(--mdb-animation-slide-out-right-transform-to) + } +} + +.slide-out-right { + --mdb-animation-slide-out-right-transform-from: translate3d(0,0,0); + --mdb-animation-slide-out-right-transform-to: translate3d(100%,0,0); + animation-name: slide-out-right +} + +@keyframes slide-out-up { + 0% { + transform: var(--mdb-animation-slide-out-up-transform-from) + } + + to { + visibility: hidden; + transform: var(--mdb-animation-slide-out-up-transform-to) + } +} + +.slide-out-up { + --mdb-animation-slide-out-up-transform-from: translate3d(0,0,0); + --mdb-animation-slide-out-up-transform-to: translate3d(0,-100%,0); + animation-name: slide-out-up +} + +@keyframes slide-down { + 0% { + transform: var(--mdb-animation-slide-down-transform-from) + } + + to { + transform: var(--mdb-animation-slide-down-transform-to) + } +} + +.slide-down { + --mdb-animation-slide-down-transform-from: translate3d(0,0,0); + --mdb-animation-slide-down-transform-to: translate3d(0,100%,0); + animation-name: slide-down +} + +@keyframes slide-left { + 0% { + transform: var(--mdb-animation-slide-left-transform-from) + } + + to { + transform: var(--mdb-animation-slide-left-transform-to) + } +} + +.slide-left { + --mdb-animation-slide-left-transform-from: translate3d(0,0,0); + --mdb-animation-slide-left-transform-to: translate3d(-100%,0,0); + animation-name: slide-left +} + +@keyframes slide-right { + 0% { + transform: var(--mdb-animation-slide-right-transform-from) + } + + to { + transform: var(--mdb-animation-slide-right-transform-to) + } +} + +.slide-right { + --mdb-animation-slide-right-transform-from: translate3d(0,0,0); + --mdb-animation-slide-right-transform-to: translate3d(100%,0,0); + animation-name: slide-right +} + +@keyframes slide-up { + 0% { + transform: var(--mdb-animation-slide-up-transform-from) + } + + to { + transform: var(--mdb-animation-slide-up-transform-to) + } +} + +.slide-up { + --mdb-animation-slide-up-transform-from: translate3d(0,0,0); + --mdb-animation-slide-up-transform-to: translate3d(0,-100%,0); + animation-name: slide-up +} + +@keyframes zoom-in { + 0% { + opacity: 0; + transform: var(--mdb-animation-zoom-in-transform-from) + } + + 50% { + opacity: 1 + } +} + +.zoom-in { + --mdb-animation-zoom-in-transform-from: scale3d(0.3,0.3,0.3); + animation-name: zoom-in +} + +@keyframes zoom-out { + 0% { + opacity: 1 + } + + 50% { + opacity: 0; + transform: var(--mdb-animation-zoom-out-transform-50) + } + + to { + opacity: 0 + } +} + +.zoom-out { + --mdb-animation-zoom-out-transform-50: scale3d(0.3,0.3,0.3); + animation-name: zoom-out +} + +@keyframes tada { + 0% { + transform: var(--mdb-animation-tada-transform-from) + } + + 10%,20% { + transform: var(--mdb-animation-tada-transform-20) + } + + 30%,50%,70%,90% { + transform: var(--mdb-animation-tada-transform-90) + } + + 40%,60%,80% { + transform: var(--mdb-animation-tada-transform-80) + } + + to { + transform: var(--mdb-animation-tada-transform-to) + } +} + +.tada { + --mdb-animation-tada-transform-from: scale3d(1,1,1); + --mdb-animation-tada-transform-20: scale3d(0.9,0.9,0.9) rotate3d(0,0,1,-3deg); + --mdb-animation-tada-transform-90: scale3d(1.1,1.1,1.1) rotate3d(0,0,1,3deg); + --mdb-animation-tada-transform-80: scale3d(1.1,1.1,1.1) rotate3d(0,0,1,-3deg); + --mdb-animation-tada-transform-to: scale3d(1,1,1); + animation-name: tada +} + +@keyframes pulse { + 0% { + transform: var(--mdb-animation-pulse-transform-from) + } + + 50% { + transform: var(--mdb-animation-pulse-transform-50) + } + + to { + transform: var(--mdb-animation-pulse-transform-to) + } +} + +.pulse { + --mdb-animation-pulse-transform-from: scale3d(1,1,1); + --mdb-animation-pulse-transform-50: scale3d(1.05,1.05,1.05); + --mdb-animation-pulse-transform-to: scale3d(1,1,1); + animation-name: pulse +} + +.stepper,.steps,.timeline { + --mdb-steps-transition: height 0.2s ease-in-out; + position: relative; + padding: 0; + margin: 0; + width: 100%; + list-style: none; + overflow: hidden; + transition: var(--mdb-steps-transition) +} + +.stepper-vertical .stepper-step,.steps-step,.timeline-step { + --mdb-steps-step-after-left: 2.45rem; + --mdb-steps-step-after-width: 1px; + --mdb-steps-step-after-margin-top: 0.5rem; + --mdb-steps-step-after-bg: #dfdfdf; + height: -webkit-fit-content; + height: -moz-fit-content; + height: fit-content; + position: relative +} + +.stepper-vertical .stepper-step:not(:last-child):after,.steps-step-after,.timeline-step:after { + position: absolute; + left: var(--mdb-steps-step-after-left); + width: var(--mdb-steps-step-after-width); + margin-top: var(--mdb-steps-step-after-margin-top); + content: ""; + background-color: var(--mdb-steps-step-after-bg) +} + +.stepper-vertical .stepper-content,.steps-content,.timeline-content { + --mdb-steps-content-padding-y: 1.5rem; + overflow: hidden; + padding-top: 0; + padding-bottom: var(--mdb-steps-content-padding-y); + padding-right: var(--mdb-steps-content-padding-y) +} + +.stepper-vertical .stepper-head,.steps-head-vertical,.timeline-head { + --mdb-steps-head-vertical-padding-top: 1.5rem; + --mdb-steps-head-vertical-padding-x: 1.5rem; + padding-left: var(--mdb-steps-head-vertical-padding-x); + padding-right: var(--mdb-steps-head-vertical-padding-x); + padding-top: var(--mdb-steps-head-vertical-padding-top) +} + +.stepper-vertical .stepper-head-icon,.steps-head-icon-vertical,.timeline-head-icon { + --mdb-steps-head-icon-vertical-margin-right: 0.75rem; + margin-right: var(--mdb-steps-head-icon-vertical-margin-right) +} + +.stepper-vertical .stepper-head-text:after,.steps-head-text-after-vertical { + position: absolute +} + +.stepper-head,.steps-head,.timeline-head { + --mdb-steps-head-line-height: 1.3; + --mdb-steps-head-hover-bgc: rgba(0,0,0,0.025); + display: flex; + align-items: center; + text-decoration: none; + color: unset; + line-height: var(--mdb-steps-head-line-height) +} + +.stepper-head:hover,.steps-head-hover { + background-color: var(--mdb-steps-head-hover-bgc) +} + +.stepper-head:focus,.steps-head-focus { + outline: none +} + +.stepper-head-text,.steps-head-text,.timeline-head-text { + --mdb-steps-head-text-color: #757575; + --mdb-steps-head-text-after-font-size: 0.8rem; + color: var(--mdb-steps-head-text-color) +} + +.stepper-head-text:after,.steps-head-text-after,.timeline-head-text:after { + display: flex; + font-size: var(--mdb-steps-head-text-after-font-size); + content: attr(data-content) +} + +.stepper-head-icon,.steps-head-icon,.timeline-head-icon { + --mdb-steps-head-icon-font-size: 0.875rem; + --mdb-steps-head-icon-width: 1.938rem; + --mdb-steps-head-icon-height: 1.938rem; + --mdb-steps-head-icon-font-weight: 500; + display: flex; + justify-content: center; + align-items: center; + border-radius: 100%; + font-size: var(--mdb-steps-head-icon-font-size); + width: var(--mdb-steps-head-icon-width); + height: var(--mdb-steps-head-icon-height); + font-weight: var(--mdb-steps-head-icon-font-weight) +} + +.stepper-active .stepper-head-text,.steps-active-head-text,.timeline-head-text { + --mdb-steps-active-head-text-font-weight: 500; + font-weight: var(--mdb-steps-active-head-text-font-weight) +} + +.stepper { + --mdb-stepper-padding-x: 1rem; + --mdb-stepper-step-height: 4.5rem; + --mdb-stepper-step-head-padding-left: 1.5rem; + --mdb-stepper-step-head-padding-right: 1.5rem; + --mdb-stepper-step-head-height: 1px; + --mdb-stepper-step-head-bg: rgba(0,0,0,0.1); + --mdb-stepper-step-head-margin-right: 0.5rem; + --mdb-stepper-step-head-margin-left: 0.5rem; + --mdb-stepper-head-icon-margin-y: 1.5rem; + --mdb-stepper-head-icon-margin-right: 0.5rem; + --mdb-stepper-vertical-step-top: 3.25rem; + --mdb-stepper-vertical-step-height: calc(100% - 2.45rem); + --mdb-stepper-vertical-content-padding-left: 3.75rem; + --mdb-stepper-vertical-content-transition: height 0.3s ease-in-out,margin-top 0.3s ease-in-out,margin-bottom 0.3s ease-in-out,padding-top 0.3s ease-in-out,padding-bottom 0.3s ease-in-out; + --mdb-stepper-vertical-head-padding-bottom: 1.5rem; + --mdb-stepper-mobile-step-margin-y: 1rem; + --mdb-stepper-mobile-step-head-padding-x: 0.25rem; + --mdb-stepper-mobile-head-icon-height: 0.5rem; + --mdb-stepper-mobile-head-icon-width: 0.5rem; + --mdb-stepper-mobile-content-top: 2.56rem; + --mdb-stepper-mobile-active-head-icon-bg: #376fc8; + --mdb-stepper-mobile-completed-head-icon-bg: #139647; + --mdb-stepper-head-icon-bg: #ebedef; + --mdb-stepper-head-icon-color: #40464f; + --mdb-stepper-completed-head-icon-bg: #d6f0e0; + --mdb-stepper-completed-head-icon-color: #0d6832; + --mdb-stepper-active-head-icon-bg: #dfe7f6; + --mdb-stepper-active-head-icon-color: #2c58a0; + --mdb-stepper-invalid-head-icon-bg: #f9e1e5; + --mdb-stepper-invalid-head-icon-color: #af233a; + --mdb-stepper-disabled-head-color: grey; + --mdb-stepper-disabled-head-icon-bg: #e6e6e6; + --mdb-stepper-disabled-head-icon-color: grey; + --mdb-stepper-mobile-head-padding-y: 0.5rem; + --mdb-stepper-mobile-head-padding-x: 1rem; + --mdb-stepper-mobile-footer-height: 2.5rem; + --mdb-stepper-back-btn-i-margin-right: 0.5rem; + --mdb-stepper-next-btn-i-margin-left: 0.5rem; + --mdb-stepper-mobile-progress-bar-height: 0.3rem; + --mdb-stepper-mobile-progress-height: 0.3rem; + --mdb-stepper-mobile-progress-background-color: #e0e0e0 +} + +.stepper:not(.stepper-vertical) { + display: flex; + justify-content: space-between +} + +.stepper:not(.stepper-vertical) .stepper-content { + position: absolute; + width: 100%; + padding-right: var(--mdb-stepper-padding-x); + padding-left: var(--mdb-stepper-padding-x) +} + +.stepper:not(.stepper-vertical) .stepper-step { + flex: auto; + height: var(--mdb-stepper-step-height) +} + +.stepper:not(.stepper-vertical) .stepper-step:first-child .stepper-head { + padding-left: var(--mdb-stepper-step-head-padding-left) +} + +.stepper:not(.stepper-vertical) .stepper-step:last-child .stepper-head { + padding-right: var(--mdb-stepper-step-head-padding-right) +} + +.stepper:not(.stepper-vertical) .stepper-step:not(:first-child) .stepper-head:before { + flex: 1; + height: var(--mdb-stepper-step-head-height); + width: 100%; + margin-right: var(--mdb-stepper-step-head-margin-right); + content: ""; + background-color: var(--mdb-stepper-step-head-bg) +} + +.stepper:not(.stepper-vertical) .stepper-step:not(:last-child) .stepper-head:after { + flex: 1; + height: var(--mdb-stepper-step-head-height); + width: 100%; + margin-left: var(--mdb-stepper-step-head-margin-left); + content: ""; + background-color: var(--mdb-stepper-step-head-bg) +} + +.stepper:not(.stepper-vertical) .stepper-head-icon { + margin-top: var(--mdb-stepper-head-icon-margin-y); + margin-right: var(--mdb-stepper-head-icon-margin-right); + margin-bottom: var(--mdb-stepper-head-icon-margin-y); + margin-left: 0 +} + +.stepper-vertical .stepper-step:not(:last-child):after { + top: var(--mdb-stepper-vertical-step-top); + height: var(--mdb-stepper-vertical-step-height) +} + +.stepper-vertical .stepper-content { + padding-left: var(--mdb-stepper-vertical-content-padding-left); + transition: var(--mdb-stepper-vertical-content-transition) +} + +.stepper-vertical .stepper-content-hide { + margin-top: 0!important; + margin-bottom: 0!important; + padding-top: 0!important; + padding-bottom: 0!important; + height: 0!important +} + +.stepper-vertical .stepper-head { + padding-bottom: var(--mdb-stepper-vertical-head-padding-bottom) +} + +.stepper.stepper-mobile { + justify-content: center; + align-items: flex-end +} + +.stepper.stepper-mobile.stepper-progress-bar .stepper-head-icon { + display: none +} + +.stepper.stepper-mobile .stepper-step { + flex: unset; + height: -webkit-fit-content; + height: -moz-fit-content; + height: fit-content; + margin-top: var(--mdb-stepper-mobile-step-margin-y); + margin-bottom: var(--mdb-stepper-mobile-step-margin-y) +} + +.stepper.stepper-mobile .stepper-step:not(:last-child) .stepper-head:after { + margin-left: 0 +} + +.stepper.stepper-mobile .stepper-step:not(:first-child) .stepper-head:before { + margin-right: 0 +} + +.stepper.stepper-mobile .stepper-step:not(:last-child):not(:first-child) .stepper-head { + padding-left: var(--mdb-stepper-mobile-step-head-padding-x); + padding-right: var(--mdb-stepper-mobile-step-head-padding-x) +} + +.stepper.stepper-mobile .stepper-head-icon { + font-size: 0; + margin: 0; + height: var(--mdb-stepper-mobile-head-icon-height); + width: var(--mdb-stepper-mobile-head-icon-width); + z-index: 1 +} + +.stepper.stepper-mobile .stepper-head-text { + display: none +} + +.stepper.stepper-mobile .stepper-content { + top: var(--mdb-stepper-mobile-content-top) +} + +.stepper.stepper-mobile .stepper-active .stepper-head-icon { + background-color: var(--mdb-stepper-mobile-active-head-icon-bg) +} + +.stepper.stepper-mobile .stepper-completed .stepper-head-icon { + background-color: var(--mdb-stepper-mobile-completed-head-icon-bg) +} + +.stepper-form { + display: inherit; + justify-content: inherit; + width: inherit; + position: inherit +} + +.stepper-content { + left: 0 +} + +.stepper-head { + cursor: pointer +} + +.stepper-head-icon { + background-color: var(--mdb-stepper-head-icon-bg); + color: var(--mdb-stepper-head-icon-color) +} + +.stepper-completed .stepper-head-icon { + background-color: var(--mdb-stepper-completed-head-icon-bg); + color: var(--mdb-stepper-completed-head-icon-color) +} + +.stepper-active .stepper-content { + display: block +} + +.stepper-active .stepper-head-icon { + background-color: var(--mdb-stepper-active-head-icon-bg); + color: var(--mdb-stepper-active-head-icon-color) +} + +.stepper-invalid .stepper-head-icon { + background-color: var(--mdb-stepper-invalid-head-icon-bg); + color: var(--mdb-stepper-invalid-head-icon-color) +} + +.stepper-disabled .stepper-head { + color: var(--mdb-stepper-disabled-head-color); + cursor: default +} + +.stepper-disabled .stepper-head-icon { + background-color: var(--mdb-stepper-disabled-head-icon-bg); + color: var(--mdb-stepper-disabled-head-icon-color) +} + +.stepper-mobile-head { + position: absolute; + align-self: normal; + height: -webkit-fit-content; + height: -moz-fit-content; + height: fit-content; + width: 100%; + padding: var(--mdb-stepper-mobile-head-padding-y) var(--mdb-stepper-mobile-head-padding-x) +} + +.stepper-mobile-footer { + position: absolute; + display: flex; + justify-content: space-between; + align-items: center; + width: 100%; + height: var(--mdb-stepper-mobile-footer-height) +} + +.stepper-back-btn { + display: block; + left: 0 +} + +.stepper-back-btn .btn-link { + color: unset +} + +.stepper-back-btn i { + margin-right: var(--mdb-stepper-back-btn-i-margin-right) +} + +.stepper-next-btn { + display: block; + right: 0 +} + +.stepper-next-btn .btn-link { + color: unset +} + +.stepper-next-btn i { + margin-left: var(--mdb-stepper-next-btn-i-margin-left) +} + +.stepper-mobile-progress-bar { + height: var(--mdb-stepper-mobile-progress-bar-height); + width: 0 +} + +.stepper-mobile-progress { + height: var(--mdb-stepper-mobile-progress-height); + flex-grow: 100; + background-color: var(--mdb-stepper-mobile-progress-background-color) +} + +.timeline { + --mdb-timeline-step-top: 2.94rem; + --mdb-timeline-step-height: calc(100% - 1.94rem); + --mdb-timeline-content-padding-left: 4.25rem; + --mdb-timeline-head-padding-bottom: 0.5rem; + --mdb-timeline-step-sm-left: 1.8rem; + --mdb-timeline-step-sm-top: 2rem; + --mdb-timeline-head-sm-margin-right: 1rem; + --mdb-timeline-head-sm-bg: #dfdfdf; + --mdb-timeline-head-sm-height: 0.7rem; + --mdb-timeline-head-sm-width: 0.7rem; + --mdb-timeline-content-sm-padding-left: 3.25rem +} + +.timeline-step:after { + top: var(--mdb-timeline-step-top); + height: var(--mdb-timeline-step-height) +} + +.timeline-content { + padding-left: var(--mdb-timeline-content-padding-left) +} + +.timeline-head { + padding-bottom: var(--mdb-timeline-head-padding-bottom) +} + +.timeline-step-sm:after { + left: var(--mdb-timeline-step-sm-left); + height: 100%; + top: var(--mdb-timeline-step-sm-top) +} + +.timeline-head-sm { + margin-right: var(--mdb-timeline-head-sm-margin-right); + background-color: var(--mdb-timeline-head-sm-bg); + border-radius: 100%; + height: var(--mdb-timeline-head-sm-height); + width: var(--mdb-timeline-head-sm-width) +} + +.timeline-content-sm { + padding-left: var(--mdb-timeline-content-sm-padding-left) +} + +.select-dropdown .form-check-input label { + display: block +} + +select.select-initialized { + display: none!important +} + +.select-wrapper { + --mdb-form-outline-select-arrow-color: #000; + --mdb-form-outline-select-arrow-font-size: 16px; + --mdb-form-outline-select-arrow-top: 7px; + --mdb-form-outline-select-arrow-right: 16px; + --mdb-form-outline-select-valid-color: #00b74a; + --mdb-form-outline-select-invalid-color: #f93154; + --mdb-form-outline-select-clear-btn-color: #000; + --mdb-form-outline-select-clear-btn-font-size: 1rem; + --mdb-form-outline-select-clear-btn-top: 7px; + --mdb-form-outline-select-clear-btn-right: 27px; + --mdb-form-outline-select-clear-btn-focus-color: #3b71ca; + --mdb-form-outline-select-sm-clear-btn-font-size: 0.8rem; + --mdb-form-outline-select-sm-clear-btn-top: 4px; + --mdb-form-outline-select-lg-clear-btn-top: 11px; + --mdb-form-outline-select-label-max-width: 80%; + --mdb-form-outline-select-label-active-transform: translateY(-1rem) translateY(0.1rem) scale(0.8); + --mdb-form-outline-select-lg-label-active-transform: translateY(-1.25rem) translateY(0.1rem) scale(0.8); + --mdb-form-outline-select-sm-label-active-transform: translateY(-0.83rem) translateY(0.1rem) scale(0.8); + --mdb-form-outline-select-input-focused-color: #616161; + --mdb-form-outline-select-label-color: #3b71ca; + --mdb-form-outline-select-notch-border-color: #3b71ca; + --mdb-form-outline-select-white-notch-border-color: #fff; + --mdb-form-outline-select-input-focused-arrow-color: #3b71ca; + --mdb-form-outline-select-white-focus-arrow-color: #fff; + --mdb-form-outline-select-white-arrow-color: #fff; + --mdb-form-outline-select-white-clear-btn: #fff; + --mdb-form-outline-select-sm-arrow-top: 3px; + --mdb-form-outline-select-lg-arrow-top: 11px; + --mdb-form-outline-form-notch-border-top: 1px solid transparent +} + +.select-arrow { + color: var(--mdb-form-outline-select-arrow-color); + text-align: center; + font-size: var(--mdb-form-outline-select-arrow-font-size); + position: absolute; + top: var(--mdb-form-outline-select-arrow-top); + right: var(--mdb-form-outline-select-arrow-right) +} + +.select-arrow:after { + display: inline-block; + margin-left: .255em; + vertical-align: .255em; + content: ""; + border-top: .3em solid; + border-right: .3em solid transparent; + border-bottom: 0; + border-left: .3em solid transparent +} + +.select-arrow:empty:after { + margin-left: 0 +} + +.was-validated .form-control:valid~.select-arrow { + color: var(--mdb-form-outline-select-valid-color) +} + +.was-validated .form-control:invalid~.select-arrow { + color: var(--mdb-form-outline-select-invalid-color) +} + +.select-clear-btn { + color: var(--mdb-form-outline-select-clear-btn-color); + font-size: var(--mdb-form-outline-select-clear-btn-font-size); + position: absolute; + top: var(--mdb-form-outline-select-clear-btn-top); + right: var(--mdb-form-outline-select-clear-btn-right); + cursor: pointer +} + +.select-clear-btn:focus { + color: var(--mdb-form-outline-select-clear-btn-focus-color); + outline: none +} + +.form-control-sm~.select-clear-btn { + font-size: var(--mdb-form-outline-select-sm-clear-btn-font-size); + top: var(--mdb-form-outline-select-sm-clear-btn-top) +} + +.form-control-lg~.select-clear-btn { + top: var(--mdb-form-outline-select-lg-clear-btn-top) +} + +.select-dropdown-container { + --mdb-form-outline-select-dropdown-container-z-index: 1070; + --mdb-form-outline-select-dropdown-bg: #fff; + --mdb-form-outline-select-dropdown-box-shadow: 0 2px 5px 0 rgba(0,0,0,0.16),0 2px 10px 0 rgba(0,0,0,0.12); + --mdb-form-outline-select-dropdown-min-width: 100px; + --mdb-form-outline-select-dropdown-transform: scaleY(0.8); + --mdb-form-outline-select-dropdown-transition: all 0.2s; + --mdb-form-outline-select-dropdown-open-transform: scaleY(1); + --mdb-form-outline-select-dropdown-input-group-padding: 10px; + --mdb-form-outline-select-options-wrapper-scrollbar-width: 4px; + --mdb-form-outline-select-options-wrapper-scrollbar-height: 4px; + --mdb-form-outline-select-options-wrapper-scrollbar-border-bottom-right-radius: 4px; + --mdb-form-outline-select-options-wrapper-scrollbar-border-bottom-left-radius: 4px; + --mdb-form-outline-select-options-wrapper-scrollbar-thumb-height: 50px; + --mdb-form-outline-select-options-wrapper-scrollbar-thumb-bg: #999; + --mdb-form-outline-select-options-wrapper-scrollbar-thumb-border-radius: 4px; + --mdb-form-outline-select-no-results-padding-left: 16px; + --mdb-form-outline-select-no-results-padding-right: 16px; + z-index: var(--mdb-form-outline-select-dropdown-container-z-index) +} + +.select-dropdown { + background-color: var(--mdb-form-outline-select-dropdown-bg); + box-shadow: var(--mdb-form-outline-select-dropdown-box-shadow); + margin: 0; + min-width: var(--mdb-form-outline-select-dropdown-min-width); + outline: 0; + position: relative; + transform: var(--mdb-form-outline-select-dropdown-transform); + opacity: 0; + transition: var(--mdb-form-outline-select-dropdown-transition) +} + +.select-dropdown.open { + transform: var(--mdb-form-outline-select-dropdown-open-transform); + opacity: 1 +} + +.select-dropdown>.input-group { + padding: var(--mdb-form-outline-select-dropdown-input-group-padding) +} + +.select-label { + max-width: var(--mdb-form-outline-select-label-max-width); + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap +} + +.select-label.active { + transform: var(--mdb-form-outline-select-label-active-transform) +} + +.form-control-lg~.select-label.active { + transform: var(--mdb-form-outline-select-lg-label-active-transform) +} + +.form-control-sm~.select-label.active { + transform: var(--mdb-form-outline-select-sm-label-active-transform) +} + +.form-outline .select-label.active~.form-notch .form-notch-middle { + border-right: none; + border-left: none; + border-top: var(--mdb-form-outline-form-notch-border-top) +} + +.select-input { + cursor: pointer +} + +.select-input[disabled] { + cursor: default +} + +.form-outline .form-control.select-input:focus,.select-input.focused { + color: var(--mdb-form-outline-select-input-focused-color); + outline: 0 +} + +.form-outline .form-control.select-input:focus~.select-label,.select-input.focused~.select-label { + color: var(--mdb-form-outline-select-label-color) +} + +.form-outline .form-control.select-input:focus::-moz-placeholder,.select-input.focused::-moz-placeholder { + opacity: 1 +} + +.form-outline .form-control.select-input:focus::placeholder,.select-input.focused::placeholder { + opacity: 1 +} + +.form-outline .form-control.select-input:focus~.form-notch .form-notch-leading,.select-input.focused~.form-notch .form-notch-leading { + border-color: var(--mdb-form-outline-select-notch-border-color); + box-shadow: -1px 0 0 0 var(--mdb-form-outline-select-notch-border-color),0 1px 0 0 var(--mdb-form-outline-select-notch-border-color),0 -1px 0 0 var(--mdb-form-outline-select-notch-border-color) +} + +.form-outline .form-control.select-input:focus~.form-notch .form-notch-trailing,.select-input.focused~.form-notch .form-notch-trailing { + border-color: var(--mdb-form-outline-select-notch-border-color); + box-shadow: 1px 0 0 0 var(--mdb-form-outline-select-notch-border-color),0 -1px 0 0 var(--mdb-form-outline-select-notch-border-color),0 1px 0 0 var(--mdb-form-outline-select-notch-border-color) +} + +.select-input.focused~.form-notch .form-notch-middle { + border-top: var(--mdb-form-outline-form-notch-border-top); + border-color: var(--mdb-form-outline-select-notch-border-color); + box-shadow: 0 1px 0 0 var(--mdb-form-outline-select-notch-border-color) +} + +.select-input.focused~.select-arrow { + color: var(--mdb-form-outline-select-input-focused-arrow-color) +} + +.form-control-sm~.select-arrow { + top: var(--mdb-form-outline-select-sm-arrow-top) +} + +.form-control-lg~.select-arrow { + top: var(--mdb-form-outline-select-lg-arrow-top) +} + +.select-options-wrapper { + overflow-y: auto +} + +.select-options-wrapper::-webkit-scrollbar { + width: var(--mdb-form-outline-select-options-wrapper-scrollbar-width); + height: var(--mdb-form-outline-select-options-wrapper-scrollbar-height) +} + +.select-options-wrapper::-webkit-scrollbar-button:end:increment,.select-options-wrapper::-webkit-scrollbar-button:start:decrement { + display: block; + height: 0; + background-color: transparent +} + +.select-options-wrapper::-webkit-scrollbar-track-piece { + background-color: transparent; + border-radius: 0; + border-bottom-right-radius: var(--mdb-form-outline-select-options-wrapper-scrollbar-border-bottom-right-radius); + border-bottom-left-radius: var(--mdb-form-outline-select-options-wrapper-scrollbar-border-bottom-left-radius) +} + +.select-options-wrapper::-webkit-scrollbar-thumb:vertical { + height: var(--mdb-form-outline-select-options-wrapper-scrollbar-thumb-height); + background-color: var(--mdb-form-outline-select-options-wrapper-scrollbar-thumb-bg); + border-radius: var(--mdb-form-outline-select-options-wrapper-scrollbar-thumb-border-radius) +} + +.select-options-list { + list-style: none; + margin: 0; + padding: 0 +} + +.select-option-group-label { + --mdb-form-outline-select-option-group-label-padding-left: 16px; + --mdb-form-outline-select-option-group-label-padding-right: 16px; + --mdb-form-outline-select-option-group-label-font-size: 1rem; + --mdb-form-outline-select-option-group-label-font-weight: 400; + --mdb-form-outline-select-option-group-label-color: rgba(0,0,0,0.54); + width: 100%; + white-space: nowrap; + text-overflow: ellipsis; + overflow: hidden; + display: flex; + flex-direction: row; + align-items: center; + padding-left: var(--mdb-form-outline-select-option-group-label-padding-left); + padding-right: var(--mdb-form-outline-select-option-group-label-padding-right); + font-size: var(--mdb-form-outline-select-option-group-label-font-size); + font-weight: var(--mdb-form-outline-select-option-group-label-font-weight); + background-color: transparent; + color: var(--mdb-form-outline-select-option-group-label-color); + -webkit-user-select: none; + -moz-user-select: none; + user-select: none +} + +.select-option-group>.select-option { + --mdb-form-outline-select-option-group-select-option-padding-left: 26px; + padding-left: var(--mdb-form-outline-select-option-group-select-option-padding-left) +} + +.select-option { + --mdb-form-outline-select-option-color: rgba(0,0,0,0.87); + --mdb-form-outline-select-option-padding-left: 16px; + --mdb-form-outline-select-option-padding-right: 16px; + --mdb-form-outline-select-option-font-size: 1rem; + --mdb-form-outline-select-option-font-weight: 400; + --mdb-form-outline-select-option-hover-not-disabled-bg: rgba(0,0,0,0.048); + --mdb-form-outline-select-option-active-bg: rgba(0,0,0,0.048); + --mdb-form-outline-select-option-selected-active-bg: rgba(0,0,0,0.048); + --mdb-form-outline-select-option-selected-disabled-color: #9e9e9e; + --mdb-form-outline-select-option-selected-bg: rgba(0,0,0,0.02); + --mdb-form-outline-select-option-disabled-color: #9e9e9e; + --mdb-form-outline-select-option-text-form-check-input-margin-right: 10px; + --mdb-form-outline-select-option-secondary-text-font-size: 0.8rem; + --mdb-form-outline-select-option-secondary-text-color: #6c757d; + --mdb-form-outline-select-option-icon-width: 28px; + --mdb-form-outline-select-option-icon-height: 28px; + --mdb-form-outline-select-white-arrow: #fff; + width: 100%; + white-space: nowrap; + text-overflow: ellipsis; + overflow: hidden; + cursor: pointer; + display: flex; + flex-direction: row; + align-items: center; + justify-content: space-between; + color: var(--mdb-form-outline-select-option-color); + padding-left: var(--mdb-form-outline-select-option-padding-left); + padding-right: var(--mdb-form-outline-select-option-padding-right); + font-size: var(--mdb-form-outline-select-option-font-size); + font-weight: var(--mdb-form-outline-select-option-font-weight); + background-color: transparent; + -webkit-user-select: none; + -moz-user-select: none; + user-select: none +} + +.select-option:hover:not(.disabled) { + background-color: var(--mdb-form-outline-select-option-hover-not-disabled-bg) +} + +.select-option.active { + background-color: var(--mdb-form-outline-select-option-active-bg) +} + +.select-option.selected.active { + background-color: var(--mdb-form-outline-select-option-selected-active-bg) +} + +.select-option.selected.disabled { + cursor: default; + color: var(--mdb-form-outline-select-option-selected-disabled-color); + background-color: transparent +} + +.select-option.selected { + background-color: var(--mdb-form-outline-select-option-selected-bg) +} + +.select-option.disabled { + cursor: default; + color: var(--mdb-form-outline-select-option-disabled-color) +} + +.select-option-text .form-check-input { + margin-right: var(--mdb-form-outline-select-option-text-form-check-input-margin-right) +} + +.select-option-secondary-text { + font-size: var(--mdb-form-outline-select-option-secondary-text-font-size); + color: var(--mdb-form-outline-select-option-secondary-text-color); + display: block; + line-height: normal +} + +.select-option-icon { + width: var(--mdb-form-outline-select-option-icon-width); + height: var(--mdb-form-outline-select-option-icon-height) +} + +.select-custom-content { + --mdb-form-outline-select-custom-content-padding: 16px; + padding: var(--mdb-form-outline-select-custom-content-padding) +} + +.select-no-results { + padding-left: var(--mdb-form-outline-select-no-results-padding-left); + padding-right: var(--mdb-form-outline-select-no-results-padding-right); + display: flex; + align-items: center +} + +.form-white .select-input.focused~.select-arrow { + color: var(--mdb-form-outline-select-white-arrow-color) +} + +.form-white .select-input:focus~.select-arrow { + color: var(--mdb-form-outline-select-white-focus-arrow-color) +} + +.form-white .select-arrow { + color: var(--mdb-form-outline-select-white-arrow-color) +} + +.form-white .select-clear-btn { + color: var(--mdb-form-outline-select-white-clear-btn) +} + +.form-white .form-control.select-input:focus,.form-white .form-control.select-input:focus~.select-label,.form-white .select-input.focused,.form-white .select-input.focused~.select-label { + color: #fff +} + +.form-white .form-control.select-input:focus~.form-notch .form-notch-leading,.form-white .select-input.focused~.form-notch .form-notch-leading { + border-color: var(--mdb-form-outline-select-white-notch-border-color); + box-shadow: -1px 0 0 0 var(--mdb-form-outline-select-white-notch-border-color),0 1px 0 0 var(--mdb-form-outline-select-white-notch-border-color),0 -1px 0 0 var(--mdb-form-outline-select-white-notch-border-color) +} + +.form-white .form-control.select-input:focus~.form-notch .form-notch-trailing,.form-white .select-input.focused~.form-notch .form-notch-trailing { + border-color: var(--mdb-form-outline-select-white-notch-border-color); + box-shadow: 1px 0 0 0 var(--mdb-form-outline-select-white-notch-border-color),0 -1px 0 0 var(--mdb-form-outline-select-white-notch-border-color),0 1px 0 0 var(--mdb-form-outline-select-white-notch-border-color) +} + +.form-outline .form-control.active~.form-label.select-fake-value,.form-outline .form-control:focus~.form-label.select-fake-value,.form-outline .form-control~.form-label.select-fake-value { + transform: none; + display: none +} + +.form-outline .form-control.active~.form-label.select-fake-value.active,.form-outline .form-control:focus~.form-label.select-fake-value.active,.form-outline .form-control~.form-label.select-fake-value.active { + display: block +} + +code[class*=language-],pre[class*=language-] { + color: #000; + background: none; + text-shadow: 0 1px #fff; + font-family: Consolas,Monaco,Andale Mono,Ubuntu Mono,monospace; + text-align: left; + white-space: pre; + word-spacing: normal; + word-break: normal; + word-wrap: normal; + line-height: 1.5; + -moz-tab-size: 4; + -o-tab-size: 4; + tab-size: 4; + -webkit-hyphens: none; + hyphens: none +} + +code[class*=language-]::-moz-selection,code[class*=language-] ::-moz-selection,pre[class*=language-]::-moz-selection,pre[class*=language-] ::-moz-selection { + text-shadow: none; + background: #b3d4fc +} + +code[class*=language-]::selection,code[class*=language-] ::selection,pre[class*=language-]::selection,pre[class*=language-] ::selection { + text-shadow: none; + background: #b3d4fc +} + +@media print { + code[class*=language-],pre[class*=language-] { + text-shadow: none + } +} + +pre[class*=language-] { + padding: 1em; + margin: .5em 0; + overflow: auto +} + +:not(pre)>code[class*=language-],pre[class*=language-] { + background: #f5f2f0 +} + +:not(pre)>code[class*=language-] { + padding: .1em; + border-radius: .3em; + white-space: normal +} + +.token.cdata,.token.comment,.token.doctype,.token.prolog { + color: #708090 +} + +.token.punctuation { + color: #999 +} + +.namespace { + opacity: .7 +} + +.token.boolean,.token.constant,.token.deleted,.token.number,.token.property,.token.symbol,.token.tag { + color: #905 +} + +.token.attr-name,.token.builtin,.token.char,.token.inserted,.token.selector,.token.string { + color: #690 +} + +.language-css .token.string,.style .token.string,.token.entity,.token.operator,.token.url { + color: #9a6e3a; + background: hsla(0,0%,100%,.5) +} + +.token.atrule,.token.attr-value,.token.keyword { + color: #07a +} + +.token.class-name,.token.function { + color: #dd4a68 +} + +.token.important,.token.regex,.token.variable { + color: #e90 +} + +.token.bold,.token.important { + font-weight: 700 +} + +.token.italic { + font-style: italic +} + +.token.entity { + cursor: help +} + +pre.line-numbers { + padding-left: 3.8em +} + +.line-numbers .type-terminal .line-numbers-rows { + border-right: none; + top: -.2em +} + +.type-terminal .line-numbers-rows>span:before { + content: "$" +} + +.prism-previewer,.prism-previewer:after,.prism-previewer:before { + position: absolute; + pointer-events: none +} + +.prism-previewer,.prism-previewer:after { + left: 50% +} + +.prism-previewer { + margin-top: -48px; + width: 32px; + height: 32px; + margin-left: -16px; + opacity: 0; + transition: opacity .25s +} + +.prism-previewer.flipped { + margin-top: 0; + margin-bottom: -48px +} + +.prism-previewer:after,.prism-previewer:before { + content: ""; + position: absolute; + pointer-events: none +} + +.prism-previewer:before { + top: -5px; + right: -5px; + left: -5px; + bottom: -5px; + border-radius: 10px; + border: 5px solid #fff; + box-shadow: inset 0 0 3px rgba(0,0,0,.5),0 0 10px rgba(0,0,0,.75) +} + +.prism-previewer:after { + top: 100%; + width: 0; + height: 0; + margin: 5px 0 0 -7px; + border: 7px solid rgba(255,0,0,0); + border-top-color: #fff +} + +.prism-previewer.flipped:after { + top: auto; + bottom: 100%; + margin-top: 0; + margin-bottom: 5px; + border-top-color: rgba(255,0,0,0); + border-bottom-color: #fff +} + +.prism-previewer.active { + opacity: 1 +} + +.prism-previewer-angle:before { + border-radius: 50%; + background: #fff +} + +.prism-previewer-angle:after { + margin-top: 4px +} + +.prism-previewer-angle svg { + width: 32px; + height: 32px; + transform: rotate(-90deg) +} + +.prism-previewer-angle[data-negative] svg { + transform: scaleX(-1) rotate(-90deg) +} + +.prism-previewer-angle circle { + fill: transparent; + stroke: #2e3538; + stroke-opacity: .9; + stroke-width: 32; + stroke-dasharray: 0,500 +} + +.prism-previewer-gradient { + background-image: linear-gradient(45deg,#bbb 25%,transparent 0,transparent 75%,#bbb 0,#bbb),linear-gradient(45deg,#bbb 25%,#eee 0,#eee 75%,#bbb 0,#bbb); + background-size: 10px 10px; + background-position: 0 0,5px 5px; + width: 64px; + margin-left: -32px +} + +.prism-previewer-gradient:before { + content: none +} + +.prism-previewer-gradient div { + position: absolute; + top: -5px; + left: -5px; + right: -5px; + bottom: -5px; + border-radius: 10px; + border: 5px solid #fff; + box-shadow: inset 0 0 3px rgba(0,0,0,.5),0 0 10px rgba(0,0,0,.75) +} + +.prism-previewer-color { + background-image: linear-gradient(45deg,#bbb 25%,transparent 0,transparent 75%,#bbb 0,#bbb),linear-gradient(45deg,#bbb 25%,#eee 0,#eee 75%,#bbb 0,#bbb); + background-size: 10px 10px; + background-position: 0 0,5px 5px +} + +.prism-previewer-color:before { + background-color: inherit; + background-clip: padding-box +} + +.prism-previewer-easing { + margin-top: -76px; + margin-left: -30px; + width: 60px; + height: 60px; + background: #333 +} + +.prism-previewer-easing.flipped { + margin-bottom: -116px +} + +.prism-previewer-easing svg { + width: 60px; + height: 60px +} + +.prism-previewer-easing circle { + fill: #2e3538; + stroke: #fff +} + +.prism-previewer-easing path { + fill: none; + stroke: #fff; + stroke-linecap: round; + stroke-width: 4 +} + +.prism-previewer-easing line { + stroke: #fff; + stroke-opacity: .5; + stroke-width: 2 +} + +@keyframes prism-previewer-time { + 0% { + stroke-dasharray: 0,500; + stroke-dashoffset: 0 + } + + 50% { + stroke-dasharray: 100,500; + stroke-dashoffset: 0 + } + + to { + stroke-dasharray: 0,500; + stroke-dashoffset: -100 + } +} + +.prism-previewer-time:before { + border-radius: 50%; + background: #fff +} + +.prism-previewer-time:after { + margin-top: 4px +} + +.prism-previewer-time svg { + width: 32px; + height: 32px; + transform: rotate(-90deg) +} + +.prism-previewer-time circle { + fill: transparent; + stroke: #2e3538; + stroke-opacity: .9; + stroke-width: 32; + stroke-dasharray: 0,500; + stroke-dashoffset: 0; + animation: prism-previewer-time 3s linear infinite +} + +.docs-pills .d-flex.justify-content-between { + border-bottom: 1px solid #e0e0e0!important +} + +.docs-pills .nav { + border-bottom: 0!important +} + +.docs-pills .btn-group-sm>.btn[class*=btn-outline-],.docs-pills .btn.btn-sm[class*=btn-outline-] { + margin-top: .1rem!important; + padding-left: 1rem!important; + padding-right: 1rem!important +} + +.docs-pills .nav-pills .nav-link { + padding: 10px 20px; + margin: 0 5px +} + +.docs-pills .nav-item .active { + background-color: #e3ebf7!important; + color: #285192!important +} + +.docs-pills .tab-content { + padding: 0 +} + +.docs-pills .btn-copy-code,.docs-pills .export-to-snippet { + position: absolute; + top: 9px; + right: 8px; + color: #616162!important; + padding: 6px 15px!important +} + +.docs-pills { + position: relative!important +} + +.docs-pills pre[class*=language-] { + margin-top: 0 +} + +pre.line-numbers { + position: relative; + padding-left: 3.8em!important; + counter-reset: linenumber +} + +pre.line-numbers>code { + position: relative; + white-space: inherit +} + +.line-numbers .line-numbers-rows { + position: absolute; + pointer-events: none; + top: 0; + font-size: 100%; + left: -3.8em; + width: 3em; + letter-spacing: -1px; + border-right: 1px solid #999; + -webkit-user-select: none; + -moz-user-select: none; + user-select: none +} + +.line-numbers-rows>span { + pointer-events: none; + display: block; + counter-increment: linenumber +} + +.line-numbers-rows>span:before { + content: counter(linenumber); + color: #999; + display: block; + padding-right: .8em; + text-align: right +} + +.code-toolbar { + margin: 0 +} + +code[class*=language-],pre[class*=language-] { + max-height: 450px +} + +#mdb-footer { + padding-left: 240px +} + +@media(max-width: 1439px) { + #mdb-footer { + padding-left:0 + } +} + +#mdb-intro { + padding-left: 240px; + margin-top: 58.51px +} + +@media(max-width: 1439px) { + #mdb-intro { + padding-left:0 + } +} diff --git a/test_web/static/js/bootstrap.min.js b/test_web/static/js/bootstrap.min.js new file mode 100644 index 0000000..a2eac27 --- /dev/null +++ b/test_web/static/js/bootstrap.min.js @@ -0,0 +1,18 @@ +/*! + * Bootstrap v4.3.1 (https://getbootstrap.com/) + * Copyright 2011-2019 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + */ +!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports,require("jquery"),require("popper.js")):"function"==typeof define&&define.amd?define(["exports","jquery","popper.js"],e):e((t=t||self).bootstrap={},t.jQuery,t.Popper)}(this,function(t,g,u){"use strict";function i(t,e){for(var n=0;nthis._items.length-1||t<0))if(this._isSliding)g(this._element).one(Q.SLID,function(){return e.to(t)});else{if(n===t)return this.pause(),void this.cycle();var i=ndocument.documentElement.clientHeight;!this._isBodyOverflowing&&t&&(this._element.style.paddingLeft=this._scrollbarWidth+"px"),this._isBodyOverflowing&&!t&&(this._element.style.paddingRight=this._scrollbarWidth+"px")},t._resetAdjustments=function(){this._element.style.paddingLeft="",this._element.style.paddingRight=""},t._checkScrollbar=function(){var t=document.body.getBoundingClientRect();this._isBodyOverflowing=t.left+t.right
',trigger:"hover focus",title:"",delay:0,html:!1,selector:!1,placement:"top",offset:0,container:!1,fallbackPlacement:"flip",boundary:"scrollParent",sanitize:!0,sanitizeFn:null,whiteList:Ee},je="show",He="out",Re={HIDE:"hide"+De,HIDDEN:"hidden"+De,SHOW:"show"+De,SHOWN:"shown"+De,INSERTED:"inserted"+De,CLICK:"click"+De,FOCUSIN:"focusin"+De,FOCUSOUT:"focusout"+De,MOUSEENTER:"mouseenter"+De,MOUSELEAVE:"mouseleave"+De},xe="fade",Fe="show",Ue=".tooltip-inner",We=".arrow",qe="hover",Me="focus",Ke="click",Qe="manual",Be=function(){function i(t,e){if("undefined"==typeof u)throw new TypeError("Bootstrap's tooltips require Popper.js (https://popper.js.org/)");this._isEnabled=!0,this._timeout=0,this._hoverState="",this._activeTrigger={},this._popper=null,this.element=t,this.config=this._getConfig(e),this.tip=null,this._setListeners()}var t=i.prototype;return t.enable=function(){this._isEnabled=!0},t.disable=function(){this._isEnabled=!1},t.toggleEnabled=function(){this._isEnabled=!this._isEnabled},t.toggle=function(t){if(this._isEnabled)if(t){var e=this.constructor.DATA_KEY,n=g(t.currentTarget).data(e);n||(n=new this.constructor(t.currentTarget,this._getDelegateConfig()),g(t.currentTarget).data(e,n)),n._activeTrigger.click=!n._activeTrigger.click,n._isWithActiveTrigger()?n._enter(null,n):n._leave(null,n)}else{if(g(this.getTipElement()).hasClass(Fe))return void this._leave(null,this);this._enter(null,this)}},t.dispose=function(){clearTimeout(this._timeout),g.removeData(this.element,this.constructor.DATA_KEY),g(this.element).off(this.constructor.EVENT_KEY),g(this.element).closest(".modal").off("hide.bs.modal"),this.tip&&g(this.tip).remove(),this._isEnabled=null,this._timeout=null,this._hoverState=null,(this._activeTrigger=null)!==this._popper&&this._popper.destroy(),this._popper=null,this.element=null,this.config=null,this.tip=null},t.show=function(){var e=this;if("none"===g(this.element).css("display"))throw new Error("Please use show on visible elements");var t=g.Event(this.constructor.Event.SHOW);if(this.isWithContent()&&this._isEnabled){g(this.element).trigger(t);var n=_.findShadowRoot(this.element),i=g.contains(null!==n?n:this.element.ownerDocument.documentElement,this.element);if(t.isDefaultPrevented()||!i)return;var o=this.getTipElement(),r=_.getUID(this.constructor.NAME);o.setAttribute("id",r),this.element.setAttribute("aria-describedby",r),this.setContent(),this.config.animation&&g(o).addClass(xe);var s="function"==typeof this.config.placement?this.config.placement.call(this,o,this.element):this.config.placement,a=this._getAttachment(s);this.addAttachmentClass(a);var l=this._getContainer();g(o).data(this.constructor.DATA_KEY,this),g.contains(this.element.ownerDocument.documentElement,this.tip)||g(o).appendTo(l),g(this.element).trigger(this.constructor.Event.INSERTED),this._popper=new u(this.element,o,{placement:a,modifiers:{offset:this._getOffset(),flip:{behavior:this.config.fallbackPlacement},arrow:{element:We},preventOverflow:{boundariesElement:this.config.boundary}},onCreate:function(t){t.originalPlacement!==t.placement&&e._handlePopperPlacementChange(t)},onUpdate:function(t){return e._handlePopperPlacementChange(t)}}),g(o).addClass(Fe),"ontouchstart"in document.documentElement&&g(document.body).children().on("mouseover",null,g.noop);var c=function(){e.config.animation&&e._fixTransition();var t=e._hoverState;e._hoverState=null,g(e.element).trigger(e.constructor.Event.SHOWN),t===He&&e._leave(null,e)};if(g(this.tip).hasClass(xe)){var h=_.getTransitionDurationFromElement(this.tip);g(this.tip).one(_.TRANSITION_END,c).emulateTransitionEnd(h)}else c()}},t.hide=function(t){var e=this,n=this.getTipElement(),i=g.Event(this.constructor.Event.HIDE),o=function(){e._hoverState!==je&&n.parentNode&&n.parentNode.removeChild(n),e._cleanTipClass(),e.element.removeAttribute("aria-describedby"),g(e.element).trigger(e.constructor.Event.HIDDEN),null!==e._popper&&e._popper.destroy(),t&&t()};if(g(this.element).trigger(i),!i.isDefaultPrevented()){if(g(n).removeClass(Fe),"ontouchstart"in document.documentElement&&g(document.body).children().off("mouseover",null,g.noop),this._activeTrigger[Ke]=!1,this._activeTrigger[Me]=!1,this._activeTrigger[qe]=!1,g(this.tip).hasClass(xe)){var r=_.getTransitionDurationFromElement(n);g(n).one(_.TRANSITION_END,o).emulateTransitionEnd(r)}else o();this._hoverState=""}},t.update=function(){null!==this._popper&&this._popper.scheduleUpdate()},t.isWithContent=function(){return Boolean(this.getTitle())},t.addAttachmentClass=function(t){g(this.getTipElement()).addClass(Ae+"-"+t)},t.getTipElement=function(){return this.tip=this.tip||g(this.config.template)[0],this.tip},t.setContent=function(){var t=this.getTipElement();this.setElementContent(g(t.querySelectorAll(Ue)),this.getTitle()),g(t).removeClass(xe+" "+Fe)},t.setElementContent=function(t,e){"object"!=typeof e||!e.nodeType&&!e.jquery?this.config.html?(this.config.sanitize&&(e=Se(e,this.config.whiteList,this.config.sanitizeFn)),t.html(e)):t.text(e):this.config.html?g(e).parent().is(t)||t.empty().append(e):t.text(g(e).text())},t.getTitle=function(){var t=this.element.getAttribute("data-original-title");return t||(t="function"==typeof this.config.title?this.config.title.call(this.element):this.config.title),t},t._getOffset=function(){var e=this,t={};return"function"==typeof this.config.offset?t.fn=function(t){return t.offsets=l({},t.offsets,e.config.offset(t.offsets,e.element)||{}),t}:t.offset=this.config.offset,t},t._getContainer=function(){return!1===this.config.container?document.body:_.isElement(this.config.container)?g(this.config.container):g(document).find(this.config.container)},t._getAttachment=function(t){return Pe[t.toUpperCase()]},t._setListeners=function(){var i=this;this.config.trigger.split(" ").forEach(function(t){if("click"===t)g(i.element).on(i.constructor.Event.CLICK,i.config.selector,function(t){return i.toggle(t)});else if(t!==Qe){var e=t===qe?i.constructor.Event.MOUSEENTER:i.constructor.Event.FOCUSIN,n=t===qe?i.constructor.Event.MOUSELEAVE:i.constructor.Event.FOCUSOUT;g(i.element).on(e,i.config.selector,function(t){return i._enter(t)}).on(n,i.config.selector,function(t){return i._leave(t)})}}),g(this.element).closest(".modal").on("hide.bs.modal",function(){i.element&&i.hide()}),this.config.selector?this.config=l({},this.config,{trigger:"manual",selector:""}):this._fixTitle()},t._fixTitle=function(){var t=typeof this.element.getAttribute("data-original-title");(this.element.getAttribute("title")||"string"!==t)&&(this.element.setAttribute("data-original-title",this.element.getAttribute("title")||""),this.element.setAttribute("title",""))},t._enter=function(t,e){var n=this.constructor.DATA_KEY;(e=e||g(t.currentTarget).data(n))||(e=new this.constructor(t.currentTarget,this._getDelegateConfig()),g(t.currentTarget).data(n,e)),t&&(e._activeTrigger["focusin"===t.type?Me:qe]=!0),g(e.getTipElement()).hasClass(Fe)||e._hoverState===je?e._hoverState=je:(clearTimeout(e._timeout),e._hoverState=je,e.config.delay&&e.config.delay.show?e._timeout=setTimeout(function(){e._hoverState===je&&e.show()},e.config.delay.show):e.show())},t._leave=function(t,e){var n=this.constructor.DATA_KEY;(e=e||g(t.currentTarget).data(n))||(e=new this.constructor(t.currentTarget,this._getDelegateConfig()),g(t.currentTarget).data(n,e)),t&&(e._activeTrigger["focusout"===t.type?Me:qe]=!1),e._isWithActiveTrigger()||(clearTimeout(e._timeout),e._hoverState=He,e.config.delay&&e.config.delay.hide?e._timeout=setTimeout(function(){e._hoverState===He&&e.hide()},e.config.delay.hide):e.hide())},t._isWithActiveTrigger=function(){for(var t in this._activeTrigger)if(this._activeTrigger[t])return!0;return!1},t._getConfig=function(t){var e=g(this.element).data();return Object.keys(e).forEach(function(t){-1!==Oe.indexOf(t)&&delete e[t]}),"number"==typeof(t=l({},this.constructor.Default,e,"object"==typeof t&&t?t:{})).delay&&(t.delay={show:t.delay,hide:t.delay}),"number"==typeof t.title&&(t.title=t.title.toString()),"number"==typeof t.content&&(t.content=t.content.toString()),_.typeCheckConfig(be,t,this.constructor.DefaultType),t.sanitize&&(t.template=Se(t.template,t.whiteList,t.sanitizeFn)),t},t._getDelegateConfig=function(){var t={};if(this.config)for(var e in this.config)this.constructor.Default[e]!==this.config[e]&&(t[e]=this.config[e]);return t},t._cleanTipClass=function(){var t=g(this.getTipElement()),e=t.attr("class").match(Ne);null!==e&&e.length&&t.removeClass(e.join(""))},t._handlePopperPlacementChange=function(t){var e=t.instance;this.tip=e.popper,this._cleanTipClass(),this.addAttachmentClass(this._getAttachment(t.placement))},t._fixTransition=function(){var t=this.getTipElement(),e=this.config.animation;null===t.getAttribute("x-placement")&&(g(t).removeClass(xe),this.config.animation=!1,this.hide(),this.show(),this.config.animation=e)},i._jQueryInterface=function(n){return this.each(function(){var t=g(this).data(Ie),e="object"==typeof n&&n;if((t||!/dispose|hide/.test(n))&&(t||(t=new i(this,e),g(this).data(Ie,t)),"string"==typeof n)){if("undefined"==typeof t[n])throw new TypeError('No method named "'+n+'"');t[n]()}})},s(i,null,[{key:"VERSION",get:function(){return"4.3.1"}},{key:"Default",get:function(){return Le}},{key:"NAME",get:function(){return be}},{key:"DATA_KEY",get:function(){return Ie}},{key:"Event",get:function(){return Re}},{key:"EVENT_KEY",get:function(){return De}},{key:"DefaultType",get:function(){return ke}}]),i}();g.fn[be]=Be._jQueryInterface,g.fn[be].Constructor=Be,g.fn[be].noConflict=function(){return g.fn[be]=we,Be._jQueryInterface};var Ve="popover",Ye="bs.popover",ze="."+Ye,Xe=g.fn[Ve],$e="bs-popover",Ge=new RegExp("(^|\\s)"+$e+"\\S+","g"),Je=l({},Be.Default,{placement:"right",trigger:"click",content:"",template:''}),Ze=l({},Be.DefaultType,{content:"(string|element|function)"}),tn="fade",en="show",nn=".popover-header",on=".popover-body",rn={HIDE:"hide"+ze,HIDDEN:"hidden"+ze,SHOW:"show"+ze,SHOWN:"shown"+ze,INSERTED:"inserted"+ze,CLICK:"click"+ze,FOCUSIN:"focusin"+ze,FOCUSOUT:"focusout"+ze,MOUSEENTER:"mouseenter"+ze,MOUSELEAVE:"mouseleave"+ze},sn=function(t){var e,n;function i(){return t.apply(this,arguments)||this}n=t,(e=i).prototype=Object.create(n.prototype),(e.prototype.constructor=e).__proto__=n;var o=i.prototype;return o.isWithContent=function(){return this.getTitle()||this._getContent()},o.addAttachmentClass=function(t){g(this.getTipElement()).addClass($e+"-"+t)},o.getTipElement=function(){return this.tip=this.tip||g(this.config.template)[0],this.tip},o.setContent=function(){var t=g(this.getTipElement());this.setElementContent(t.find(nn),this.getTitle());var e=this._getContent();"function"==typeof e&&(e=e.call(this.element)),this.setElementContent(t.find(on),e),t.removeClass(tn+" "+en)},o._getContent=function(){return this.element.getAttribute("data-content")||this.config.content},o._cleanTipClass=function(){var t=g(this.getTipElement()),e=t.attr("class").match(Ge);null!==e&&0=this._offsets[o]&&("undefined"==typeof this._offsets[o+1]||t]+>/g,"")),d&&(j=f(j)),j=j.toUpperCase(),g="contains"===c?j.indexOf(b)>=0:j.startsWith(b)))break}return g}function e(a){return parseInt(a,10)||0}function f(b){var c=[{re:/[\xC0-\xC6]/g,ch:"A"},{re:/[\xE0-\xE6]/g,ch:"a"},{re:/[\xC8-\xCB]/g,ch:"E"},{re:/[\xE8-\xEB]/g,ch:"e"},{re:/[\xCC-\xCF]/g,ch:"I"},{re:/[\xEC-\xEF]/g,ch:"i"},{re:/[\xD2-\xD6]/g,ch:"O"},{re:/[\xF2-\xF6]/g,ch:"o"},{re:/[\xD9-\xDC]/g,ch:"U"},{re:/[\xF9-\xFC]/g,ch:"u"},{re:/[\xC7-\xE7]/g,ch:"c"},{re:/[\xD1]/g,ch:"N"},{re:/[\xF1]/g,ch:"n"}];return a.each(c,function(){b=b?b.replace(this.re,this.ch):""}),b}function g(b){var c=arguments,d=b;[].shift.apply(c);var e,f=this.each(function(){var b=a(this);if(b.is("select")){var f=b.data("selectpicker"),g="object"==typeof d&&d;if(f){if(g)for(var h in g)g.hasOwnProperty(h)&&(f.options[h]=g[h])}else{var i=a.extend({},x.DEFAULTS,a.fn.selectpicker.defaults||{},b.data(),g);i.template=a.extend({},x.DEFAULTS.template,a.fn.selectpicker.defaults?a.fn.selectpicker.defaults.template:{},b.data().template,g.template),b.data("selectpicker",f=new x(this,i))}"string"==typeof d&&(e=f[d]instanceof Function?f[d].apply(f,c):f.options[d])}});return void 0!==e?e:f}var h=document.createElement("_");if(h.classList.toggle("c3",!1),h.classList.contains("c3")){var i=DOMTokenList.prototype.toggle;DOMTokenList.prototype.toggle=function(a,b){return 1 in arguments&&!this.contains(a)==!b?b:i.call(this,a)}}String.prototype.startsWith||function(){var a=function(){try{var a={},b=Object.defineProperty,c=b(a,a,a)&&b}catch(a){}return c}(),b={}.toString,c=function(a){if(null==this)throw new TypeError;var c=String(this);if(a&&"[object RegExp]"==b.call(a))throw new TypeError;var d=c.length,e=String(a),f=e.length,g=arguments.length>1?arguments[1]:void 0,h=g?Number(g):0;h!=h&&(h=0);var i=Math.min(Math.max(h,0),d);if(f+i>d)return!1;for(var j=-1;++j":">",'"':""","'":"'","`":"`"},n={"&":"&","<":"<",">":">",""":'"',"'":"'","`":"`"},o=function(a){var b=function(b){return a[b]},c="(?:"+Object.keys(a).join("|")+")",d=RegExp(c),e=RegExp(c,"g");return function(a){return a=null==a?"":""+a,d.test(a)?a.replace(e,b):a}},p=o(m),q=o(n),r={32:" ",48:"0",49:"1",50:"2",51:"3",52:"4",53:"5",54:"6",55:"7",56:"8",57:"9",59:";",65:"A",66:"B",67:"C",68:"D",69:"E",70:"F",71:"G",72:"H",73:"I",74:"J",75:"K",76:"L",77:"M",78:"N",79:"O",80:"P",81:"Q",82:"R",83:"S",84:"T",85:"U",86:"V",87:"W",88:"X",89:"Y",90:"Z",96:"0",97:"1",98:"2",99:"3",100:"4",101:"5",102:"6",103:"7",104:"8",105:"9"},s={ESCAPE:27,ENTER:13,SPACE:32,TAB:9,ARROW_UP:38,ARROW_DOWN:40},t={};try{t.full=(a.fn.dropdown.Constructor.VERSION||"").split(" ")[0].split("."),t.major=t.full[0]}catch(a){console.error("There was an issue retrieving Bootstrap's version. Ensure Bootstrap is being loaded before bootstrap-select and there is no namespace collision.",a),t.major="3"}var u={DISABLED:"disabled",DIVIDER:"4"===t.major?"dropdown-divider":"divider",SHOW:"4"===t.major?"show":"open",DROPUP:"dropup",MENURIGHT:"dropdown-menu-right",MENULEFT:"dropdown-menu-left",BUTTONCLASS:"4"===t.major?"btn-light":"btn-default",POPOVERHEADER:"4"===t.major?"popover-header":"popover-title"},v=new RegExp(s.ARROW_UP+"|"+s.ARROW_DOWN),w=new RegExp("^"+s.TAB+"$|"+s.ESCAPE),x=(new RegExp(s.ENTER+"|"+s.SPACE),function(b,c){var d=this;j.useDefault||(a.valHooks.select.set=j._set,j.useDefault=!0),this.$element=a(b),this.$newElement=null,this.$button=null,this.$menu=null,this.options=c,this.selectpicker={main:{map:{newIndex:{},originalIndex:{}}},current:{map:{}},search:{map:{}},view:{},keydown:{keyHistory:"",resetKeyHistory:{start:function(){return setTimeout(function(){d.selectpicker.keydown.keyHistory=""},800)}}}},null===this.options.title&&(this.options.title=this.$element.attr("title"));var e=this.options.windowPadding;"number"==typeof e&&(this.options.windowPadding=[e,e,e,e]),this.val=x.prototype.val,this.render=x.prototype.render,this.refresh=x.prototype.refresh,this.setStyle=x.prototype.setStyle,this.selectAll=x.prototype.selectAll,this.deselectAll=x.prototype.deselectAll,this.destroy=x.prototype.destroy,this.remove=x.prototype.remove,this.show=x.prototype.show,this.hide=x.prototype.hide,this.init()});x.VERSION="1.13.1",x.DEFAULTS={noneSelectedText:"Nothing selected",noneResultsText:"No results matched {0}",countSelectedText:function(a,b){return 1==a?"{0} item selected":"{0} items selected"},maxOptionsText:function(a,b){return[1==a?"Limit reached ({n} item max)":"Limit reached ({n} items max)",1==b?"Group limit reached ({n} item max)":"Group limit reached ({n} items max)"]},selectAllText:"Select All",deselectAllText:"Deselect All",doneButton:!1,doneButtonText:"Close",multipleSeparator:", ",styleBase:"btn",style:"btn-default",size:"auto",title:null,selectedTextFormat:"values",width:!1,container:!1,hideDisabled:!1,showSubtext:!1,showIcon:!0,showContent:!0,dropupAuto:!0,header:!1,liveSearch:!1,liveSearchPlaceholder:null,liveSearchNormalize:!1,liveSearchStyle:"contains",actionsBox:!1,iconBase:"glyphicon",tickIcon:"glyphicon-ok",showTick:!1,template:{caret:''},maxOptions:!1,mobile:!1,selectOnTab:!1,dropdownAlignRight:!1,windowPadding:0,virtualScroll:600},"4"===t.major&&(x.DEFAULTS.style="btn-light",x.DEFAULTS.iconBase="",x.DEFAULTS.tickIcon="bs-ok-default"),x.prototype={constructor:x,init:function(){var a=this,b=this.$element.attr("id");this.$element.addClass("bs-select-hidden"),this.multiple=this.$element.prop("multiple"),this.autofocus=this.$element.prop("autofocus"),this.$newElement=this.createDropdown(),this.createLi(),this.$element.after(this.$newElement).prependTo(this.$newElement),this.$button=this.$newElement.children("button"),this.$menu=this.$newElement.children(".dropdown-menu"),this.$menuInner=this.$menu.children(".inner"),this.$searchbox=this.$menu.find("input"),this.$element.removeClass("bs-select-hidden"),!0===this.options.dropdownAlignRight&&this.$menu.addClass(u.MENURIGHT),void 0!==b&&this.$button.attr("data-id",b),this.checkDisabled(),this.clickListener(),this.options.liveSearch&&this.liveSearchListener(),this.render(),this.setStyle(),this.setWidth(),this.options.container?this.selectPosition():this.$element.on("hide.bs.select",function(){if(a.isVirtual()){var b=a.$menuInner[0],c=b.firstChild.cloneNode(!1);b.replaceChild(c,b.firstChild),b.scrollTop=0}}),this.$menu.data("this",this),this.$newElement.data("this",this),this.options.mobile&&this.mobile(),this.$newElement.on({"hide.bs.dropdown":function(b){a.$menuInner.attr("aria-expanded",!1),a.$element.trigger("hide.bs.select",b)},"hidden.bs.dropdown":function(b){a.$element.trigger("hidden.bs.select",b)},"show.bs.dropdown":function(b){a.$menuInner.attr("aria-expanded",!0),a.$element.trigger("show.bs.select",b)},"shown.bs.dropdown":function(b){a.$element.trigger("shown.bs.select",b)}}),a.$element[0].hasAttribute("required")&&this.$element.on("invalid",function(){a.$button.addClass("bs-invalid"),a.$element.on({"shown.bs.select":function(){a.$element.val(a.$element.val()).off("shown.bs.select")},"rendered.bs.select":function(){this.validity.valid&&a.$button.removeClass("bs-invalid"),a.$element.off("rendered.bs.select")}}),a.$button.on("blur.bs.select",function(){a.$element.focus().blur(),a.$button.off("blur.bs.select")})}),setTimeout(function(){a.$element.trigger("loaded.bs.select")})},createDropdown:function(){var b=this.multiple||this.options.showTick?" show-tick":"",c=this.autofocus?" autofocus":"",d=this.options.header?'
'+this.options.header+"
":"",e=this.options.liveSearch?'':"",f=this.multiple&&this.options.actionsBox?'
":"",g=this.multiple&&this.options.doneButton?'
":"",h='";return a(h)},setPositionData:function(){this.selectpicker.view.canHighlight=[];for(var a=0;a=this.options.virtualScroll||!0===this.options.virtualScroll},createView:function(c,d){function e(a,d){var e,j,k,l,m,n,o,p=f.selectpicker.current.elements.length,q=[],r=void 0,s=!0,t=f.isVirtual();f.selectpicker.view.scrollTop=a,!0===t&&f.sizeInfo.hasScrollBar&&f.$menu[0].offsetWidth>f.sizeInfo.totalMenuWidth&&(f.sizeInfo.menuWidth=f.$menu[0].offsetWidth,f.sizeInfo.totalMenuWidth=f.sizeInfo.menuWidth+f.sizeInfo.scrollBarWidth,f.$menu.css("min-width",f.sizeInfo.menuWidth)),e=Math.ceil(f.sizeInfo.menuInnerHeight/f.sizeInfo.liHeight*1.5),j=Math.round(p/e)||1;for(var u=0;up-1?0:f.selectpicker.current.data[p-1].position-f.selectpicker.current.data[f.selectpicker.view.position1-1].position,y.firstChild.style.marginTop=w+"px",y.firstChild.style.marginBottom=x+"px"),y.firstChild.appendChild(z)}if(f.prevActiveIndex=f.activeIndex,f.options.liveSearch){if(c&&d){var D,E=0;f.selectpicker.view.canHighlight[E]||(E=1+f.selectpicker.view.canHighlight.slice(1).indexOf(!0)),D=f.selectpicker.view.visibleElements[E],f.selectpicker.view.currentActive&&(f.selectpicker.view.currentActive.classList.remove("active"),f.selectpicker.view.currentActive.firstChild&&f.selectpicker.view.currentActive.firstChild.classList.remove("active")),D&&(D.classList.add("active"),D.firstChild&&D.firstChild.classList.add("active")),f.activeIndex=f.selectpicker.current.map.originalIndex[E]}}else f.$menuInner.focus()}d=d||0;var f=this;this.selectpicker.current=c?this.selectpicker.search:this.selectpicker.main;var g,h,i=[];this.setPositionData(),e(d,!0),this.$menuInner.off("scroll.createView").on("scroll.createView",function(a,b){f.noScroll||e(this.scrollTop,b),f.noScroll=!1}),a(window).off("resize.createView").on("resize.createView",function(){e(f.$menuInner[0].scrollTop)})},createLi:function(){var b,c=this,d=[],e=0,f=0,g=[],h=0,i=0,j=-1;this.selectpicker.view.titleOption||(this.selectpicker.view.titleOption=document.createElement("option"));var k={span:document.createElement("span"),subtext:document.createElement("small"),a:document.createElement("a"),li:document.createElement("li"),whitespace:document.createTextNode(" ")},l=k.span.cloneNode(!1),m=document.createDocumentFragment();l.className=c.options.iconBase+" "+c.options.tickIcon+" check-mark",k.a.appendChild(l),k.a.setAttribute("role","option"),k.subtext.className="text-muted",k.text=k.span.cloneNode(!1),k.text.className="text";var n=function(a,b,c,d){var e=k.li.cloneNode(!1);return a&&(1===a.nodeType||11===a.nodeType?e.appendChild(a):e.innerHTML=a),void 0!==c&&""!==c&&(e.className=c),void 0!==d&&null!==d&&e.classList.add("optgroup-"+d),e},o=function(a,b,c){var d=k.a.cloneNode(!0);return a&&(11===a.nodeType?d.appendChild(a):d.insertAdjacentHTML("beforeend",a)),void 0!==b&""!==b&&(d.className=b),"4"===t.major&&d.classList.add("dropdown-item"),c&&d.setAttribute("style",c),d},q=function(a){var b,d,e=k.text.cloneNode(!1);if(a.optionContent)e.innerHTML=a.optionContent;else{if(e.textContent=a.text,a.optionIcon){var f=k.whitespace.cloneNode(!1);d=k.span.cloneNode(!1),d.className=c.options.iconBase+" "+a.optionIcon,m.appendChild(d),m.appendChild(f)}a.optionSubtext&&(b=k.subtext.cloneNode(!1),b.innerHTML=a.optionSubtext,e.appendChild(b))}return m.appendChild(e),m},r=function(a){var b,d,e=k.text.cloneNode(!1);if(e.textContent=a.labelEscaped,a.labelIcon){var f=k.whitespace.cloneNode(!1);d=k.span.cloneNode(!1),d.className=c.options.iconBase+" "+a.labelIcon,m.appendChild(d),m.appendChild(f)}return a.labelSubtext&&(b=k.subtext.cloneNode(!1),b.textContent=a.labelSubtext,e.appendChild(b)),m.appendChild(e),m};if(this.options.title&&!this.multiple){j--;var s=this.$element[0],v=!1,w=!this.selectpicker.view.titleOption.parentNode;if(w){this.selectpicker.view.titleOption.className="bs-title-option",this.selectpicker.view.titleOption.value="";v=void 0===a(s.options[s.selectedIndex]).attr("selected")&&void 0===this.$element.data("selected")}(w||0!==this.selectpicker.view.titleOption.index)&&s.insertBefore(this.selectpicker.view.titleOption,s.firstChild),v&&(s.selectedIndex=0)}var x=this.$element.find("option");x.each(function(k){var l=a(this);if(j++,!l.hasClass("bs-title-option")){var m,s,t=l.data(),v=this.className||"",w=p(this.style.cssText),y=t.content,z=this.textContent,A=t.tokens,B=t.subtext,C=t.icon,D=l.parent(),E=D[0],F="OPTGROUP"===E.tagName,G=F&&E.disabled,H=this.disabled||G,I=this.previousElementSibling&&"OPTGROUP"===this.previousElementSibling.tagName,J=D.data();if(!0===t.hidden||c.options.hideDisabled&&(H&&!F||G)){if(m=t.prevHiddenIndex,l.next().data("prevHiddenIndex",void 0!==m?m:k),j--,!I&&void 0!==m){var K=x[m].previousElementSibling;K&&"OPTGROUP"===K.tagName&&!K.disabled&&(I=!0)}return void(I&&"divider"!==g[g.length-1].type&&(j++,d.push(n(!1,0,u.DIVIDER,h+"div")),g.push({type:"divider",optID:h,originalIndex:k})))}if(F&&!0!==t.divider){if(c.options.hideDisabled&&H){if(void 0===J.allOptionsDisabled){var L=D.children();D.data("allOptionsDisabled",L.filter(":disabled").length===L.length)}if(D.data("allOptionsDisabled"))return void j--}var M=" "+E.className||"";if(!this.previousElementSibling){h+=1;var N=E.label,O=p(N),P=J.subtext,Q=J.icon;0!==k&&d.length>0&&(j++,d.push(n(!1,0,u.DIVIDER,h+"div")),g.push({type:"divider",optID:h,originalIndex:k})),j++;var R=r({labelEscaped:O,labelSubtext:P,labelIcon:Q});d.push(n(R,0,"dropdown-header"+M,h)),g.push({content:O,subtext:P,type:"optgroup-label",optID:h,originalIndex:k}),i=j-1}if(c.options.hideDisabled&&H||!0===t.hidden)return void j--;s=q({text:z,optionContent:y,optionSubtext:B,optionIcon:C}),d.push(n(o(s,"opt "+v+M,w),0,"",h)),g.push({content:y||z,subtext:B,tokens:A,type:"option",optID:h,headerIndex:i,lastIndex:i+E.childElementCount,originalIndex:k,data:t}),e++}else if(!0===t.divider)d.push(n(!1,0,"divider")),g.push({type:"divider",originalIndex:k});else{if(!I&&c.options.hideDisabled&&void 0!==(m=t.prevHiddenIndex)){var K=x[m].previousElementSibling;K&&"OPTGROUP"===K.tagName&&!K.disabled&&(I=!0)}I&&"divider"!==g[g.length-1].type&&(j++,d.push(n(!1,0,u.DIVIDER,h+"div")),g.push({type:"divider",optID:h,originalIndex:k})),s=q({text:z,optionContent:y,optionSubtext:B,optionIcon:C}),d.push(n(o(s,v,w))),g.push({content:y||z,subtext:B,tokens:A,type:"option",originalIndex:k,data:t}),e++}c.selectpicker.main.map.newIndex[k]=j,c.selectpicker.main.map.originalIndex[j]=k;var S=g[g.length-1];S.disabled=H;var T=0;S.content&&(T+=S.content.length),S.subtext&&(T+=S.subtext.length),C&&(T+=1),T>f&&(f=T,b=d[d.length-1])}}),this.selectpicker.main.elements=d,this.selectpicker.main.data=g,this.selectpicker.current=this.selectpicker.main,this.selectpicker.view.widestOption=b,this.selectpicker.view.availableOptionsCount=e},findLis:function(){return this.$menuInner.find(".inner > li")},render:function(){var a=this,b=this.$element.find("option"),c=[],d=[];this.togglePlaceholder(),this.tabIndex();for(var e=0,f=this.selectpicker.main.elements.length;e
':"";i=a.options.showSubtext&&k.subtext&&!a.multiple?' '+k.subtext+"":"",j=h.title?h.title:k.content&&a.options.showContent?k.content.toString():l+h.innerHTML.trim()+i,d.push(j)}}var m=this.multiple?d.join(this.options.multipleSeparator):d[0];if(c.length>50&&(m+="..."),this.multiple&&-1!==this.options.selectedTextFormat.indexOf("count")){var n=this.options.selectedTextFormat.split(">");if(n.length>1&&c.length>n[1]||1===n.length&&c.length>=2){var o=this.selectpicker.view.availableOptionsCount;m=("function"==typeof this.options.countSelectedText?this.options.countSelectedText(c.length,o):this.options.countSelectedText).replace("{0}",c.length.toString()).replace("{1}",o.toString())}}void 0==this.options.title&&(this.options.title=this.$element.attr("title")),"static"==this.options.selectedTextFormat&&(m=this.options.title),m||(m=void 0!==this.options.title?this.options.title:this.options.noneSelectedText),this.$button[0].title=q(m.replace(/<[^>]*>?/g,"").trim()),this.$button.find(".filter-option-inner-inner")[0].innerHTML=m,this.$element.trigger("rendered.bs.select")},setStyle:function(a,b){this.$element.attr("class")&&this.$newElement.addClass(this.$element.attr("class").replace(/selectpicker|mobile-device|bs-select-hidden|validate\[.*\]/gi,""));var c=a||this.options.style;"add"==b?this.$button.addClass(c):"remove"==b?this.$button.removeClass(c):(this.$button.removeClass(this.options.style),this.$button.addClass(c))},liHeight:function(b){if(b||!1!==this.options.size&&!this.sizeInfo){this.sizeInfo||(this.sizeInfo={});var c=document.createElement("div"),d=document.createElement("div"),f=document.createElement("div"),g=document.createElement("ul"),h=document.createElement("li"),i=document.createElement("li"),j=document.createElement("li"),k=document.createElement("a"),l=document.createElement("span"),m=this.options.header&&this.$menu.find("."+u.POPOVERHEADER).length>0?this.$menu.find("."+u.POPOVERHEADER)[0].cloneNode(!0):null,n=this.options.liveSearch?document.createElement("div"):null,o=this.options.actionsBox&&this.multiple&&this.$menu.find(".bs-actionsbox").length>0?this.$menu.find(".bs-actionsbox")[0].cloneNode(!0):null,p=this.options.doneButton&&this.multiple&&this.$menu.find(".bs-donebutton").length>0?this.$menu.find(".bs-donebutton")[0].cloneNode(!0):null;if(this.sizeInfo.selectWidth=this.$newElement[0].offsetWidth,l.className="text",k.className="dropdown-item",c.className=this.$menu[0].parentNode.className+" "+u.SHOW,c.style.width=this.sizeInfo.selectWidth+"px",d.className="dropdown-menu "+u.SHOW,f.className="inner "+u.SHOW,g.className="dropdown-menu inner "+("4"===t.major?u.SHOW:""),h.className=u.DIVIDER,i.className="dropdown-header",l.appendChild(document.createTextNode("Inner text")),k.appendChild(l),j.appendChild(k),i.appendChild(l.cloneNode(!0)),this.selectpicker.view.widestOption&&g.appendChild(this.selectpicker.view.widestOption.cloneNode(!0)),g.appendChild(j),g.appendChild(h),g.appendChild(i),m&&d.appendChild(m),n){var q=document.createElement("input");n.className="bs-searchbox",q.className="form-control",n.appendChild(q),d.appendChild(n)}o&&d.appendChild(o),f.appendChild(g),d.appendChild(f),p&&d.appendChild(p),c.appendChild(d),document.body.appendChild(c);var r,s=k.offsetHeight,v=i?i.offsetHeight:0,w=m?m.offsetHeight:0,x=n?n.offsetHeight:0,y=o?o.offsetHeight:0,z=p?p.offsetHeight:0,A=a(h).outerHeight(!0),B=!!window.getComputedStyle&&window.getComputedStyle(d),C=d.offsetWidth,D=B?null:a(d),E={vert:e(B?B.paddingTop:D.css("paddingTop"))+e(B?B.paddingBottom:D.css("paddingBottom"))+e(B?B.borderTopWidth:D.css("borderTopWidth"))+e(B?B.borderBottomWidth:D.css("borderBottomWidth")),horiz:e(B?B.paddingLeft:D.css("paddingLeft"))+e(B?B.paddingRight:D.css("paddingRight"))+e(B?B.borderLeftWidth:D.css("borderLeftWidth"))+e(B?B.borderRightWidth:D.css("borderRightWidth"))},F={vert:E.vert+e(B?B.marginTop:D.css("marginTop"))+e(B?B.marginBottom:D.css("marginBottom"))+2,horiz:E.horiz+e(B?B.marginLeft:D.css("marginLeft"))+e(B?B.marginRight:D.css("marginRight"))+2};f.style.overflowY="scroll",r=d.offsetWidth-C,document.body.removeChild(c),this.sizeInfo.liHeight=s,this.sizeInfo.dropdownHeaderHeight=v,this.sizeInfo.headerHeight=w,this.sizeInfo.searchHeight=x,this.sizeInfo.actionsHeight=y,this.sizeInfo.doneButtonHeight=z,this.sizeInfo.dividerHeight=A,this.sizeInfo.menuPadding=E,this.sizeInfo.menuExtras=F,this.sizeInfo.menuWidth=C,this.sizeInfo.totalMenuWidth=this.sizeInfo.menuWidth,this.sizeInfo.scrollBarWidth=r,this.sizeInfo.selectHeight=this.$newElement[0].offsetHeight,this.setPositionData()}},getSelectPosition:function(){var b,c=this,d=a(window),e=c.$newElement.offset(),f=a(c.options.container);c.options.container&&!f.is("body")?(b=f.offset(),b.top+=parseInt(f.css("borderTopWidth")),b.left+=parseInt(f.css("borderLeftWidth"))):b={top:0,left:0};var g=c.options.windowPadding;this.sizeInfo.selectOffsetTop=e.top-b.top-d.scrollTop(),this.sizeInfo.selectOffsetBot=d.height()-this.sizeInfo.selectOffsetTop-this.sizeInfo.selectHeight-b.top-g[2],this.sizeInfo.selectOffsetLeft=e.left-b.left-d.scrollLeft(),this.sizeInfo.selectOffsetRight=d.width()-this.sizeInfo.selectOffsetLeft-this.sizeInfo.selectWidth-b.left-g[1],this.sizeInfo.selectOffsetTop-=g[0],this.sizeInfo.selectOffsetLeft-=g[3]},setMenuSize:function(a){this.getSelectPosition();var b,c,d,e,f,g,h,i=this.sizeInfo.selectWidth,j=this.sizeInfo.liHeight,k=this.sizeInfo.headerHeight,l=this.sizeInfo.searchHeight,m=this.sizeInfo.actionsHeight,n=this.sizeInfo.doneButtonHeight,o=this.sizeInfo.dividerHeight,p=this.sizeInfo.menuPadding,q=0;if(this.options.dropupAuto&&(h=j*this.selectpicker.current.elements.length+p.vert,this.$newElement.toggleClass(u.DROPUP,this.sizeInfo.selectOffsetTop-this.sizeInfo.selectOffsetBot>this.sizeInfo.menuExtras.vert&&h+this.sizeInfo.menuExtras.vert+50>this.sizeInfo.selectOffsetBot)),"auto"===this.options.size)e=this.selectpicker.current.elements.length>3?3*this.sizeInfo.liHeight+this.sizeInfo.menuExtras.vert-2:0,c=this.sizeInfo.selectOffsetBot-this.sizeInfo.menuExtras.vert,d=e+k+l+m+n,g=Math.max(e-p.vert,0),this.$newElement.hasClass(u.DROPUP)&&(c=this.sizeInfo.selectOffsetTop-this.sizeInfo.menuExtras.vert),f=c,b=c-k-l-m-n-p.vert;else if(this.options.size&&"auto"!=this.options.size&&this.selectpicker.current.elements.length>this.options.size){for(var r=0;rthis.sizeInfo.selectOffsetRight&&this.sizeInfo.selectOffsetRightthis.sizeInfo.menuInnerHeight&&(this.sizeInfo.hasScrollBar=!0,this.sizeInfo.totalMenuWidth=this.sizeInfo.menuWidth+this.sizeInfo.scrollBarWidth,this.$menu.css("min-width",this.sizeInfo.totalMenuWidth)),this.dropdown&&this.dropdown._popper&&this.dropdown._popper.update()},setSize:function(b){if(this.liHeight(b),this.options.header&&this.$menu.css("padding-top",0),!1!==this.options.size){var c,d=this,e=a(window),f=0;this.setMenuSize(),"auto"===this.options.size?(this.$searchbox.off("input.setMenuSize propertychange.setMenuSize").on("input.setMenuSize propertychange.setMenuSize",function(){return d.setMenuSize()}),e.off("resize.setMenuSize scroll.setMenuSize").on("resize.setMenuSize scroll.setMenuSize",function(){return d.setMenuSize()})):this.options.size&&"auto"!=this.options.size&&this.selectpicker.current.elements.length>this.options.size&&(this.$searchbox.off("input.setMenuSize propertychange.setMenuSize"),e.off("resize.setMenuSize scroll.setMenuSize")),b?f=this.$menuInner[0].scrollTop:d.multiple||"number"==typeof(c=d.selectpicker.main.map.newIndex[d.$element[0].selectedIndex])&&!1!==d.options.size&&(f=d.sizeInfo.liHeight*c,f=f-d.sizeInfo.menuInnerHeight/2+d.sizeInfo.liHeight/2),d.createView(!1,f)}},setWidth:function(){var a=this;"auto"===this.options.width?requestAnimationFrame(function(){a.$menu.css("min-width","0"),a.liHeight(),a.setMenuSize();var b=a.$newElement.clone().appendTo("body"),c=b.css("width","auto").children("button").outerWidth();b.remove(),a.sizeInfo.selectWidth=Math.max(a.sizeInfo.totalMenuWidth,c),a.$newElement.css("width",a.sizeInfo.selectWidth+"px")}):"fit"===this.options.width?(this.$menu.css("min-width",""),this.$newElement.css("width","").addClass("fit-width")):this.options.width?(this.$menu.css("min-width",""),this.$newElement.css("width",this.options.width)):(this.$menu.css("min-width",""),this.$newElement.css("width","")),this.$newElement.hasClass("fit-width")&&"fit"!==this.options.width&&this.$newElement.removeClass("fit-width")},selectPosition:function(){this.$bsContainer=a('
');var b,c,d,e=this,f=a(this.options.container),g=function(a){var g={};e.$bsContainer.addClass(a.attr("class").replace(/form-control|fit-width/gi,"")).toggleClass(u.DROPUP,a.hasClass(u.DROPUP)),b=a.offset(),f.is("body")?c={top:0,left:0}:(c=f.offset(),c.top+=parseInt(f.css("borderTopWidth"))-f.scrollTop(),c.left+=parseInt(f.css("borderLeftWidth"))-f.scrollLeft()),d=a.hasClass(u.DROPUP)?0:a[0].offsetHeight,t.major<4&&(g.top=b.top-c.top+d,g.left=b.left-c.left),g.width=a[0].offsetWidth,e.$bsContainer.css(g)};this.$button.on("click.bs.dropdown.data-api",function(){e.isDisabled()||(g(e.$newElement),e.$bsContainer.appendTo(e.options.container).toggleClass(u.SHOW,!e.$button.hasClass(u.SHOW)).append(e.$menu))}),a(window).on("resize scroll",function(){g(e.$newElement)}),this.$element.on("hide.bs.select",function(){e.$menu.data("height",e.$menu.height()),e.$bsContainer.detach()})},setOptionStatus:function(){var a=this,b=this.$element.find("option");if(a.noScroll=!1,a.selectpicker.view.visibleElements&&a.selectpicker.view.visibleElements.length)for(var c=0;c3&&!b.dropdown&&(b.dropdown=b.$button.data("bs.dropdown"),b.dropdown._menu=b.$menu[0])}),this.$button.on("click.bs.dropdown.data-api",function(){b.$newElement.hasClass(u.SHOW)||b.setSize()}),this.$element.on("shown.bs.select",function(){b.$menuInner[0].scrollTop!==b.selectpicker.view.scrollTop&&(b.$menuInner[0].scrollTop=b.selectpicker.view.scrollTop),b.options.liveSearch?b.$searchbox.focus():b.$menuInner.focus()}),this.$menuInner.on("click","li a",function(d,e){var f=a(this),g=b.isVirtual()?b.selectpicker.view.position0:0,h=b.selectpicker.current.map.originalIndex[f.parent().index()+g],i=c(b.$element[0]),j=b.$element.prop("selectedIndex"),l=!0;if(b.multiple&&1!==b.options.maxOptions&&d.stopPropagation(),d.preventDefault(),!b.isDisabled()&&!f.parent().hasClass(u.DISABLED)){var m=b.$element.find("option"),n=m.eq(h),o=n.prop("selected"),p=n.parent("optgroup"),q=b.options.maxOptions,r=p.data("maxOptions")||!1;if(h===b.activeIndex&&(e=!0),e||(b.prevActiveIndex=b.activeIndex,b.activeIndex=void 0),b.multiple){if(n.prop("selected",!o),b.setSelected(h,!o),f.blur(),!1!==q||!1!==r){var s=q
');x[2]&&(y=y.replace("{var}",x[2][q>1?0:1]),z=z.replace("{var}",x[2][r>1?0:1])),n.prop("selected",!1),b.$menu.append(A),q&&s&&(A.append(a("
"+y+"
")),l=!1,b.$element.trigger("maxReached.bs.select")),r&&t&&(A.append(a("
"+z+"
")),l=!1,b.$element.trigger("maxReachedGrp.bs.select")),setTimeout(function(){b.setSelected(h,!1)},10),A.delay(750).fadeOut(300,function(){a(this).remove()})}}}else m.prop("selected",!1),n.prop("selected",!0),b.setSelected(h,!0);!b.multiple||b.multiple&&1===b.options.maxOptions?b.$button.focus():b.options.liveSearch&&b.$searchbox.focus(),l&&(i!=c(b.$element[0])&&b.multiple||j!=b.$element.prop("selectedIndex")&&!b.multiple)&&(k=[h,n.prop("selected"),i],b.$element.triggerNative("change"))}}),this.$menu.on("click","li."+u.DISABLED+" a, ."+u.POPOVERHEADER+", ."+u.POPOVERHEADER+" :not(.close)",function(c){c.currentTarget==this&&(c.preventDefault(),c.stopPropagation(),b.options.liveSearch&&!a(c.target).hasClass("close")?b.$searchbox.focus():b.$button.focus())}),this.$menuInner.on("click",".divider, .dropdown-header",function(a){a.preventDefault(),a.stopPropagation(),b.options.liveSearch?b.$searchbox.focus():b.$button.focus()}),this.$menu.on("click","."+u.POPOVERHEADER+" .close",function(){b.$button.click()}),this.$searchbox.on("click",function(a){a.stopPropagation()}),this.$menu.on("click",".actions-btn",function(c){b.options.liveSearch?b.$searchbox.focus():b.$button.focus(),c.preventDefault(),c.stopPropagation(),a(this).hasClass("bs-select-all")?b.selectAll():b.deselectAll()}),this.$element.on({change:function(){b.render(),b.$element.trigger("changed.bs.select",k),k=null},focus:function(){b.$button.focus()}})},liveSearchListener:function(){var a=this,b=document.createElement("li");this.$button.on("click.bs.dropdown.data-api",function(){a.$searchbox.val()&&a.$searchbox.val("")}),this.$searchbox.on("click.bs.dropdown.data-api focus.bs.dropdown.data-api touchend.bs.dropdown.data-api",function(a){a.stopPropagation()}),this.$searchbox.on("input propertychange",function(){var c=a.$searchbox.val();if(a.selectpicker.search.map.newIndex={},a.selectpicker.search.map.originalIndex={},a.selectpicker.search.elements=[],a.selectpicker.search.data=[],c){var e,f=[],g=c.toUpperCase(),h={},i=[],j=a._searchStyle(),k=a.options.liveSearchNormalize;a._$lisSelected=a.$menuInner.find(".selected");for(var e=0;e0&&(h[l.headerIndex-1]=!0,i.push(l.headerIndex-1)),h[l.headerIndex]=!0,i.push(l.headerIndex),h[l.lastIndex+1]=!0),h[e]&&"optgroup-label"!==l.type&&i.push(e)}for(var e=0,m=i.length;e=48&&b.which<=57||b.which>=96&&b.which<=105||b.which>=65&&b.which<=90)&&k.$button.trigger("click.bs.dropdown.data-api"),b.which===s.ESCAPE&&e&&(b.preventDefault(),k.$button.trigger("click.bs.dropdown.data-api").focus()),o){if(!l.length)return;c=!0===q?l.index(l.filter(".active")):k.selectpicker.current.map.newIndex[k.activeIndex],void 0===c&&(c=-1),-1!==c&&(f=k.selectpicker.current.elements[c+t],f.classList.remove("active"),f.firstChild&&f.firstChild.classList.remove("active")),b.which===s.ARROW_UP?(-1!==c&&c--,c+t<0&&(c+=l.length),k.selectpicker.view.canHighlight[c+t]||-1===(c=k.selectpicker.view.canHighlight.slice(0,c+t).lastIndexOf(!0)-t)&&(c=l.length-1)):(b.which===s.ARROW_DOWN||n)&&(c++,c+t>=k.selectpicker.view.canHighlight.length&&(c=0),k.selectpicker.view.canHighlight[c+t]||(c=c+1+k.selectpicker.view.canHighlight.slice(c+t+1).indexOf(!0))),b.preventDefault();var x=t+c;b.which===s.ARROW_UP?0===t&&c===l.length-1?(k.$menuInner[0].scrollTop=k.$menuInner[0].scrollHeight,x=k.selectpicker.current.elements.length-1):(g=k.selectpicker.current.data[x],h=g.position-g.height,m=hp)),f=k.selectpicker.current.elements[x],f.classList.add("active"),f.firstChild&&f.firstChild.classList.add("active"),k.activeIndex=k.selectpicker.current.map.originalIndex[x],k.selectpicker.view.currentActive=f,m&&(k.$menuInner[0].scrollTop=h),k.options.liveSearch?k.$searchbox.focus():i.focus()}else if(!i.is("input")&&!w.test(b.which)||b.which===s.SPACE&&k.selectpicker.keydown.keyHistory){var y,z,A=[];b.preventDefault(),k.selectpicker.keydown.keyHistory+=r[b.which],k.selectpicker.keydown.resetKeyHistory.cancel&&clearTimeout(k.selectpicker.keydown.resetKeyHistory.cancel),k.selectpicker.keydown.resetKeyHistory.cancel=k.selectpicker.keydown.resetKeyHistory.start(),z=k.selectpicker.keydown.keyHistory,/^(.)\1+$/.test(z)&&(z=z.charAt(0));for(var B=0;B0?(h=g.position-g.height,m=!0):(h=g.position-k.sizeInfo.menuInnerHeight,m=g.position>p+k.sizeInfo.menuInnerHeight),f=k.selectpicker.current.elements[y],f.classList.add("active"),f.firstChild&&f.firstChild.classList.add("active"),k.activeIndex=A[E],f.firstChild.focus(),m&&(k.$menuInner[0].scrollTop=h),i.focus()}}e&&(b.which===s.SPACE&&!k.selectpicker.keydown.keyHistory||b.which===s.ENTER||b.which===s.TAB&&k.options.selectOnTab)&&(b.which!==s.SPACE&&b.preventDefault(),k.options.liveSearch&&b.which===s.SPACE||(k.$menuInner.find(".active a").trigger("click",!0),i.focus(),k.options.liveSearch||(b.preventDefault(),a(document).data("spaceSelect",!0))))},mobile:function(){this.$element.addClass("mobile-device")},refresh:function(){var b=a.extend({},this.options,this.$element.data());this.options=b,this.selectpicker.main.map.newIndex={},this.selectpicker.main.map.originalIndex={},this.createLi(),this.checkDisabled(),this.render(),this.setStyle(),this.setWidth(),this.setSize(!0),this.$element.trigger("refreshed.bs.select")},hide:function(){this.$newElement.hide()},show:function(){this.$newElement.show()},remove:function(){this.$newElement.remove(),this.$element.remove()},destroy:function(){this.$newElement.before(this.$element).remove(),this.$bsContainer?this.$bsContainer.remove():this.$menu.remove(),this.$element.off(".bs.select").removeData("selectpicker").removeClass("bs-select-hidden selectpicker")}};var y=a.fn.selectpicker;a.fn.selectpicker=g,a.fn.selectpicker.Constructor=x,a.fn.selectpicker.noConflict=function(){return a.fn.selectpicker=y,this},a(document).off("keydown.bs.dropdown.data-api").on("keydown.bs.select",'.bootstrap-select [data-toggle="dropdown"], .bootstrap-select [role="listbox"], .bs-searchbox input',x.prototype.keydown).on("focusin.modal",'.bootstrap-select [data-toggle="dropdown"], .bootstrap-select [role="listbox"], .bs-searchbox input',function(a){a.stopPropagation()}),a(window).on("load.bs.select.data-api",function(){a(".selectpicker").each(function(){var b=a(this);g.call(b,b.data())})})}(a)}); + //# sourceMappingURL=bootstrap-select.js.map + \ No newline at end of file diff --git a/test_web/static/js/index.js b/test_web/static/js/index.js index 8d4f91e..ff46807 100644 --- a/test_web/static/js/index.js +++ b/test_web/static/js/index.js @@ -1,17 +1,21 @@ -var all_plugins = undefined; -var plugin_arr = []; -var current_array = []; -var current_plugin_requirePath = undefined; +const state = { + all_plugins: {}, + plugin_arr: [], + current_array: [], + current_plugin: undefined, + filters: [], +} const language_selection = $('#language'); const plugin_search = $('#plugin'); const search_results = $('#search-results'); fetch('/all_plugins').then(res => res.json()).then(all => { - all_plugins = all; + state.all_plugins = all; + language_selection.html(``); for(let lang in all){ language_selection.append(``); - plugin_arr = plugin_arr.concat(all[lang]); + state.plugin_arr = state.plugin_arr.concat(all[lang]); } }); @@ -32,236 +36,329 @@ const display_search = (arr) => { } plugin_search.focus(e => { - if(!all_plugins) return; + if(!state.all_plugins) return; if(language_selection.val()){ - current_array = all_plugins[language_selection.val()]; + state.current_array = state.all_plugins[language_selection.val()]; }else{ - current_array = plugin_arr; + state.current_array = state.plugin_arr; } - display_search(current_array); + display_search(state.current_array); }); plugin_search.keyup(e => { - display_search(current_array.filter(plg => plg.name.toLowerCase().includes(plugin_search.val().toLowerCase()))); + display_search(state.current_array.filter(plg => plg.name.toLowerCase().includes(plugin_search.val().toLowerCase()))); }); $('#clear-search').click(e => { search_results.hide(); plugin_search.val(''); plugin_search.attr('data-require', ''); -}) +}); const test_plugin = (btn) => { const ele = $(btn); - current_plugin_requirePath = ele.attr('data-require'); - plugin_search.attr('data-require', current_plugin_requirePath); + plugin_requirePath = ele.attr('data-require'); + state.current_plugin = new Plugin(plugin_requirePath); + plugin_search.attr('data-require', plugin_requirePath); plugin_search.val(ele.text().split('/')[1]); search_results.hide(); + state.current_plugin.getfilters(); } -const popularNovels = () => { - if(!current_plugin_requirePath) return; - $('#popularNovels .spinner-border').show(); - fetch(`/popularNovels/`,{ - method: 'POST', - headers: { - "Content-Type": "application/json" - }, - body: JSON.stringify({"pluginRequirePath": current_plugin_requirePath}), - }) - .then(res => res.json()) - .then(novels => { - const novel_list = $('#popularNovels .novel-list'); - novel_list.html(''); - if(novels.error){ - novel_list.html(novels.error); - }else{ - novels.forEach(novel => { - novel_list.append(` -
- No cover found -
-
-
name
- ${novel.name?.slice(0, 50)} -
Copy
-
-
-
url
- ${novel.url?.slice(0, 50)} -
Copy
-
-
-
cover
- ${novel.cover?.slice(0, 50)} -
Copy
+ +class Plugin { + constructor(requirePath){ + this.requirePath = requirePath; + } + + getfilters = () => { + const makeSelect = (filter) => { + const container = document.createElement('div'); + const select = document.createElement('select'); + select.classList.add('select'); + if(filter.inputType === 2 || filter.inputType === "Checkbox"){ + select.setAttribute("multiple", ""); + }else{ + select.innerHTML = ``; + } + select.setAttribute("key", filter.key); + filter.values.forEach((v) => { + const option = document.createElement('option'); + option.setAttribute("value", v.value) + option.innerText = v.label; + select.append(option); + }); + container.append(select); + const label = document.createElement('label'); + label.classList.add("form-label"); + label.classList.add("select-label"); + label.innerText = filter.label; + container.append(label); + const hr = document.createElement('hr'); + hr.classList.add("hr"); + container.append(hr); + return container; + } + fetch("/filters", { + method: 'POST', + headers: { + "Content-Type": "application/json" + }, + body: JSON.stringify({"pluginRequirePath": this.requirePath}), + }).then(res => res.json()) + .then(filters => { + const filtersModal = $("#filtersModal .modal-body"); + filtersModal.html(""); + filters.forEach(filter => { + filtersModal.append(makeSelect(filter)) + }); + state.filters.length = 0; + document.querySelectorAll('select.select').forEach(e => { + const key = e.getAttribute("key"); + const select = new mdb.Select(e); + select.key = key; + state.filters.push(select); + }) + }) + } + + popularNovels = () => { + const filters = {}; + state.filters.forEach(_f => { + filters[_f.key] = _f.value; + }) + $('#popularNovels .spinner-border').show(); + fetch(`/popularNovels/`,{ + method: 'POST', + headers: { + "Content-Type": "application/json" + }, + body: JSON.stringify( + { + "pluginRequirePath": this.requirePath, + "filters": filters + } + ), + }) + .then(res => res.json()) + .then(novels => { + const novel_list = $('#popularNovels .novel-list'); + novel_list.html(''); + if(novels.error){ + novel_list.html(novels.error); + }else{ + novels.forEach(novel => { + novel_list.append(` +
+ No cover found +
+
+
name
+ ${novel.name?.slice(0, 50)} +
Copy
+
+
+
url
+ ${novel.url?.slice(0, 50)} +
Copy
+
+
+
cover
+ ${novel.cover?.slice(0, 50)} +
Copy
+
-
- `); - }) - } - $('#popularNovels .spinner-border').hide(); - }); -} - -const searchNovels = () => { - const searchTerm = $('#searchNovels input').val(); - if(!current_plugin_requirePath || !searchTerm) return; - $('#searchNovels .spinner-border').show(); - fetch(`/searchNovels/`,{ - method: 'POST', - headers: { - "Content-Type": "application/json" - }, - body: JSON.stringify({"pluginRequirePath": current_plugin_requirePath, "searchTerm": searchTerm}), - }) - .then(res => res.json()) - .then(novels => { - const novel_list = $('#searchNovels .novel-list'); - novel_list.html(''); - if(novels.error){ - novel_list.html(novels.error); - }else{ - novels.forEach(novel => { - novel_list.append(` -
- No cover found -
-
-
name
- ${novel.name?.slice(0, 50)} -
Copy
-
-
-
url
- ${novel.url?.slice(0, 50)} -
Copy
-
-
-
cover
- ${novel.cover?.slice(0, 50)} -
Copy
+ `); + }) + } + $('#popularNovels .spinner-border').hide(); + }); + } + + searchNovels = () => { + const searchTerm = $('#searchNovels input').val(); + $('#searchNovels .spinner-border').show(); + fetch(`/searchNovels/`,{ + method: 'POST', + headers: { + "Content-Type": "application/json" + }, + body: JSON.stringify({"pluginRequirePath": this.requirePath, "searchTerm": searchTerm}), + }) + .then(res => res.json()) + .then(novels => { + const novel_list = $('#searchNovels .novel-list'); + novel_list.html(''); + if(novels.error){ + novel_list.html(novels.error); + }else{ + novels.forEach(novel => { + novel_list.append(` +
+ No cover found +
+
+
name
+ ${novel.name?.slice(0, 50)} +
Copy
+
+
+
url
+ ${novel.url?.slice(0, 50)} +
Copy
+
+
+
cover
+ ${novel.cover?.slice(0, 50)} +
Copy
+
+ `); + }) + } + $('#searchNovels .spinner-border').hide(); + }); + } + + parseNovelAndChapters = () => { + const novelUrl = $('#parseNovelAndChapters input').val(); + $('#parseNovelAndChapters .spinner-border').show(); + fetch(`/parseNovelAndChapters/`,{ + method: 'POST', + headers: { + "Content-Type": "application/json" + }, + body: JSON.stringify({"pluginRequirePath": this.requirePath, "novelUrl": novelUrl}), + }) + .then(res => res.json()) + .then(sourceNovel => { + const novel_item = $('#parseNovelAndChapters .novel-list .novel-item'); + novel_item.html(` + No cover found +
+
+
name
+ ${sourceNovel.name?.slice(0, 50)} +
Copy
+
+
+
url
+ ${sourceNovel.url?.slice(0, 50)} +
Copy
+
+
+
cover
+ ${sourceNovel.cover?.slice(0, 50)} +
Copy
+
+
+
summary
+ ${sourceNovel.summary?.slice(0, 50)} +
Copy
+
+
+
author
+ ${sourceNovel.author} +
Copy
+
+
+
artist
+ ${sourceNovel.artist} +
Copy
+
+
+
status
+ ${sourceNovel.status} +
Copy
+
+
+
genres
+ ${sourceNovel.genres?.slice(0, 50)} +
Copy
+
- `); - }) - } - $('#searchNovels .spinner-border').hide(); - }); + `); + if(sourceNovel.error){ + novel_item.html(sourceNovel.error); + }else{ + const chapter_list = $('#parseNovelAndChapters .chapter-list'); + chapter_list.html(''); + sourceNovel.chapters.forEach(chapter => { + chapter_list.append(` +
+ ${chapter.name?.slice(0, 26)}
+ ${chapter.releaseTime} +
Copy url
+
+ `); + }) + } + $('#parseNovelAndChapters .spinner-border').hide(); + }); + } + + parseChapter = () => { + const chapterUrl = $('#parseChapter input').val(); + $('#parseChapter .spinner-border').show(); + fetch(`/parseChapter/`,{ + method: 'POST', + headers: { + "Content-Type": "application/json" + }, + body: JSON.stringify({"pluginRequirePath": this.requirePath, "chapterUrl": chapterUrl}), + }) + .then(res => res.json()) + .then(chapterText => { + $('#parseChapter textarea').text(chapterText); + $('#parseChapter .spinner-border').hide(); + }) + } + + fetchImage = () => { + const url = $('#fetchImage input').val(); + $('#fetchImage .spinner-border').show(); + fetch(`/fetchImage/`,{ + method: 'POST', + headers: { + "Content-Type": "application/json" + }, + body: JSON.stringify({"pluginRequirePath": this.requirePath, "url": url}), + }) + .then(res => res.json()) + .then(base64 => { + $('#fetchImage img').attr("src", `data:image/jpg;base64,${base64}`); + $('#fetchImage .spinner-border').hide(); + }) + } } -const parseNovelAndChapters = () => { - const novelUrl = $('#parseNovelAndChapters input').val(); - if(!current_plugin_requirePath || !novelUrl) return; - $('#parseNovelAndChapters .spinner-border').show(); - fetch(`/parseNovelAndChapters/`,{ - method: 'POST', - headers: { - "Content-Type": "application/json" - }, - body: JSON.stringify({"pluginRequirePath": current_plugin_requirePath, "novelUrl": novelUrl}), - }) - .then(res => res.json()) - .then(sourceNovel => { - const novel_item = $('#parseNovelAndChapters .novel-list .novel-item'); - novel_item.html(` - No cover found -
-
-
name
- ${sourceNovel.name?.slice(0, 50)} -
Copy
-
-
-
url
- ${sourceNovel.url?.slice(0, 50)} -
Copy
-
-
-
cover
- ${sourceNovel.cover?.slice(0, 50)} -
Copy
-
-
-
summary
- ${sourceNovel.summary?.slice(0, 50)} -
Copy
-
-
-
author
- ${sourceNovel.author} -
Copy
-
-
-
artist
- ${sourceNovel.artist} -
Copy
-
-
-
status
- ${sourceNovel.status} -
Copy
-
-
-
genres
- ${sourceNovel.genres?.slice(0, 50)} -
Copy
-
-
- `); - if(sourceNovel.error){ - novel_item.html(sourceNovel.error); - }else{ - const chapter_list = $('#parseNovelAndChapters .chapter-list'); - chapter_list.html(''); - sourceNovel.chapters.forEach(chapter => { - chapter_list.append(` -
- ${chapter.name?.slice(0, 26)}
- ${chapter.releaseTime} -
Copy url
-
- `); - }) - } - $('#parseNovelAndChapters .spinner-border').hide(); - }); -} +$(".popularNovels-btn").click(e => { + if(state.current_plugin){ + state.current_plugin.popularNovels(); + } +}); -const parseChapter = () => { - const chapterUrl = $('#parseChapter input').val(); - if(!current_plugin_requirePath || !chapterUrl) return; - $('#parseChapter .spinner-border').show(); - fetch(`/parseChapter/`,{ - method: 'POST', - headers: { - "Content-Type": "application/json" - }, - body: JSON.stringify({"pluginRequirePath": current_plugin_requirePath, "chapterUrl": chapterUrl}), - }) - .then(res => res.json()) - .then(chapterText => { - $('#parseChapter textarea').text(chapterText); - $('#parseChapter .spinner-border').hide(); - }) -} +$(".searchNovels-btn").click(e => { + if(state.current_plugin){ + state.current_plugin.searchNovels(); + } +}); -const fetchImage = () => { - const url = $('#fetchImage input').val(); - if(!current_plugin_requirePath || !url) return; - $('#fetchImage .spinner-border').show(); - fetch(`/fetchImage/`,{ - method: 'POST', - headers: { - "Content-Type": "application/json" - }, - body: JSON.stringify({"pluginRequirePath": current_plugin_requirePath, "url": url}), - }) - .then(res => res.json()) - .then(base64 => { - $('#fetchImage img').attr("src", `data:image/jpg;base64,${base64}`); - $('#fetchImage .spinner-border').hide(); - }) -} \ No newline at end of file +$(".parseNovelAndChapters-btn").click(e => { + if(state.current_plugin){ + state.current_plugin.parseNovelAndChapters(); + } +}); + +$(".parseChapter-btn").click(e => { + if(state.current_plugin){ + state.current_plugin.parseChapter(); + } +}); +$(".fetchImage-btn").click(e => { + if(state.current_plugin){ + state.current_plugin.fetchImage(); + } +}); diff --git a/test_web/static/js/jquery-3.6.4.min.js b/test_web/static/js/jquery.min.js similarity index 100% rename from test_web/static/js/jquery-3.6.4.min.js rename to test_web/static/js/jquery.min.js diff --git a/test_web/static/js/mdb5.js b/test_web/static/js/mdb5.js new file mode 100644 index 0000000..0d88f15 --- /dev/null +++ b/test_web/static/js/mdb5.js @@ -0,0 +1,19710 @@ +/*! + * + * Version: MDB Pro 6.4.2 + * + * Copyright: Material Design for Bootstrap + * https://mdbootstrap.com/ + * + * If you don't have a PRO license, you can purchase one here: + * https://mdbootstrap.com/docs/standard/pro/ + * + * Enterprise quotations, standard license & license customization: + * https://mdbootstrap.com/general/license/ + * + * Documentation: + * https://mdbootstrap.com/docs/standard/ + * + * Support: + * https://mdbootstrap.com/support/ + * + * Contact: + * contact@mdbootstrap.com + * + */ +!function(t, e) { + "object" == typeof exports && "object" == typeof module ? module.exports = e() : "function" == typeof define && define.amd ? define("mdb", [], e) : "object" == typeof exports ? exports.mdb = e() : t.mdb = e() +}(this, function() { + return n = [function(t, e, n) { + "use strict"; + n(17), + n(53); + function i(t) { + return "true" === t || "false" !== t && (t === Number(t).toString() ? Number(t) : "" === t || "null" === t ? null : t) + } + function o(t) { + return t.replace(/[A-Z]/g, t=>"-".concat(t.toLowerCase())) + } + e.a = { + setDataAttribute(t, e, n) { + t.setAttribute("data-mdb-".concat(o(e)), n) + }, + removeDataAttribute(t, e) { + t.removeAttribute("data-mdb-".concat(o(e))) + }, + getDataAttributes(t) { + if (!t) + return {}; + const n = { + ...t.dataset + }; + return Object.keys(n).filter(t=>t.startsWith("mdb")).forEach(t=>{ + let e = t.replace(/^mdb/, ""); + e = e.charAt(0).toLowerCase() + e.slice(1, e.length), + n[e] = i(n[t]) + } + ), + n + }, + getDataAttribute(t, e) { + return i(t.getAttribute("data-mdb-".concat(o(e)))) + }, + offset(t) { + t = t.getBoundingClientRect(); + return { + top: t.top + document.body.scrollTop, + left: t.left + document.body.scrollLeft + } + }, + position(t) { + return { + top: t.offsetTop, + left: t.offsetLeft + } + }, + style(t, e) { + Object.assign(t.style, e) + }, + toggleClass(t, e) { + t && (t.classList.contains(e) ? t.classList.remove(e) : t.classList.add(e)) + }, + addClass(t, e) { + t.classList.contains(e) || t.classList.add(e) + }, + addStyle(e, n) { + Object.keys(n).forEach(t=>{ + e.style[t] = n[t] + } + ) + }, + removeClass(t, e) { + t.classList.contains(e) && t.classList.remove(e) + }, + hasClass(t, e) { + return t.classList.contains(e) + } + } + } + , function(t, e, n) { + "use strict"; + n.d(e, "a", function() { + return a + }); + n(17), + n(53), + n(11), + n(12); + n = n(3); + const h = Object(n.f)() + , g = /[^.]*(?=\..*)\.|.*/ + , d = /\..*/ + , u = /::\d+$/ + , i = {}; + let o = 1; + const r = { + mouseenter: "mouseover", + mouseleave: "mouseout" + } + , p = ["click", "dblclick", "mouseup", "mousedown", "contextmenu", "mousewheel", "DOMMouseScroll", "mouseover", "mouseout", "mousemove", "selectstart", "selectend", "keydown", "keypress", "keyup", "orientationchange", "touchstart", "touchmove", "touchend", "touchcancel", "pointerdown", "pointermove", "pointerup", "pointerleave", "pointercancel", "gesturestart", "gesturechange", "gestureend", "focus", "blur", "change", "reset", "select", "submit", "focusin", "focusout", "load", "unload", "beforeunload", "resize", "move", "DOMContentLoaded", "readystatechange", "error", "abort", "scroll"]; + function m(t, e) { + return e && "".concat(e, "::").concat(o++) || t.uidEvent || o++ + } + function b(t) { + var e = m(t); + return t.uidEvent = e, + i[e] = i[e] || {}, + i[e] + } + function v(n, i, t) { + var o = 2 < arguments.length && void 0 !== t ? t : null + , r = Object.keys(n); + for (let t = 0, e = r.length; t < e; t++) { + var s = n[r[t]]; + if (s.originalHandler === i && s.delegationSelector === o) + return s + } + return null + } + function _(t, e, n) { + var i = "string" == typeof e + , n = i ? n : e; + let o = t.replace(d, ""); + e = r[o], + e && (o = e), + e = -1 < p.indexOf(o); + return [i, n, o = e ? o : t] + } + function s(t, e, n, i, o) { + var r, s, a, l, c, u, h, d, p, f; + "string" == typeof e && t && (n || (n = i, + i = null), + [r,s,a] = _(e, n, i), + (c = v(l = (l = b(t))[a] || (l[a] = {}), s, r ? n : null)) ? c.oneOff = c.oneOff && o : (c = m(s, e.replace(g, "")), + (e = r ? (d = t, + p = n, + f = i, + function n(i) { + var o = d.querySelectorAll(p); + for (let e = i["target"]; e && e !== this; e = e.parentNode) + for (let t = o.length; t--; ) + if (o[t] === e) + return i.delegateTarget = e, + n.oneOff && y.off(d, i.type, f), + f.apply(e, [i]); + return null + } + ) : (u = t, + h = n, + function t(e) { + return e.delegateTarget = u, + t.oneOff && y.off(u, e.type, h), + h.apply(u, [e]) + } + )).delegationSelector = r ? n : null, + e.originalHandler = s, + e.oneOff = o, + l[e.uidEvent = c] = e, + t.addEventListener(a, e, r))) + } + function f(t, e, n, i, o) { + i = v(e[n], i, o); + i && (t.removeEventListener(n, i, Boolean(o)), + delete e[n][i.uidEvent]) + } + const y = { + on(t, e, n, i) { + s(t, e, n, i, !1) + }, + one(t, e, n, i) { + s(t, e, n, i, !0) + }, + extend(i, t, o) { + t.forEach(t=>{ + y.on(i, "".concat(t.name, ".bs.").concat(o), e=>{ + const n = {}; + t.parametersToCopy && t.parametersToCopy.forEach(t=>{ + n[t] = e[t] + } + ), + y.trigger(i, "".concat(t.name, ".mdb.").concat(o), n).defaultPrevented && e.preventDefault() + } + ) + } + ) + }, + off(s, a, t, e) { + if ("string" == typeof a && s) { + const [n,i,o] = _(a, t, e) + , r = o !== a + , l = b(s); + e = "." === a.charAt(0); + if (void 0 !== i) + return l && l[o] ? void f(s, l, o, i, n ? t : null) : void 0; + e && Object.keys(l).forEach(t=>{ + { + var e = s + , n = l + , i = t + , o = a.slice(1); + const r = n[i] || {}; + Object.keys(r).forEach(t=>{ + -1 < t.indexOf(o) && (t = r[t], + f(e, n, i, t.originalHandler, t.delegationSelector)) + } + ) + } + } + ); + const c = l[o] || {}; + Object.keys(c).forEach(t=>{ + var e = t.replace(u, ""); + (!r || -1 < a.indexOf(e)) && (e = c[t], + f(s, l, o, e.originalHandler, e.delegationSelector)) + } + ) + } + }, + trigger(t, e, n) { + if ("string" != typeof e || !t) + return null; + var i = e.replace(d, "") + , o = e !== i + , r = -1 < p.indexOf(i); + let s, a = !0, l = !0, c = !1, u = null; + return o && h && (s = h.Event(e, n), + h(t).trigger(s), + a = !s.isPropagationStopped(), + l = !s.isImmediatePropagationStopped(), + c = s.isDefaultPrevented()), + r ? (u = document.createEvent("HTMLEvents")).initEvent(i, a, !0) : u = new CustomEvent(e,{ + bubbles: a, + cancelable: !0 + }), + void 0 !== n && Object.keys(n).forEach(t=>{ + Object.defineProperty(u, t, { + get() { + return n[t] + } + }) + } + ), + c && u.preventDefault(), + l && t.dispatchEvent(u), + u.defaultPrevented && void 0 !== s && s.preventDefault(), + u + } + } + , a = { + on(e, t, n, i) { + var o = t.split(" "); + for (let t = 0; t < o.length; t++) + y.on(e, o[t], n, i) + }, + off(e, t, n, i) { + var o = t.split(" "); + for (let t = 0; t < o.length; t++) + y.off(e, o[t], n, i) + } + }; + e.b = y + } + , function(t, e, n) { + "use strict"; + n(11), + n(12); + e.a = { + closest(t, e) { + return t.closest(e) + }, + matches(t, e) { + return t.matches(e) + }, + find(t) { + var e = 1 < arguments.length && void 0 !== arguments[1] ? arguments[1] : document.documentElement; + return [].concat(...Element.prototype.querySelectorAll.call(e, t)) + }, + findOne(t) { + var e = 1 < arguments.length && void 0 !== arguments[1] ? arguments[1] : document.documentElement; + return Element.prototype.querySelector.call(e, t) + }, + children(t, e) { + return [].concat(...t.children).filter(t=>t.matches(e)) + }, + parents(t, e) { + var n = []; + let i = t.parentNode; + for (; i && i.nodeType === Node.ELEMENT_NODE && 3 !== i.nodeType; ) + this.matches(i, e) && n.push(i), + i = i.parentNode; + return n + }, + prev(t, e) { + let n = t.previousElementSibling; + for (; n; ) { + if (n.matches(e)) + return [n]; + n = n.previousElementSibling + } + return [] + }, + next(t, e) { + let n = t.nextElementSibling; + for (; n; ) { + if (this.matches(n, e)) + return [n]; + n = n.nextElementSibling + } + return [] + } + } + } + , function(t, e, n) { + "use strict"; + n.d(e, "f", function() { + return c + }), + n.d(e, "e", function() { + return i + }), + n.d(e, "d", function() { + return r + }), + n.d(e, "c", function() { + return s + }), + n.d(e, "j", function() { + return a + }), + n.d(e, "h", function() { + return l + }), + n.d(e, "a", function() { + return d + }), + n.d(e, "b", function() { + return p + }), + n.d(e, "i", function() { + return u + }), + n.d(e, "g", function() { + return h + }); + n(17), + n(75), + n(72); + const i = t=>{ + for (; t += Math.floor(1e6 * Math.random()), + document.getElementById(t); ) + ; + return t + } + , o = t=>{ + let e = t.getAttribute("data-mdb-target"); + return e && "#" !== e || (t = t.getAttribute("href"), + e = t && "#" !== t ? t.trim() : null), + e + } + , r = t=>{ + t = o(t); + return t && document.querySelector(t) ? t : null + } + , s = t=>{ + t = o(t); + return t ? document.querySelector(t) : null + } + ; + const a = (o,r,s)=>{ + Object.keys(s).forEach(t=>{ + var e, n = s[t], i = r[t], i = i && ((e = i)[0] || e).nodeType ? "element" : null == (e = i) ? "".concat(e) : {}.toString.call(e).match(/\s([a-z]+)/i)[1].toLowerCase(); + if (!new RegExp(n).test(i)) + throw new Error("".concat(o.toUpperCase(), ": ") + 'Option "'.concat(t, '" provided type "').concat(i, '" ') + 'but expected type "'.concat(n, '".')) + } + ) + } + , l = t=>{ + var e; + return !!t && !!(t.style && t.parentNode && t.parentNode.style) && (e = getComputedStyle(t), + t = getComputedStyle(t.parentNode), + "none" !== e.display) && "none" !== t.display && "hidden" !== e.visibility + } + ; + const c = ()=>{ + var t = window["jQuery"]; + return t && !document.body.hasAttribute("data-mdb-no-jquery") ? t : null + } + , u = t=>{ + "loading" === document.readyState ? document.addEventListener("DOMContentLoaded", t) : t() + } + , h = "rtl" === document.documentElement.dir + , d = t=>Array.from(t) + , p = t=>document.createElement(t) + } + , function(t, e, n) { + "use strict"; + n.d(e, "a", function() { + return w + }), + n.d(e, "b", function() { + return O + }), + n.d(e, "c", function() { + return x + }), + n.d(e, "d", function() { + return g + }), + n.d(e, "e", function() { + return d + }), + n.d(e, "f", function() { + return c + }), + n.d(e, "j", function() { + return v + }), + n.d(e, "g", function() { + return S + }), + n.d(e, "h", function() { + return l + }), + n.d(e, "i", function() { + return o + }), + n.d(e, "k", function() { + return f + }), + n.d(e, "l", function() { + return h + }), + n.d(e, "m", function() { + return y + }), + n.d(e, "n", function() { + return p + }), + n.d(e, "o", function() { + return m + }), + n.d(e, "p", function() { + return b + }), + n.d(e, "r", function() { + return u + }), + n.d(e, "q", function() { + return i + }); + n(17), + n(28), + n(75), + n(11), + n(12); + const r = 1e3 + , s = "transitionend" + , i = t=>null == t ? "".concat(t) : Object.prototype.toString.call(t).match(/\s([a-z]+)/i)[1].toLowerCase() + , o = t=>{ + for (; t += Math.floor(1e6 * Math.random()), + document.getElementById(t); ) + ; + return t + } + , a = e=>{ + let n = e.getAttribute("data-mdb-target"); + if (!n || "#" === n) { + let t = e.getAttribute("href"); + if (!t || !t.includes("#") && !t.startsWith(".")) + return null; + t.includes("#") && !t.startsWith("#") && (t = "#".concat(t.split("#")[1])), + n = t && "#" !== t ? t.trim() : null + } + return n + } + , l = t=>{ + t = a(t); + return t && document.querySelector(t) ? t : null + } + , c = t=>{ + t = a(t); + return t ? document.querySelector(t) : null + } + , u = t=>{ + t.dispatchEvent(new Event(s)) + } + , h = t=>!(!t || "object" != typeof t) && void 0 !== (t = void 0 !== t.jquery ? t[0] : t).nodeType + , d = t=>h(t) ? t.jquery ? t[0] : t : "string" == typeof t && 0 < t.length ? document.querySelector(t) : null + , p = t=>{ + if (!h(t) || 0 === t.getClientRects().length) + return !1; + var e = "visible" === getComputedStyle(t).getPropertyValue("visibility") + , n = t.closest("details:not([open])"); + if (n && n !== t) { + t = t.closest("summary"); + if (t && t.parentNode !== n) + return !1; + if (null === t) + return !1 + } + return e + } + , f = t=>!t || t.nodeType !== Node.ELEMENT_NODE || !!t.classList.contains("disabled") || (void 0 !== t.disabled ? t.disabled : t.hasAttribute("disabled") && "false" !== t.getAttribute("disabled")) + , g = t=>{ + var e; + return document.documentElement.attachShadow ? "function" == typeof t.getRootNode ? (e = t.getRootNode())instanceof ShadowRoot ? e : null : t instanceof ShadowRoot ? t : t.parentNode ? g(t.parentNode) : null : null + } + , m = ()=>{} + , b = t=>{ + t.offsetHeight + } + , v = ()=>window.jQuery && !document.body.hasAttribute("data-mdb-no-jquery") ? window.jQuery : null + , _ = [] + , y = ()=>"rtl" === document.documentElement.dir + , w = i=>{ + var t; + t = ()=>{ + const t = v(); + if (t) { + const e = i.NAME + , n = t.fn[e]; + t.fn[e] = i.jQueryInterface, + t.fn[e].Constructor = i, + t.fn[e].noConflict = ()=>(t.fn[e] = n, + i.jQueryInterface) + } + } + , + "loading" === document.readyState ? (_.length || document.addEventListener("DOMContentLoaded", ()=>{ + for (const t of _) + t() + } + ), + _.push(t)) : t() + } + , O = t=>{ + "function" == typeof t && t() + } + , x = function(n, i) { + if (!(2 < arguments.length && void 0 !== arguments[2]) || arguments[2]) { + var t = (t=>{ + if (!t) + return 0; + let {transitionDuration: e, transitionDelay: n} = window.getComputedStyle(t); + var t = Number.parseFloat(e) + , i = Number.parseFloat(n); + return t || i ? (e = e.split(",")[0], + n = n.split(",")[0], + (Number.parseFloat(e) + Number.parseFloat(n)) * r) : 0 + } + )(i) + 5; + let e = !1; + const o = t=>{ + t = t.target; + t === i && (e = !0, + i.removeEventListener(s, o), + O(n)) + } + ; + i.addEventListener(s, o), + setTimeout(()=>{ + e || u(i) + } + , t) + } else + O(n) + } + , S = (t,e,n,i)=>{ + var o = t.length; + let r = t.indexOf(e); + return -1 === r ? !n && i ? t[o - 1] : t[0] : (r += n ? 1 : -1, + i && (r = (r + o) % o), + t[Math.max(0, Math.min(r, o - 1))]) + } + } + , function(t, e, n) { + "use strict"; + n.d(e, "u", function() { + return i + }), + n.d(e, "i", function() { + return o + }), + n.d(e, "s", function() { + return r + }), + n.d(e, "l", function() { + return s + }), + n.d(e, "d", function() { + return a + }), + n.d(e, "e", function() { + return l + }), + n.d(e, "t", function() { + return c + }), + n.d(e, "k", function() { + return u + }), + n.d(e, "j", function() { + return h + }), + n.d(e, "w", function() { + return d + }), + n.d(e, "p", function() { + return p + }), + n.d(e, "r", function() { + return f + }), + n.d(e, "v", function() { + return g + }), + n.d(e, "o", function() { + return m + }), + n.d(e, "g", function() { + return b + }), + n.d(e, "q", function() { + return v + }), + n.d(e, "b", function() { + return _ + }), + n.d(e, "f", function() { + return y + }), + n.d(e, "m", function() { + return w + }), + n.d(e, "a", function() { + return O + }), + n.d(e, "h", function() { + return x + }), + n.d(e, "x", function() { + return S + }), + n.d(e, "c", function() { + return C + }), + n.d(e, "n", function() { + return E + }); + var i = "top" + , o = "bottom" + , r = "right" + , s = "left" + , a = "auto" + , l = [i, o, r, s] + , c = "start" + , u = "end" + , h = "clippingParents" + , d = "viewport" + , p = "popper" + , f = "reference" + , g = l.reduce(function(t, e) { + return t.concat([e + "-" + c, e + "-" + u]) + }, []) + , m = [].concat(l, [a]).reduce(function(t, e) { + return t.concat([e, e + "-" + c, e + "-" + u]) + }, []) + , b = "beforeRead" + , v = "read" + , _ = "afterRead" + , y = "beforeMain" + , w = "main" + , O = "afterMain" + , x = "beforeWrite" + , S = "write" + , C = "afterWrite" + , E = [b, v, _, y, w, O, x, S, C] + } + , function(t, e, n) { + "use strict"; + n(11), + n(12), + n(17), + n(53), + n(28); + var l = n(4); + const g = /[^.]*(?=\..*)\.|.*/ + , i = /\..*/ + , y = /::\d+$/ + , o = {}; + let r = 1; + const m = { + mouseenter: "mouseover", + mouseleave: "mouseout" + } + , s = new Set(["click", "dblclick", "mouseup", "mousedown", "contextmenu", "mousewheel", "DOMMouseScroll", "mouseover", "mouseout", "mousemove", "selectstart", "selectend", "keydown", "keypress", "keyup", "orientationchange", "touchstart", "touchmove", "touchend", "touchcancel", "pointerdown", "pointermove", "pointerup", "pointerleave", "pointercancel", "gesturestart", "gesturechange", "gestureend", "focus", "blur", "change", "reset", "select", "submit", "focusin", "focusout", "load", "unload", "beforeunload", "resize", "move", "DOMContentLoaded", "readystatechange", "error", "abort", "scroll"]); + function b(t, e) { + return e && "".concat(e, "::").concat(r++) || t.uidEvent || r++ + } + function w(t) { + var e = b(t); + return t.uidEvent = e, + o[e] = o[e] || {}, + o[e] + } + function v(t, e, n) { + let i = 2 < arguments.length && void 0 !== n ? n : null; + return Object.values(t).find(t=>t.callable === e && t.delegationSelector === i) + } + function O(t, e, n) { + var i = "string" == typeof e + , e = !i && e || n; + let o = c(t); + return [i, e, o = s.has(o) ? o : t] + } + function a(i, o, r, s, a) { + if ("string" == typeof o && i) { + let[t,e,n] = O(o, r, s); + o in m && (e = (l = e, + function(t) { + if (!t.relatedTarget || t.relatedTarget !== t.delegateTarget && !t.delegateTarget.contains(t.relatedTarget)) + return l.call(this, t) + } + )); + var l, c, u, h, d, p, s = w(i), s = s[n] || (s[n] = {}), f = v(s, e, t ? r : null); + f ? f.oneOff = f.oneOff && a : (f = b(e, o.replace(g, "")), + (o = t ? (h = i, + d = r, + p = e, + function e(n) { + var i = h.querySelectorAll(d); + for (let t = n["target"]; t && t !== this; t = t.parentNode) + for (const o of i) + if (o === t) + return S(n, { + delegateTarget: t + }), + e.oneOff && _.off(h, n.type, d, p), + p.apply(t, [n]) + } + ) : (c = i, + u = e, + function t(e) { + return S(e, { + delegateTarget: c + }), + t.oneOff && _.off(c, e.type, u), + u.apply(c, [e]) + } + )).delegationSelector = t ? r : null, + o.callable = e, + o.oneOff = a, + s[o.uidEvent = f] = o, + i.addEventListener(n, o, t)) + } + } + function x(t, e, n, i, o) { + i = v(e[n], i, o); + i && (t.removeEventListener(n, i, Boolean(o)), + delete e[n][i.uidEvent]) + } + function c(t) { + return t = t.replace(i, ""), + m[t] || t + } + const _ = { + on(t, e, n, i) { + a(t, e, n, i, !1) + }, + one(t, e, n, i) { + a(t, e, n, i, !0) + }, + off(t, e, n, i) { + if ("string" == typeof e && t) { + var [i,o,r] = O(e, n, i) + , s = r !== e + , a = w(t) + , l = a[r] || {} + , c = e.startsWith("."); + if (void 0 !== o) + return Object.keys(l).length ? void x(t, a, r, o, i ? n : null) : void 0; + if (c) + for (const b of Object.keys(a)) { + u = g = f = p = d = h = void 0; + var u, h = t, d = a, p = b, f = e.slice(1), g = d[p] || {}; + for (const v of Object.keys(g)) + v.includes(f) && x(h, d, p, (u = g[v]).callable, u.delegationSelector) + } + for (const _ of Object.keys(l)) { + var m = _.replace(y, ""); + s && !e.includes(m) || x(t, a, r, (m = l[_]).callable, m.delegationSelector) + } + } + }, + trigger(t, e, n) { + if ("string" != typeof e || !t) + return null; + var i = Object(l.j)(); + let o = null + , r = !0 + , s = !0 + , a = !1; + e !== c(e) && i && (o = i.Event(e, n), + i(t).trigger(o), + r = !o.isPropagationStopped(), + s = !o.isImmediatePropagationStopped(), + a = o.isDefaultPrevented()); + i = S(i = new Event(e,{ + bubbles: r, + cancelable: !0 + }), n); + return a && i.preventDefault(), + s && t.dispatchEvent(i), + i.defaultPrevented && o && o.preventDefault(), + i + } + }; + function S(e, t) { + for (const [n,i] of Object.entries(t || {})) + try { + e[n] = i + } catch (t) { + Object.defineProperty(e, n, { + configurable: !0, + get() { + return i + } + }) + } + return e + } + e.a = _ + } + , function(t, e, n) { + "use strict"; + const i = (()=>{ + const i = {}; + let o = 1; + return { + set(t, e, n) { + void 0 === t[e] && (t[e] = { + key: e, + id: o + }, + o++), + i[t[e].id] = n + }, + get(t, e) { + return t && void 0 !== t[e] && (t = t[e]).key === e ? i[t.id] : null + }, + delete(t, e) { + var n; + void 0 !== t[e] && (n = t[e]).key === e && (delete i[n.id], + delete t[e]) + } + } + } + )(); + e.a = { + setData(t, e, n) { + i.set(t, e, n) + }, + getData(t, e) { + return i.get(t, e) + }, + removeData(t, e) { + i.delete(t, e) + } + } + } + , function(t, e, n) { + "use strict"; + n(11), + n(12); + var i = n(4); + e.a = { + find(t) { + var e = 1 < arguments.length && void 0 !== arguments[1] ? arguments[1] : document.documentElement; + return [].concat(...Element.prototype.querySelectorAll.call(e, t)) + }, + findOne(t) { + var e = 1 < arguments.length && void 0 !== arguments[1] ? arguments[1] : document.documentElement; + return Element.prototype.querySelector.call(e, t) + }, + children(t, e) { + return [].concat(...t.children).filter(t=>t.matches(e)) + }, + parents(t, e) { + var n = []; + let i = t.parentNode.closest(e); + for (; i; ) + n.push(i), + i = i.parentNode.closest(e); + return n + }, + prev(t, e) { + let n = t.previousElementSibling; + for (; n; ) { + if (n.matches(e)) + return [n]; + n = n.previousElementSibling + } + return [] + }, + next(t, e) { + let n = t.nextElementSibling; + for (; n; ) { + if (n.matches(e)) + return [n]; + n = n.nextElementSibling + } + return [] + }, + focusableChildren(t) { + var e = ["a", "button", "input", "textarea", "select", "details", "[tabindex]", '[contenteditable="true"]'].map(t=>"".concat(t, ':not([tabindex^="-"])')).join(","); + return this.find(e, t).filter(t=>!Object(i.k)(t) && Object(i.n)(t)) + } + } + } + , function(t, e, n) { + "use strict"; + n.d(e, "h", function() { + return i + }), + n.d(e, "n", function() { + return o + }), + n.d(e, "k", function() { + return r + }), + n.d(e, "c", function() { + return s + }), + n.d(e, "g", function() { + return a + }), + n.d(e, "d", function() { + return l + }), + n.d(e, "j", function() { + return c + }), + n.d(e, "i", function() { + return u + }), + n.d(e, "e", function() { + return h + }), + n.d(e, "l", function() { + return d + }), + n.d(e, "f", function() { + return p + }), + n.d(e, "m", function() { + return f + }), + n.d(e, "a", function() { + return g + }), + n.d(e, "b", function() { + return m + }); + const i = 37 + , o = 38 + , r = 39 + , s = 40 + , a = 36 + , l = 35 + , c = 33 + , u = 34 + , h = 13 + , d = 32 + , p = 27 + , f = 9 + , g = 8 + , m = 46 + } + , function(t, e, n) { + "use strict"; + n.d(e, "a", function() { + return o + }), + n.d(e, "b", function() { + return r + }), + n.d(e, "c", function() { + return s + }); + var i = n(19); + function o(t) { + return t instanceof Object(i.a)(t).Element || t instanceof Element + } + function r(t) { + return t instanceof Object(i.a)(t).HTMLElement || t instanceof HTMLElement + } + function s(t) { + return "undefined" != typeof ShadowRoot && (t instanceof Object(i.a)(t).ShadowRoot || t instanceof ShadowRoot) + } + } + , function(t, e, n) { + "use strict"; + var i = n(77) + , o = n(158) + , r = n(81) + , s = n(46) + , a = n(40).f + , l = n(161) + , c = n(165) + , u = n(43) + , n = n(23) + , h = "Array Iterator" + , d = s.set + , p = s.getterFor(h) + , s = (t.exports = l(Array, "Array", function(t, e) { + d(this, { + type: h, + target: i(t), + index: 0, + kind: e + }) + }, function() { + var t = p(this) + , e = t.target + , n = t.kind + , i = t.index++; + if (!e || i >= e.length) + return t.target = void 0, + c(void 0, !0); + switch (n) { + case "keys": + return c(i, !1); + case "values": + return c(e[i], !1) + } + return c([i, e[i]], !1) + }, "values"), + r.Arguments = r.Array); + if (o("keys"), + o("values"), + o("entries"), + !u && n && "values" !== s.name) + try { + a(s, "name", { + value: "values" + }) + } catch (t) {} + } + , function(t, e, n) { + "use strict"; + function i(e, t) { + if (e) { + if (e[u] !== d) + try { + c(e, u, d) + } catch (t) { + e[u] = d + } + if (e[h] || c(e, h, t), + s[t]) + for (var n in l) + if (e[n] !== l[n]) + try { + c(e, n, l[n]) + } catch (t) { + e[n] = l[n] + } + } + } + var o, r = n(13), s = n(217), a = n(218), l = n(11), c = n(57), n = n(20), u = n("iterator"), h = n("toStringTag"), d = l.values; + for (o in s) + i(r[o] && r[o].prototype, o); + i(a, "DOMTokenList") + } + , function(n, t, e) { + "use strict"; + !function(t) { + function e(t) { + return t && t.Math === Math && t + } + n.exports = e("object" == typeof globalThis && globalThis) || e("object" == typeof window && window) || e("object" == typeof self && self) || e("object" == typeof t && t) || function() { + return this + }() || this || Function("return this")() + } + .call(this, e(206)) + } + , function(t, e, n) { + "use strict"; + var n = n(89) + , i = Function.prototype + , o = i.call + , i = n && i.bind.bind(o, o); + t.exports = n ? i : function(t) { + return function() { + return o.apply(t, arguments) + } + } + } + , function(t, e, n) { + "use strict"; + var n = n(143) + , i = n.all; + t.exports = n.IS_HTMLDDA ? function(t) { + return "function" == typeof t || t === i + } + : function(t) { + return "function" == typeof t + } + } + , function(t, e, n) { + "use strict"; + t.exports = function(t) { + try { + return !!t() + } catch (t) { + return !0 + } + } + } + , function(t, e, n) { + "use strict"; + var i = n(26) + , n = n(124); + i({ + target: "RegExp", + proto: !0, + forced: /./.exec !== n + }, { + exec: n + }) + } + , function(t, e, n) { + "use strict"; + n.d(e, "a", function() { + return i + }), + n.d(e, "b", function() { + return o + }), + n.d(e, "c", function() { + return r + }); + var i = Math.max + , o = Math.min + , r = Math.round + } + , function(t, e, n) { + "use strict"; + function i(t) { + var e; + return null == t ? window : "[object Window]" !== t.toString() ? (e = t.ownerDocument) && e.defaultView || window : t + } + n.d(e, "a", function() { + return i + }) + } + , function(t, e, n) { + "use strict"; + var i = n(13) + , o = n(114) + , r = n(29) + , s = n(147) + , a = n(146) + , n = n(145) + , l = i.Symbol + , c = o("wks") + , u = n ? l.for || l : l && l.withoutSetter || s; + t.exports = function(t) { + return r(c, t) || (c[t] = a && r(l, t) ? l[t] : u("Symbol." + t)), + c[t] + } + } + , function(t, e, n) { + "use strict"; + n(11), + n(12); + const i = new Map; + var o = function(t, e, n) { + i.has(t) || i.set(t, new Map); + t = i.get(t); + t.has(e) || 0 === t.size ? t.set(e, n) : console.error("Bootstrap doesn't allow more than one instance per element. Bound instance: ".concat(Array.from(t.keys())[0], ".")) + } + , r = function(t, e) { + return i.has(t) && i.get(t).get(e) || null + } + , s = function(t, e) { + var n; + i.has(t) && ((n = i.get(t)).delete(e), + 0 === n.size) && i.delete(t) + } + , a = n(4) + , l = n(6) + , n = n(45); + class c extends n.a { + constructor(t, e) { + super(), + (t = Object(a.e)(t)) && (this._element = t, + this._config = this._getConfig(e), + o(this._element, this.constructor.DATA_KEY, this)) + } + dispose() { + s(this._element, this.constructor.DATA_KEY), + l.a.off(this._element, this.constructor.EVENT_KEY); + for (const t of Object.getOwnPropertyNames(this)) + this[t] = null + } + _queueCallback(t, e) { + var n = !(2 < arguments.length && void 0 !== arguments[2]) || arguments[2]; + Object(a.c)(t, e, n) + } + _getConfig(t) { + return t = this._mergeConfigObj(t, this._element), + t = this._configAfterMerge(t), + this._typeCheckConfig(t), + t + } + static getInstance(t) { + return r(Object(a.e)(t), this.DATA_KEY) + } + static getOrCreateInstance(t) { + var e = 1 < arguments.length && void 0 !== arguments[1] ? arguments[1] : {}; + return this.getInstance(t) || new this(t,"object" == typeof e ? e : null) + } + static get VERSION() { + return "5.2.3" + } + static get DATA_KEY() { + return "bs.".concat(this.NAME) + } + static get EVENT_KEY() { + return ".".concat(this.DATA_KEY) + } + static eventName(t) { + return "".concat(t).concat(this.EVENT_KEY) + } + } + e.a = c + } + , function(t, e, n) { + "use strict"; + var n = n(89) + , i = Function.prototype.call; + t.exports = n ? i.bind(i) : function() { + return i.apply(i, arguments) + } + } + , function(t, e, n) { + "use strict"; + n = n(16); + t.exports = !n(function() { + return 7 !== Object.defineProperty({}, 1, { + get: function() { + return 7 + } + })[1] + }) + } + , function(t, e, n) { + "use strict"; + function i(t) { + return t ? (t.nodeName || "").toLowerCase() : null + } + n.d(e, "a", function() { + return i + }) + } + , function(t, e, n) { + "use strict"; + function i(t) { + return t.split("-")[0] + } + n.d(e, "a", function() { + return i + }) + } + , function(t, e, n) { + "use strict"; + var c = n(13) + , u = n(111).f + , h = n(57) + , d = n(41) + , p = n(116) + , f = n(151) + , g = n(122); + t.exports = function(t, e) { + var n, i, o, r = t.target, s = t.global, a = t.stat, l = s ? c : a ? c[r] || p(r, {}) : (c[r] || {}).prototype; + if (l) + for (n in e) { + if (i = e[n], + o = t.dontCallGetSet ? (o = u(l, n)) && o.value : l[n], + !g(s ? n : r + (a ? "." : "#") + n, t.forced) && void 0 !== o) { + if (typeof i == typeof o) + continue; + f(i, o) + } + (t.sham || o && o.sham) && h(i, "sham", !0), + d(l, n, i, t) + } + } + } + , function(t, e, n) { + "use strict"; + n.d(e, "a", function() { + return o + }); + var i = n(10); + function o(t) { + return ((Object(i.a)(t) ? t.ownerDocument : t.document) || window.document).documentElement + } + } + , function(t, e, n) { + "use strict"; + var i = n(26) + , o = n(154).includes + , r = n(16) + , n = n(158); + i({ + target: "Array", + proto: !0, + forced: r(function() { + return !Array(1).includes() + }) + }, { + includes: function(t) { + return o(this, t, 1 < arguments.length ? arguments[1] : void 0) + } + }), + n("includes") + } + , function(t, e, n) { + "use strict"; + var i = n(14) + , o = n(50) + , r = i({}.hasOwnProperty); + t.exports = Object.hasOwn || function(t, e) { + return r(o(t), e) + } + } + , function(t, e, n) { + "use strict"; + var i = n(35) + , o = String + , r = TypeError; + t.exports = function(t) { + if (i(t)) + return t; + throw r(o(t) + " is not an object") + } + } + , , function(t, e, n) { + "use strict"; + n.d(e, "a", function() { + return i + }); + var d = n(5) + , h = n(19) + , p = n(27) + , f = n(66) + , g = n(106); + var m = n(33) + , b = n(67) + , v = n(18); + var a = n(70) + , l = n(42) + , _ = n(10) + , y = n(36) + , c = n(47) + , u = n(107) + , w = n(24); + function O(t) { + return Object.assign({}, t, { + left: t.x, + top: t.y, + right: t.x + t.width, + bottom: t.y + t.height + }) + } + function x(t, e, n) { + return e === d.w ? O((i = t, + o = n, + s = Object(h.a)(i), + a = Object(p.a)(i), + s = s.visualViewport, + l = a.clientWidth, + a = a.clientHeight, + u = c = 0, + s && (l = s.width, + a = s.height, + (r = Object(g.a)()) || !r && "fixed" === o) && (c = s.offsetLeft, + u = s.offsetTop), + { + width: l, + height: a, + x: c + Object(f.a)(i), + y: u + })) : Object(_.a)(e) ? (r = e, + o = n, + (o = Object(y.a)(r, !1, "fixed" === o)).top = o.top + r.clientTop, + o.left = o.left + r.clientLeft, + o.bottom = o.top + r.clientHeight, + o.right = o.left + r.clientWidth, + o.width = r.clientWidth, + o.height = r.clientHeight, + o.x = o.left, + o.y = o.top, + o) : O((s = Object(p.a)(t), + l = Object(p.a)(s), + a = Object(b.a)(s), + c = null == (c = s.ownerDocument) ? void 0 : c.body, + i = Object(v.a)(l.scrollWidth, l.clientWidth, c ? c.scrollWidth : 0, c ? c.clientWidth : 0), + u = Object(v.a)(l.scrollHeight, l.clientHeight, c ? c.scrollHeight : 0, c ? c.clientHeight : 0), + s = -a.scrollLeft + Object(f.a)(s), + a = -a.scrollTop, + "rtl" === Object(m.a)(c || l).direction && (s += Object(v.a)(l.clientWidth, c ? c.clientWidth : 0) - i), + { + width: i, + height: u, + x: s, + y: a + })); + var i, o, r, s, a, l, c, u + } + function S(n, t, e, i) { + var o, r = "clippingParents" === t ? (r = n, + s = Object(a.a)(Object(c.a)(r)), + o = 0 <= ["absolute", "fixed"].indexOf(Object(m.a)(r).position) && Object(_.b)(r) ? Object(l.a)(r) : r, + Object(_.a)(o) ? s.filter(function(t) { + return Object(_.a)(t) && Object(u.a)(t, o) && "body" !== Object(w.a)(t) + }) : []) : [].concat(t), s = [].concat(r, [e]), t = s[0], e = s.reduce(function(t, e) { + e = x(n, e, i); + return t.top = Object(v.a)(e.top, t.top), + t.right = Object(v.b)(e.right, t.right), + t.bottom = Object(v.b)(e.bottom, t.bottom), + t.left = Object(v.a)(e.left, t.left), + t + }, x(n, t, i)); + return e.width = e.right - e.left, + e.height = e.bottom - e.top, + e.x = e.left, + e.y = e.top, + e + } + var C = n(108) + , E = n(103) + , k = n(105); + function i(t, e) { + var i, e = e = void 0 === e ? {} : e, n = e.placement, n = void 0 === n ? t.placement : n, o = e.strategy, o = void 0 === o ? t.strategy : o, r = e.boundary, r = void 0 === r ? d.j : r, s = e.rootBoundary, s = void 0 === s ? d.w : s, a = e.elementContext, a = void 0 === a ? d.p : a, l = e.altBoundary, l = void 0 !== l && l, e = e.padding, e = void 0 === e ? 0 : e, e = Object(E.a)("number" != typeof e ? e : Object(k.a)(e, d.e)), c = a === d.p ? d.r : d.p, u = t.rects.popper, l = t.elements[l ? c : a], c = S(Object(_.a)(l) ? l : l.contextElement || Object(p.a)(t.elements.popper), r, s, o), l = Object(y.a)(t.elements.reference), r = Object(C.a)({ + reference: l, + element: u, + strategy: "absolute", + placement: n + }), s = O(Object.assign({}, u, r)), o = a === d.p ? s : l, h = { + top: c.top - o.top + e.top, + bottom: o.bottom - c.bottom + e.bottom, + left: c.left - o.left + e.left, + right: o.right - c.right + e.right + }, u = t.modifiersData.offset; + return a === d.p && u && (i = u[n], + Object.keys(h).forEach(function(t) { + var e = 0 <= [d.s, d.i].indexOf(t) ? 1 : -1 + , n = 0 <= [d.u, d.i].indexOf(t) ? "y" : "x"; + h[t] += i[n] * e + })), + h + } + } + , function(t, e, n) { + "use strict"; + n.d(e, "a", function() { + return o + }); + var i = n(19); + function o(t) { + return Object(i.a)(t).getComputedStyle(t) + } + } + , function(t, e, n) { + "use strict"; + n(17), + n(53), + n(11), + n(12); + function o(e) { + if ("true" === e) + return !0; + if ("false" === e) + return !1; + if (e === Number(e).toString()) + return Number(e); + if ("" === e || "null" === e) + return null; + if ("string" != typeof e) + return e; + try { + return JSON.parse(decodeURIComponent(e)) + } catch (t) { + return e + } + } + function i(t) { + return t.replace(/[A-Z]/g, t=>"-".concat(t.toLowerCase())) + } + e.a = { + setDataAttribute(t, e, n) { + t.setAttribute("data-mdb-".concat(i(e)), n) + }, + removeDataAttribute(t, e) { + t.removeAttribute("data-mdb-".concat(i(e))) + }, + getDataAttributes(e) { + if (!e) + return {}; + var n = {}; + for (const i of Object.keys(e.dataset).filter(t=>t.startsWith("mdb") && !t.startsWith("mdbConfig"))) { + let t = i.replace(/^mdb/, ""); + n[t = t.charAt(0).toLowerCase() + t.slice(1, t.length)] = o(e.dataset[i]) + } + return n + }, + getDataAttribute(t, e) { + return o(t.getAttribute("data-mdb-".concat(i(e)))) + } + } + } + , function(t, e, n) { + "use strict"; + var i = n(15) + , n = n(143) + , o = n.all; + t.exports = n.IS_HTMLDDA ? function(t) { + return "object" == typeof t ? null !== t : i(t) || t === o + } + : function(t) { + return "object" == typeof t ? null !== t : i(t) + } + } + , function(t, e, n) { + "use strict"; + n.d(e, "a", function() { + return i + }); + var s = n(10) + , a = n(18) + , l = n(19) + , c = n(106); + function i(t, e, n) { + void 0 === e && (e = !1), + void 0 === n && (n = !1); + var i = t.getBoundingClientRect() + , o = 1 + , r = 1; + e && Object(s.b)(t) && (o = 0 < t.offsetWidth && Object(a.c)(i.width) / t.offsetWidth || 1, + r = 0 < t.offsetHeight && Object(a.c)(i.height) / t.offsetHeight || 1); + e = (Object(s.a)(t) ? Object(l.a)(t) : window).visualViewport, + t = !Object(c.a)() && n, + n = (i.left + (t && e ? e.offsetLeft : 0)) / o, + t = (i.top + (t && e ? e.offsetTop : 0)) / r, + e = i.width / o, + o = i.height / r; + return { + width: e, + height: o, + top: t, + right: n + e, + bottom: t + o, + left: n, + x: n, + y: t + } + } + } + , function(t, e, n) { + "use strict"; + function i(t) { + return t.split("-")[1] + } + n.d(e, "a", function() { + return i + }) + } + , function(t, e, n) { + "use strict"; + var i = n(93) + , o = String; + t.exports = function(t) { + if ("Symbol" === i(t)) + throw TypeError("Cannot convert a Symbol value to a string"); + return o(t) + } + } + , function(t, e, n) { + "use strict"; + var i = n(15) + , o = n(78) + , r = TypeError; + t.exports = function(t) { + if (i(t)) + return t; + throw r(o(t) + " is not a function") + } + } + , function(t, e, n) { + "use strict"; + var i = n(23) + , o = n(148) + , r = n(149) + , s = n(30) + , a = n(113) + , l = TypeError + , c = Object.defineProperty + , u = Object.getOwnPropertyDescriptor + , h = "enumerable" + , d = "configurable" + , p = "writable"; + e.f = i ? r ? function(t, e, n) { + var i; + return s(t), + e = a(e), + s(n), + "function" == typeof t && "prototype" === e && "value"in n && p in n && !n[p] && (i = u(t, e)) && i[p] && (t[e] = n.value, + n = { + configurable: (d in n ? n : i)[d], + enumerable: (h in n ? n : i)[h], + writable: !1 + }), + c(t, e, n) + } + : c : function(t, e, n) { + if (s(t), + e = a(e), + s(n), + o) + try { + return c(t, e, n) + } catch (t) {} + if ("get"in n || "set"in n) + throw l("Accessors not supported"); + return "value"in n && (t[e] = n.value), + t + } + } + , function(t, e, n) { + "use strict"; + var s = n(15) + , a = n(40) + , l = n(150) + , c = n(116); + t.exports = function(t, e, n, i) { + var o = (i = i || {}).enumerable + , r = void 0 !== i.name ? i.name : e; + if (s(n) && l(n, r, i), + i.global) + o ? t[e] = n : c(e, n); + else { + try { + i.unsafe ? t[e] && (o = !0) : delete t[e] + } catch (t) {} + o ? t[e] = n : a.f(t, e, { + value: n, + enumerable: !1, + configurable: !i.nonConfigurable, + writable: !i.nonWritable + }) + } + return t + } + } + , function(t, e, n) { + "use strict"; + n.d(e, "a", function() { + return i + }); + var o = n(19) + , r = n(24) + , s = n(33) + , a = n(10); + var l = n(47) + , c = n(87); + function u(t) { + return Object(a.b)(t) && "fixed" !== Object(s.a)(t).position ? t.offsetParent : null + } + function i(t) { + for (var e, n = Object(o.a)(t), i = u(t); i && (e = i, + 0 <= ["table", "td", "th"].indexOf(Object(r.a)(e))) && "static" === Object(s.a)(i).position; ) + i = u(i); + return (!i || "html" !== Object(r.a)(i) && ("body" !== Object(r.a)(i) || "static" !== Object(s.a)(i).position)) && (i || function(t) { + var e = /firefox/i.test(Object(c.a)()) + , n = /Trident/i.test(Object(c.a)()); + if (!n || !Object(a.b)(t) || "fixed" !== Object(s.a)(t).position) { + var i = Object(l.a)(t); + for (Object(a.c)(i) && (i = i.host); Object(a.b)(i) && ["html", "body"].indexOf(Object(r.a)(i)) < 0; ) { + var o = Object(s.a)(i); + if ("none" !== o.transform || "none" !== o.perspective || "paint" === o.contain || -1 !== ["transform", "perspective"].indexOf(o.willChange) || e && "filter" === o.willChange || e && o.filter && "none" !== o.filter) + return i; + i = i.parentNode + } + } + return null + }(t)) || n + } + } + , function(t, e, n) { + "use strict"; + t.exports = !1 + } + , function(t, e, n) { + "use strict"; + n.d(e, "b", function() { + return i + }), + n.d(e, "a", function() { + return o + }); + var l = n(36) + , c = n(67) + , u = n(19) + , p = n(10); + var h = n(24) + , d = n(66) + , f = n(27) + , g = n(68) + , m = n(18); + function b(t, e, n) { + void 0 === n && (n = !1); + var i = Object(p.b)(e) + , o = Object(p.b)(e) && (s = (o = e).getBoundingClientRect(), + r = Object(m.c)(s.width) / o.offsetWidth || 1, + s = Object(m.c)(s.height) / o.offsetHeight || 1, + 1 !== r || 1 !== s) + , r = Object(f.a)(e) + , s = Object(l.a)(t, o, n) + , t = { + scrollLeft: 0, + scrollTop: 0 + } + , a = { + x: 0, + y: 0 + }; + return !i && n || ("body" === Object(h.a)(e) && !Object(g.a)(r) || (t = (i = e) !== Object(u.a)(i) && Object(p.b)(i) ? { + scrollLeft: i.scrollLeft, + scrollTop: i.scrollTop + } : Object(c.a)(i)), + Object(p.b)(e) ? ((a = Object(l.a)(e, !0)).x += e.clientLeft, + a.y += e.clientTop) : r && (a.x = Object(d.a)(r))), + { + x: s.left + t.scrollLeft - a.x, + y: s.top + t.scrollTop - a.y, + width: s.width, + height: s.height + } + } + var v = n(65) + , _ = n(70) + , y = n(42) + , w = n(5); + function O(t) { + var n = new Map + , i = new Set + , o = []; + return t.forEach(function(t) { + n.set(t.name, t) + }), + t.forEach(function(t) { + i.has(t.name) || !function e(t) { + i.add(t.name), + [].concat(t.requires || [], t.requiresIfExists || []).forEach(function(t) { + i.has(t) || (t = n.get(t)) && e(t) + }), + o.push(t) + }(t) + }), + o + } + var x = { + placement: "bottom", + modifiers: [], + strategy: "absolute" + }; + function S() { + for (var t = arguments.length, e = new Array(t), n = 0; n < t; n++) + e[n] = arguments[n]; + return !e.some(function(t) { + return !(t && "function" == typeof t.getBoundingClientRect) + }) + } + function i(t) { + var t = t = void 0 === t ? {} : t + , e = t.defaultModifiers + , h = void 0 === e ? [] : e + , e = t.defaultOptions + , d = void 0 === e ? x : e; + return function(i, o, e) { + void 0 === e && (e = d); + var n, r, s = { + placement: "bottom", + orderedModifiers: [], + options: Object.assign({}, x, d), + modifiersData: {}, + elements: { + reference: i, + popper: o + }, + attributes: {}, + styles: {} + }, a = [], l = !1, c = { + state: s, + setOptions: function(t) { + var n, e, t = "function" == typeof t ? t(s.options) : t, t = (u(), + s.options = Object.assign({}, d, s.options, t), + s.scrollParents = { + reference: Object(p.a)(i) ? Object(_.a)(i) : i.contextElement ? Object(_.a)(i.contextElement) : [], + popper: Object(_.a)(o) + }, + t = [].concat(h, s.options.modifiers), + e = t.reduce(function(t, e) { + var n = t[e.name]; + return t[e.name] = n ? Object.assign({}, n, e, { + options: Object.assign({}, n.options, e.options), + data: Object.assign({}, n.data, e.data) + }) : e, + t + }, {}), + t = Object.keys(e).map(function(t) { + return e[t] + }), + n = O(t), + w.n.reduce(function(t, e) { + return t.concat(n.filter(function(t) { + return t.phase === e + })) + }, [])); + return s.orderedModifiers = t.filter(function(t) { + return t.enabled + }), + s.orderedModifiers.forEach(function(t) { + var e = t.name + , n = t.options + , t = t.effect; + "function" == typeof t && (t = t({ + state: s, + name: e, + instance: c, + options: void 0 === n ? {} : n + }), + a.push(t || function() {} + )) + }), + c.update() + }, + forceUpdate: function() { + if (!l) { + var t = s.elements + , e = t.reference + , t = t.popper; + if (S(e, t)) { + s.rects = { + reference: b(e, Object(y.a)(t), "fixed" === s.options.strategy), + popper: Object(v.a)(t) + }, + s.reset = !1, + s.placement = s.options.placement, + s.orderedModifiers.forEach(function(t) { + return s.modifiersData[t.name] = Object.assign({}, t.data) + }); + for (var n, i, o, r = 0; r < s.orderedModifiers.length; r++) + !0 === s.reset ? (s.reset = !1, + r = -1) : (n = (o = s.orderedModifiers[r]).fn, + i = o.options, + o = o.name, + "function" == typeof n && (s = n({ + state: s, + options: void 0 === i ? {} : i, + name: o, + instance: c + }) || s)) + } + } + }, + update: (n = function() { + return new Promise(function(t) { + c.forceUpdate(), + t(s) + } + ) + } + , + function() { + return r = r || new Promise(function(t) { + Promise.resolve().then(function() { + r = void 0, + t(n()) + }) + } + ) + } + ), + destroy: function() { + u(), + l = !0 + } + }; + return S(i, o) && c.setOptions(e).then(function(t) { + !l && e.onFirstUpdate && e.onFirstUpdate(t) + }), + c; + function u() { + a.forEach(function(t) { + return t() + }), + a = [] + } + } + } + var o = i() + } + , function(t, e, n) { + "use strict"; + n(11), + n(12), + n(17), + n(72); + var r = n(4) + , i = n(34); + e.a = class { + static get Default() { + return {} + } + static get DefaultType() { + return {} + } + static get NAME() { + throw new Error('You have to implement the static method "NAME", for each component!') + } + _getConfig(t) { + return t = this._mergeConfigObj(t), + t = this._configAfterMerge(t), + this._typeCheckConfig(t), + t + } + _configAfterMerge(t) { + return t + } + _mergeConfigObj(t, e) { + var n = Object(r.l)(e) ? i.a.getDataAttribute(e, "config") : {}; + return { + ...this.constructor.Default, + ..."object" == typeof n ? n : {}, + ...Object(r.l)(e) ? i.a.getDataAttributes(e) : {}, + ..."object" == typeof t ? t : {} + } + } + _typeCheckConfig(t) { + var e = 1 < arguments.length && void 0 !== arguments[1] ? arguments[1] : this.constructor.DefaultType; + for (const o of Object.keys(e)) { + var n = e[o] + , i = t[o] + , i = Object(r.l)(i) ? "element" : Object(r.q)(i); + if (!new RegExp(n).test(i)) + throw new TypeError("".concat(this.constructor.NAME.toUpperCase(), ': Option "').concat(o, '" provided type "').concat(i, '" but expected type "').concat(n, '".')) + } + } + } + } + , function(t, e, n) { + "use strict"; + var i, o, r, s, a = n(209), l = n(13), c = n(35), u = n(57), h = n(29), d = n(115), p = n(119), n = n(120), f = "Object already initialized", g = l.TypeError, l = l.WeakMap, m = a || d.state ? ((r = d.state || (d.state = new l)).get = r.get, + r.has = r.has, + r.set = r.set, + i = function(t, e) { + if (r.has(t)) + throw g(f); + return e.facade = t, + r.set(t, e), + e + } + , + o = function(t) { + return r.get(t) || {} + } + , + function(t) { + return r.has(t) + } + ) : (n[s = p("state")] = !0, + i = function(t, e) { + if (h(t, s)) + throw g(f); + return e.facade = t, + u(t, s, e), + e + } + , + o = function(t) { + return h(t, s) ? t[s] : {} + } + , + function(t) { + return h(t, s) + } + ); + t.exports = { + set: i, + get: o, + has: m, + enforce: function(t) { + return m(t) ? o(t) : i(t, {}) + }, + getterFor: function(e) { + return function(t) { + if (c(t) && (t = o(t)).type === e) + return t; + throw g("Incompatible receiver, " + e + " required") + } + } + } + } + , function(t, e, n) { + "use strict"; + n.d(e, "a", function() { + return s + }); + var i = n(24) + , o = n(27) + , r = n(10); + function s(t) { + return "html" === Object(i.a)(t) ? t : t.assignedSlot || t.parentNode || (Object(r.c)(t) ? t.host : null) || Object(o.a)(t) + } + } + , function(t, e, n) { + "use strict"; + var i = n(13) + , o = n(15); + t.exports = function(t, e) { + return arguments.length < 2 ? (n = i[t], + o(n) ? n : void 0) : i[t] && i[t][e]; + var n + } + } + , function(t, e, n) { + "use strict"; + t.exports = "undefined" != typeof navigator && String(navigator.userAgent) || "" + } + , function(t, e, n) { + "use strict"; + var i = n(73) + , o = Object; + t.exports = function(t) { + return o(i(t)) + } + } + , function(t, e, n) { + "use strict"; + n.d(e, "a", function() { + return o + }), + n.d(e, "b", function() { + return r + }); + var i = n(18); + function o(t, e, n) { + return Object(i.a)(t, Object(i.b)(e, n)) + } + function r(t, e, n) { + t = o(t, e, n); + return n < t ? n : t + } + } + , function(t, e, n) { + "use strict"; + n(11), + n(12), + n(28), + n(17); + var r = n(4) + , o = n(6) + , s = n(8) + , n = n(21); + var i = ".".concat("bs.collapse"); + const a = "show".concat(i) + , l = "shown".concat(i) + , c = "hide".concat(i) + , u = "hidden".concat(i); + i = "click".concat(i).concat(".data-api"); + const h = "show" + , d = "collapse" + , p = "collapsing" + , f = ":scope .".concat(d, " .").concat(d) + , g = '[data-mdb-toggle="collapse"]' + , m = { + parent: null, + toggle: !0 + } + , b = { + parent: "(null|element)", + toggle: "boolean" + }; + class v extends n.a { + constructor(t, e) { + super(t, e), + this._isTransitioning = !1, + this._triggerArray = []; + for (const o of s.a.find(g)) { + var n = Object(r.h)(o) + , i = s.a.find(n).filter(t=>t === this._element); + null !== n && i.length && this._triggerArray.push(o) + } + this._initializeChildren(), + this._config.parent || this._addAriaAndCollapsedClass(this._triggerArray, this._isShown()), + this._config.toggle && this.toggle() + } + static get Default() { + return m + } + static get DefaultType() { + return b + } + static get NAME() { + return "collapse" + } + toggle() { + this._isShown() ? this.hide() : this.show() + } + show() { + if (!this._isTransitioning && !this._isShown()) { + let t = []; + if (!(t = this._config.parent ? this._getFirstLevelChildren(".collapse.show, .collapse.collapsing").filter(t=>t !== this._element).map(t=>v.getOrCreateInstance(t, { + toggle: !1 + })) : t).length || !t[0]._isTransitioning) { + var e = o.a.trigger(this._element, a); + if (!e.defaultPrevented) { + for (const i of t) + i.hide(); + const n = this._getDimension(); + this._element.classList.remove(d), + this._element.classList.add(p), + this._element.style[n] = 0, + this._addAriaAndCollapsedClass(this._triggerArray, !0), + this._isTransitioning = !0; + e = n[0].toUpperCase() + n.slice(1), + e = "scroll".concat(e); + this._queueCallback(()=>{ + this._isTransitioning = !1, + this._element.classList.remove(p), + this._element.classList.add(d, h), + this._element.style[n] = "", + o.a.trigger(this._element, l) + } + , this._element, !0), + this._element.style[n] = "".concat(this._element[e], "px") + } + } + } + } + hide() { + if (!this._isTransitioning && this._isShown()) { + var t = o.a.trigger(this._element, c); + if (!t.defaultPrevented) { + t = this._getDimension(); + this._element.style[t] = "".concat(this._element.getBoundingClientRect()[t], "px"), + Object(r.p)(this._element), + this._element.classList.add(p), + this._element.classList.remove(d, h); + for (const n of this._triggerArray) { + var e = Object(r.f)(n); + e && !this._isShown(e) && this._addAriaAndCollapsedClass([n], !1) + } + this._isTransitioning = !0; + this._element.style[t] = "", + this._queueCallback(()=>{ + this._isTransitioning = !1, + this._element.classList.remove(p), + this._element.classList.add(d), + o.a.trigger(this._element, u) + } + , this._element, !0) + } + } + } + _isShown() { + return (0 < arguments.length && void 0 !== arguments[0] ? arguments[0] : this._element).classList.contains(h) + } + _configAfterMerge(t) { + return t.toggle = Boolean(t.toggle), + t.parent = Object(r.e)(t.parent), + t + } + _getDimension() { + return this._element.classList.contains("collapse-horizontal") ? "width" : "height" + } + _initializeChildren() { + if (this._config.parent) + for (const e of this._getFirstLevelChildren(g)) { + var t = Object(r.f)(e); + t && this._addAriaAndCollapsedClass([e], this._isShown(t)) + } + } + _getFirstLevelChildren(t) { + const e = s.a.find(f, this._config.parent); + return s.a.find(t, this._config.parent).filter(t=>!e.includes(t)) + } + _addAriaAndCollapsedClass(t, e) { + if (t.length) + for (const n of t) + n.classList.toggle("collapsed", !e), + n.setAttribute("aria-expanded", e) + } + static jQueryInterface(e) { + const n = {}; + return "string" == typeof e && /show|hide/.test(e) && (n.toggle = !1), + this.each(function() { + var t = v.getOrCreateInstance(this, n); + if ("string" == typeof e) { + if (void 0 === t[e]) + throw new TypeError('No method named "'.concat(e, '"')); + t[e]() + } + }) + } + } + o.a.on(document, i, g, function(t) { + ("A" === t.target.tagName || t.delegateTarget && "A" === t.delegateTarget.tagName) && t.preventDefault(); + t = Object(r.h)(this); + for (const e of s.a.find(t)) + v.getOrCreateInstance(e, { + toggle: !1 + }).toggle() + }), + Object(r.a)(v), + e.a = v + } + , function(t, e, n) { + "use strict"; + var O = n(169) + , o = n(22) + , i = n(14) + , r = n(223) + , s = n(16) + , x = n(30) + , S = n(15) + , a = n(74) + , C = n(92) + , E = n(156) + , k = n(38) + , l = n(73) + , A = n(224) + , c = n(88) + , j = n(200) + , T = n(225) + , u = n(20)("replace") + , L = Math.max + , P = Math.min + , R = i([].concat) + , M = i([].push) + , I = i("".indexOf) + , D = i("".slice) + , n = "$0" === "a".replace(/./, "$0") + , h = !!/./[u] && "" === /./[u]("a", "$0"); + r("replace", function(t, _, y) { + var w = h ? "$" : "$0"; + return [function(t, e) { + var n = l(this) + , i = a(t) ? void 0 : c(t, u); + return i ? o(i, t, n, e) : o(_, k(n), t, e) + } + , function(t, e) { + var n = x(this) + , i = k(t); + if ("string" == typeof e && -1 === I(e, w) && -1 === I(e, "$<")) { + t = y(_, n, i, e); + if (t.done) + return t.value + } + for (var o, r = S(e), s = (r || (e = k(e)), + n.global), a = (s && (o = n.unicode, + n.lastIndex = 0), + []); null !== (d = T(n, i)) && (M(a, d), + s); ) + "" === k(d[0]) && (n.lastIndex = A(i, E(n.lastIndex), o)); + for (var l, c = "", u = 0, h = 0; h < a.length; h++) { + for (var d, p = k((d = a[h])[0]), f = L(P(C(d.index), i.length), 0), g = [], m = 1; m < d.length; m++) + M(g, void 0 === (l = d[m]) ? l : String(l)); + var b = d.groups + , v = r ? (v = R([p], g, f, i), + void 0 !== b && M(v, b), + k(O(e, void 0, v))) : j(p, i, f, g, b, e); + u <= f && (c += D(i, u, f) + v, + u = f + p.length) + } + return c + D(i, u) + } + ] + }, !!s(function() { + var t = /./; + return t.exec = function() { + var t = []; + return t.groups = { + a: "7" + }, + t + } + , + "7" !== "".replace(t, "$") + }) || !n || h) + } + , function(t, e, n) { + "use strict"; + n.d(e, "a", function() { + return i + }); + n(28); + var o = n(6) + , r = n(4); + const i = function(e) { + let n = 1 < arguments.length && void 0 !== arguments[1] ? arguments[1] : "hide"; + var t = "click.dismiss".concat(e.EVENT_KEY); + const i = e.NAME; + o.a.on(document, t, '[data-mdb-dismiss="'.concat(i, '"]'), function(t) { + ["A", "AREA"].includes(this.tagName) && t.preventDefault(), + Object(r.k)(this) || (t = Object(r.f)(this) || this.closest(".".concat(i)), + e.getOrCreateInstance(t)[n]()) + }) + } + } + , function(t, e, n) { + "use strict"; + var n = n(14) + , i = n({}.toString) + , o = n("".slice); + t.exports = function(t) { + return o(i(t), 8, -1) + } + } + , function(t, e, n) { + "use strict"; + n = n(14); + t.exports = n({}.isPrototypeOf) + } + , function(t, e, n) { + "use strict"; + var i = n(23) + , o = n(40) + , r = n(76); + t.exports = i ? function(t, e, n) { + return o.f(t, e, r(1, n)) + } + : function(t, e, n) { + return t[e] = n, + t + } + } + , function(t, e, n) { + "use strict"; + var i = n(156); + t.exports = function(t) { + return i(t.length) + } + } + , function(t, e, n) { + "use strict"; + var i = n(170) + , o = n(39) + , r = n(89) + , s = i(i.bind); + t.exports = function(t, e) { + return o(t), + void 0 === e ? t : r ? s(t, e) : function() { + return t.apply(e, arguments) + } + } + } + , function(t, e, n) { + "use strict"; + var r = n(24) + , s = n(10); + e.a = { + name: "applyStyles", + enabled: !0, + phase: "write", + fn: function(t) { + var o = t.state; + Object.keys(o.elements).forEach(function(t) { + var e = o.styles[t] || {} + , n = o.attributes[t] || {} + , i = o.elements[t]; + Object(s.b)(i) && Object(r.a)(i) && (Object.assign(i.style, e), + Object.keys(n).forEach(function(t) { + var e = n[t]; + !1 === e ? i.removeAttribute(t) : i.setAttribute(t, !0 === e ? "" : e) + })) + }) + }, + effect: function(t) { + var i = t.state + , o = { + popper: { + position: i.options.strategy, + left: "0", + top: "0", + margin: "0" + }, + arrow: { + position: "absolute" + }, + reference: {} + }; + return Object.assign(i.elements.popper.style, o.popper), + i.styles = o, + i.elements.arrow && Object.assign(i.elements.arrow.style, o.arrow), + function() { + Object.keys(i.elements).forEach(function(t) { + var e = i.elements[t] + , n = i.attributes[t] || {} + , t = Object.keys((i.styles.hasOwnProperty(t) ? i.styles : o)[t]).reduce(function(t, e) { + return t[e] = "", + t + }, {}); + Object(s.b)(e) && Object(r.a)(e) && (Object.assign(e.style, t), + Object.keys(n).forEach(function(t) { + e.removeAttribute(t) + })) + }) + } + }, + requires: ["computeStyles"] + } + } + , function(t, e, n) { + "use strict"; + var _ = n(5) + , y = n(42) + , w = n(19) + , O = n(27) + , x = n(33) + , o = n(25) + , r = n(37) + , S = n(18) + , C = { + top: "auto", + right: "auto", + bottom: "auto", + left: "auto" + }; + function s(t) { + var e, n = t.popper, i = t.popperRect, o = t.placement, r = t.variation, s = t.offsets, a = t.position, l = t.gpuAcceleration, c = t.adaptive, u = t.roundOffsets, t = t.isFixed, h = s.x, h = void 0 === h ? 0 : h, d = s.y, d = void 0 === d ? 0 : d, p = "function" == typeof u ? u({ + x: h, + y: d + }) : { + x: h, + y: d + }, p = (h = p.x, + d = p.y, + s.hasOwnProperty("x")), s = s.hasOwnProperty("y"), f = _.l, g = _.u, m = window, b = (c && (b = "clientHeight", + e = "clientWidth", + (v = Object(y.a)(n)) === Object(w.a)(n) && (v = Object(O.a)(n), + "static" !== Object(x.a)(v).position) && "absolute" === a && (b = "scrollHeight", + e = "scrollWidth"), + o !== _.u && (o !== _.l && o !== _.s || r !== _.k) || (g = _.i, + d = (d - ((t && v === m && m.visualViewport ? m.visualViewport.height : v[b]) - i.height)) * (l ? 1 : -1)), + o !== _.l && (o !== _.u && o !== _.i || r !== _.k) || (f = _.s, + h = (h - ((t && v === m && m.visualViewport ? m.visualViewport.width : v[e]) - i.width)) * (l ? 1 : -1))), + Object.assign({ + position: a + }, c && C)), v = !0 === u ? (o = { + x: h, + y: d + }, + r = Object(w.a)(n), + t = o.x, + o = o.y, + r = r.devicePixelRatio || 1, + { + x: Object(S.c)(t * r) / r || 0, + y: Object(S.c)(o * r) / r || 0 + }) : { + x: h, + y: d + }; + return h = v.x, + d = v.y, + l ? Object.assign({}, b, ((e = {})[g] = s ? "0" : "", + e[f] = p ? "0" : "", + e.transform = (m.devicePixelRatio || 1) <= 1 ? "translate(" + h + "px, " + d + "px)" : "translate3d(" + h + "px, " + d + "px, 0)", + e)) : Object.assign({}, b, ((i = {})[g] = s ? d + "px" : "", + i[f] = p ? h + "px" : "", + i.transform = "", + i)) + } + e.a = { + name: "computeStyles", + enabled: !0, + phase: "beforeWrite", + fn: function(t) { + var e = t.state + , t = t.options + , n = void 0 === (n = t.gpuAcceleration) || n + , i = void 0 === (i = t.adaptive) || i + , t = void 0 === (t = t.roundOffsets) || t + , n = { + placement: Object(o.a)(e.placement), + variation: Object(r.a)(e.placement), + popper: e.elements.popper, + popperRect: e.rects.popper, + gpuAcceleration: n, + isFixed: "fixed" === e.options.strategy + }; + null != e.modifiersData.popperOffsets && (e.styles.popper = Object.assign({}, e.styles.popper, s(Object.assign({}, n, { + offsets: e.modifiersData.popperOffsets, + position: e.options.strategy, + adaptive: i, + roundOffsets: t + })))), + null != e.modifiersData.arrow && (e.styles.arrow = Object.assign({}, e.styles.arrow, s(Object.assign({}, n, { + offsets: e.modifiersData.arrow, + position: "absolute", + adaptive: !1, + roundOffsets: t + })))), + e.attributes.popper = Object.assign({}, e.attributes.popper, { + "data-popper-placement": e.placement + }) + }, + data: {} + } + } + , function(t, e, n) { + "use strict"; + var l = n(19) + , c = { + passive: !0 + }; + e.a = { + name: "eventListeners", + enabled: !0, + phase: "write", + fn: function() {}, + effect: function(t) { + var e = t.state + , n = t.instance + , i = (t = t.options).scroll + , o = void 0 === i || i + , r = void 0 === (i = t.resize) || i + , s = Object(l.a)(e.elements.popper) + , a = [].concat(e.scrollParents.reference, e.scrollParents.popper); + return o && a.forEach(function(t) { + t.addEventListener("scroll", n.update, c) + }), + r && s.addEventListener("resize", n.update, c), + function() { + o && a.forEach(function(t) { + t.removeEventListener("scroll", n.update, c) + }), + r && s.removeEventListener("resize", n.update, c) + } + }, + data: {} + } + } + , function(t, e, n) { + "use strict"; + var i = n(108); + e.a = { + name: "popperOffsets", + enabled: !0, + phase: "read", + fn: function(t) { + var e = t.state + , t = t.name; + e.modifiersData[t] = Object(i.a)({ + reference: e.rects.reference, + element: e.rects.popper, + strategy: "absolute", + placement: e.placement + }) + }, + data: {} + } + } + , function(t, e, n) { + "use strict"; + function i(t) { + return 0 <= ["top", "bottom"].indexOf(t) ? "x" : "y" + } + n.d(e, "a", function() { + return i + }) + } + , function(t, e, n) { + "use strict"; + n.d(e, "a", function() { + return i + }); + var o = n(36); + function i(t) { + var e = Object(o.a)(t) + , n = t.offsetWidth + , i = t.offsetHeight; + return Math.abs(e.width - n) <= 1 && (n = e.width), + Math.abs(e.height - i) <= 1 && (i = e.height), + { + x: t.offsetLeft, + y: t.offsetTop, + width: n, + height: i + } + } + } + , function(t, e, n) { + "use strict"; + n.d(e, "a", function() { + return s + }); + var i = n(36) + , o = n(27) + , r = n(67); + function s(t) { + return Object(i.a)(Object(o.a)(t)).left + Object(r.a)(t).scrollLeft + } + } + , function(t, e, n) { + "use strict"; + n.d(e, "a", function() { + return o + }); + var i = n(19); + function o(t) { + t = Object(i.a)(t); + return { + scrollLeft: t.pageXOffset, + scrollTop: t.pageYOffset + } + } + } + , function(t, e, n) { + "use strict"; + n.d(e, "a", function() { + return o + }); + var i = n(33); + function o(t) { + var t = Object(i.a)(t) + , e = t.overflow + , n = t.overflowX + , t = t.overflowY; + return /auto|scroll|overlay|hidden/.test(e + t + n) + } + } + , function(t, e, n) { + "use strict"; + n(11), + n(12), + n(75), + n(28); + var i = n(71) + , o = n(141) + , r = n(4); + n(17), + n(72); + const l = new Set(["background", "cite", "href", "itemtype", "longdesc", "poster", "src", "xlink:href"]); + const c = /^(?:(?:https?|mailto|ftp|tel|file|sms):|[^#&/:?]*(?:[#/?]|$))/i + , u = /^data:(?:image\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\/(?:mpeg|mp4|ogg|webm)|audio\/(?:mp3|oga|ogg|opus));base64,[\d+/a-z]+=*$/i; + var s = { + "*": ["class", "dir", "id", "lang", "role", /^aria-[\w-]*$/i], + a: ["target", "href", "title", "rel"], + area: [], + b: [], + br: [], + col: [], + code: [], + div: [], + em: [], + hr: [], + h1: [], + h2: [], + h3: [], + h4: [], + h5: [], + h6: [], + i: [], + img: ["src", "srcset", "alt", "title", "width", "height"], + li: [], + ol: [], + p: [], + pre: [], + s: [], + small: [], + span: [], + sub: [], + sup: [], + strong: [], + u: [], + ul: [] + }; + function a(t, e, n) { + if (!t.length) + return t; + if (n && "function" == typeof n) + return n(t); + n = (new window.DOMParser).parseFromString(t, "text/html"); + for (const s of [].concat(...n.body.querySelectorAll("*"))) { + var i = s.nodeName.toLowerCase(); + if (Object.keys(e).includes(i)) { + var o = [].concat(...s.attributes) + , r = [].concat(e["*"] || [], e[i] || []); + for (const a of o) + ((t,e)=>{ + const n = t.nodeName.toLowerCase(); + return e.includes(n) ? !l.has(n) || Boolean(c.test(t.nodeValue) || u.test(t.nodeValue)) : e.filter(t=>t instanceof RegExp).some(t=>t.test(n)) + } + )(a, r) || s.removeAttribute(a.nodeName) + } else + s.remove() + } + return n.body.innerHTML + } + var h = n(6) + , d = n(34) + , p = n(21) + , f = n(8) + , n = n(45); + const g = { + allowList: s, + content: {}, + extraClass: "", + html: !1, + sanitize: !0, + sanitizeFn: null, + template: "
" + } + , m = { + allowList: "object", + content: "object", + extraClass: "(string|function)", + html: "boolean", + sanitize: "boolean", + sanitizeFn: "(null|function)", + template: "string" + } + , b = { + entry: "(string|element|function|null)", + selector: "(string|element)" + }; + class v extends n.a { + constructor(t) { + super(), + this._config = this._getConfig(t) + } + static get Default() { + return g + } + static get DefaultType() { + return m + } + static get NAME() { + return "TemplateFactory" + } + getContent() { + return Object.values(this._config.content).map(t=>this._resolvePossibleFunction(t)).filter(Boolean) + } + hasContent() { + return 0 < this.getContent().length + } + changeContent(t) { + return this._checkContent(t), + this._config.content = { + ...this._config.content, + ...t + }, + this + } + toHtml() { + var t, e, n = document.createElement("div"); + n.innerHTML = this._maybeSanitize(this._config.template); + for ([t,e] of Object.entries(this._config.content)) + this._setContent(n, e, t); + var i = n.children[0] + , o = this._resolvePossibleFunction(this._config.extraClass); + return o && i.classList.add(...o.split(" ")), + i + } + _typeCheckConfig(t) { + super._typeCheckConfig(t), + this._checkContent(t.content) + } + _checkContent(t) { + for (var [e,n] of Object.entries(t)) + super._typeCheckConfig({ + selector: e, + entry: n + }, b) + } + _setContent(t, e, n) { + n = f.a.findOne(n, t); + n && ((e = this._resolvePossibleFunction(e)) ? Object(r.l)(e) ? this._putElementInTemplate(Object(r.e)(e), n) : this._config.html ? n.innerHTML = this._maybeSanitize(e) : n.textContent = e : n.remove()) + } + _maybeSanitize(t) { + return this._config.sanitize ? a(t, this._config.allowList, this._config.sanitizeFn) : t + } + _resolvePossibleFunction(t) { + return "function" == typeof t ? t(this) : t + } + _putElementInTemplate(t, e) { + this._config.html ? (e.innerHTML = "", + e.append(t)) : e.textContent = t.textContent + } + } + var _ = v; + const y = new Set(["sanitize", "allowList", "sanitizeFn"]) + , w = "fade"; + const O = "show" + , x = ".".concat("modal") + , S = "hide.bs.modal" + , C = "hover" + , E = "focus" + , k = { + AUTO: "auto", + TOP: "top", + RIGHT: Object(r.m)() ? "left" : "right", + BOTTOM: "bottom", + LEFT: Object(r.m)() ? "right" : "left" + } + , A = { + allowList: s, + animation: !0, + boundary: "clippingParents", + container: !1, + customClass: "", + delay: 0, + fallbackPlacements: ["top", "right", "bottom", "left"], + html: !1, + offset: [0, 0], + placement: "top", + popperConfig: null, + sanitize: !0, + sanitizeFn: null, + selector: !1, + template: '', + title: "", + trigger: "hover focus" + } + , j = { + allowList: "object", + animation: "boolean", + boundary: "(string|element)", + container: "(string|element|boolean)", + customClass: "(string|function)", + delay: "(number|object)", + fallbackPlacements: "array", + html: "boolean", + offset: "(array|string|function)", + placement: "(string|function)", + popperConfig: "(null|object|function)", + sanitize: "boolean", + sanitizeFn: "(null|function)", + selector: "(string|boolean)", + template: "string", + title: "(string|element|function)", + trigger: "string" + }; + class T extends p.a { + constructor(t, e) { + if (void 0 === i) + throw new TypeError("Bootstrap's tooltips require Popper (https://popper.js.org)"); + super(t, e), + this._isEnabled = !0, + this._timeout = 0, + this._isHovered = null, + this._activeTrigger = {}, + this._popper = null, + this._templateFactory = null, + this._newContent = null, + this.tip = null, + this._setListeners(), + this._config.selector || this._fixTitle() + } + static get Default() { + return A + } + static get DefaultType() { + return j + } + static get NAME() { + return "tooltip" + } + enable() { + this._isEnabled = !0 + } + disable() { + this._isEnabled = !1 + } + toggleEnabled() { + this._isEnabled = !this._isEnabled + } + toggle() { + this._isEnabled && (this._activeTrigger.click = !this._activeTrigger.click, + this._isShown() ? this._leave() : this._enter()) + } + dispose() { + clearTimeout(this._timeout), + h.a.off(this._element.closest(x), S, this._hideModalHandler), + this._element.getAttribute("data-mdb-original-title") && this._element.setAttribute("title", this._element.getAttribute("data-mdb-original-title")), + this._disposePopper(), + super.dispose() + } + show() { + if ("none" === this._element.style.display) + throw new Error("Please use show on visible elements"); + if (this._isWithContent() && this._isEnabled) { + var t = h.a.trigger(this._element, this.constructor.eventName("show")) + , e = (Object(r.d)(this._element) || this._element.ownerDocument.documentElement).contains(this._element); + if (!t.defaultPrevented && e) { + this._disposePopper(); + t = this._getTipElement(), + e = (this._element.setAttribute("aria-describedby", t.getAttribute("id")), + this._config)["container"]; + if (this._element.ownerDocument.documentElement.contains(this.tip) || (e.append(t), + h.a.trigger(this._element, this.constructor.eventName("inserted"))), + this._popper = this._createPopper(t), + t.classList.add(O), + "ontouchstart"in document.documentElement) + for (const n of [].concat(...document.body.children)) + h.a.on(n, "mouseover", r.o); + this._queueCallback(()=>{ + h.a.trigger(this._element, this.constructor.eventName("shown")), + !1 === this._isHovered && this._leave(), + this._isHovered = !1 + } + , this.tip, this._isAnimated()) + } + } + } + hide() { + if (this._isShown()) { + var t = h.a.trigger(this._element, this.constructor.eventName("hide")); + if (!t.defaultPrevented) { + if (this._getTipElement().classList.remove(O), + "ontouchstart"in document.documentElement) + for (const e of [].concat(...document.body.children)) + h.a.off(e, "mouseover", r.o); + this._activeTrigger.click = !1, + this._activeTrigger[E] = !1, + this._activeTrigger[C] = !1, + this._isHovered = null; + this._queueCallback(()=>{ + this._isWithActiveTrigger() || (this._isHovered || this._disposePopper(), + this._element.removeAttribute("aria-describedby"), + h.a.trigger(this._element, this.constructor.eventName("hidden"))) + } + , this.tip, this._isAnimated()) + } + } + } + update() { + this._popper && this._popper.update() + } + _isWithContent() { + return Boolean(this._getTitle()) + } + _getTipElement() { + return this.tip || (this.tip = this._createTipElement(this._newContent || this._getContentForTemplate())), + this.tip + } + _createTipElement(t) { + t = this._getTemplateFactory(t).toHtml(); + if (!t) + return null; + t.classList.remove(w, O), + t.classList.add("bs-".concat(this.constructor.NAME, "-auto")); + var e = Object(r.i)(this.constructor.NAME).toString(); + return t.setAttribute("id", e), + this._isAnimated() && t.classList.add(w), + t + } + setContent(t) { + this._newContent = t, + this._isShown() && (this._disposePopper(), + this.show()) + } + _getTemplateFactory(t) { + return this._templateFactory ? this._templateFactory.changeContent(t) : this._templateFactory = new _({ + ...this._config, + content: t, + extraClass: this._resolvePossibleFunction(this._config.customClass) + }), + this._templateFactory + } + _getContentForTemplate() { + return { + ".tooltip-inner": this._getTitle() + } + } + _getTitle() { + return this._resolvePossibleFunction(this._config.title) || this._element.getAttribute("data-mdb-original-title") + } + _initializeOnDelegatedTarget(t) { + return this.constructor.getOrCreateInstance(t.delegateTarget, this._getDelegateConfig()) + } + _isAnimated() { + return this._config.animation || this.tip && this.tip.classList.contains(w) + } + _isShown() { + return this.tip && this.tip.classList.contains(O) + } + _createPopper(t) { + var e = "function" == typeof this._config.placement ? this._config.placement.call(this, t, this._element) : this._config.placement + , e = k[e.toUpperCase()]; + return o.a(this._element, t, this._getPopperConfig(e)) + } + _getOffset() { + const e = this._config["offset"]; + return "string" == typeof e ? e.split(",").map(t=>Number.parseInt(t, 10)) : "function" == typeof e ? t=>e(t, this._element) : e + } + _resolvePossibleFunction(t) { + return "function" == typeof t ? t.call(this._element) : t + } + _getPopperConfig(t) { + t = { + placement: t, + modifiers: [{ + name: "flip", + options: { + fallbackPlacements: this._config.fallbackPlacements + } + }, { + name: "offset", + options: { + offset: this._getOffset() + } + }, { + name: "preventOverflow", + options: { + boundary: this._config.boundary + } + }, { + name: "arrow", + options: { + element: ".".concat(this.constructor.NAME, "-arrow") + } + }, { + name: "preSetPlacement", + enabled: !0, + phase: "beforeMain", + fn: t=>{ + this._getTipElement().setAttribute("data-popper-placement", t.state.placement) + } + }] + }; + return { + ...t, + ..."function" == typeof this._config.popperConfig ? this._config.popperConfig(t) : this._config.popperConfig + } + } + _setListeners() { + var t, e; + for (const n of this._config.trigger.split(" ")) + "click" === n ? h.a.on(this._element, this.constructor.eventName("click"), this._config.selector, t=>{ + this._initializeOnDelegatedTarget(t).toggle() + } + ) : "manual" !== n && (t = n === C ? this.constructor.eventName("mouseenter") : this.constructor.eventName("focusin"), + e = n === C ? this.constructor.eventName("mouseleave") : this.constructor.eventName("focusout"), + h.a.on(this._element, t, this._config.selector, t=>{ + var e = this._initializeOnDelegatedTarget(t); + e._activeTrigger["focusin" === t.type ? E : C] = !0, + e._enter() + } + ), + h.a.on(this._element, e, this._config.selector, t=>{ + var e = this._initializeOnDelegatedTarget(t); + e._activeTrigger["focusout" === t.type ? E : C] = e._element.contains(t.relatedTarget), + e._leave() + } + )); + this._hideModalHandler = ()=>{ + this._element && this.hide() + } + , + h.a.on(this._element.closest(x), S, this._hideModalHandler) + } + _fixTitle() { + var t = this._element.getAttribute("title"); + t && (this._element.getAttribute("aria-label") || this._element.textContent.trim() || this._element.setAttribute("aria-label", t), + this._element.setAttribute("data-mdb-original-title", t), + this._element.removeAttribute("title")) + } + _enter() { + this._isShown() || this._isHovered ? this._isHovered = !0 : (this._isHovered = !0, + this._setTimeout(()=>{ + this._isHovered && this.show() + } + , this._config.delay.show)) + } + _leave() { + this._isWithActiveTrigger() || (this._isHovered = !1, + this._setTimeout(()=>{ + this._isHovered || this.hide() + } + , this._config.delay.hide)) + } + _setTimeout(t, e) { + clearTimeout(this._timeout), + this._timeout = setTimeout(t, e) + } + _isWithActiveTrigger() { + return Object.values(this._activeTrigger).includes(!0) + } + _getConfig(t) { + var e = d.a.getDataAttributes(this._element); + for (const n of Object.keys(e)) + y.has(n) && delete e[n]; + return t = { + ...e, + ..."object" == typeof t && t ? t : {} + }, + t = this._mergeConfigObj(t), + t = this._configAfterMerge(t), + this._typeCheckConfig(t), + t + } + _configAfterMerge(t) { + return t.container = !1 === t.container ? document.body : Object(r.e)(t.container), + "number" == typeof t.delay && (t.delay = { + show: t.delay, + hide: t.delay + }), + "number" == typeof t.title && (t.title = t.title.toString()), + "number" == typeof t.content && (t.content = t.content.toString()), + t + } + _getDelegateConfig() { + var t = {}; + for (const e in this._config) + this.constructor.Default[e] !== this._config[e] && (t[e] = this._config[e]); + return t.selector = !1, + t.trigger = "manual", + t + } + _disposePopper() { + this._popper && (this._popper.destroy(), + this._popper = null), + this.tip && (this.tip.remove(), + this.tip = null) + } + static jQueryInterface(e) { + return this.each(function() { + var t = T.getOrCreateInstance(this, e); + if ("string" == typeof e) { + if (void 0 === t[e]) + throw new TypeError('No method named "'.concat(e, '"')); + t[e]() + } + }) + } + } + Object(r.a)(T); + e.a = T + } + , function(t, e, n) { + "use strict"; + n.d(e, "a", function() { + return c + }); + var o = n(47) + , r = n(68) + , s = n(24) + , a = n(10); + var l = n(19); + function c(t, e) { + void 0 === e && (e = []); + var n = function t(e) { + return 0 <= ["html", "body", "#document"].indexOf(Object(s.a)(e)) ? e.ownerDocument.body : Object(a.b)(e) && Object(r.a)(e) ? e : t(Object(o.a)(e)) + }(t) + , t = n === (null == (t = t.ownerDocument) ? void 0 : t.body) + , i = Object(l.a)(n) + , i = t ? [i].concat(i.visualViewport || [], Object(r.a)(n) ? n : []) : n + , n = e.concat(i); + return t ? n : n.concat(c(Object(o.a)(i))) + } + } + , function(t, e, n) { + "use strict"; + n.r(e); + var i = n(5) + , o = (n.d(e, "top", function() { + return i.u + }), + n.d(e, "bottom", function() { + return i.i + }), + n.d(e, "right", function() { + return i.s + }), + n.d(e, "left", function() { + return i.l + }), + n.d(e, "auto", function() { + return i.d + }), + n.d(e, "basePlacements", function() { + return i.e + }), + n.d(e, "start", function() { + return i.t + }), + n.d(e, "end", function() { + return i.k + }), + n.d(e, "clippingParents", function() { + return i.j + }), + n.d(e, "viewport", function() { + return i.w + }), + n.d(e, "popper", function() { + return i.p + }), + n.d(e, "reference", function() { + return i.r + }), + n.d(e, "variationPlacements", function() { + return i.v + }), + n.d(e, "placements", function() { + return i.o + }), + n.d(e, "beforeRead", function() { + return i.g + }), + n.d(e, "read", function() { + return i.q + }), + n.d(e, "afterRead", function() { + return i.b + }), + n.d(e, "beforeMain", function() { + return i.f + }), + n.d(e, "main", function() { + return i.m + }), + n.d(e, "afterMain", function() { + return i.a + }), + n.d(e, "beforeWrite", function() { + return i.h + }), + n.d(e, "write", function() { + return i.x + }), + n.d(e, "afterWrite", function() { + return i.c + }), + n.d(e, "modifierPhases", function() { + return i.n + }), + n(94)) + , r = (n.d(e, "applyStyles", function() { + return o.a + }), + n.d(e, "arrow", function() { + return o.b + }), + n.d(e, "computeStyles", function() { + return o.c + }), + n.d(e, "eventListeners", function() { + return o.d + }), + n.d(e, "flip", function() { + return o.e + }), + n.d(e, "hide", function() { + return o.f + }), + n.d(e, "offset", function() { + return o.g + }), + n.d(e, "popperOffsets", function() { + return o.h + }), + n.d(e, "preventOverflow", function() { + return o.i + }), + n(44)) + , s = (n.d(e, "popperGenerator", function() { + return r.b + }), + n(32)) + , a = (n.d(e, "detectOverflow", function() { + return s.a + }), + n.d(e, "createPopperBase", function() { + return r.a + }), + n(141)) + , l = (n.d(e, "createPopper", function() { + return a.a + }), + n(95)); + n.d(e, "createPopperLite", function() { + return l.a + }) + } + , function(D, N, t) { + "use strict"; + var e = t(23) + , n = t(13) + , i = t(14) + , o = t(122) + , c = t(226) + , u = t(57) + , r = t(152).f + , h = t(56) + , d = t(201) + , p = t(38) + , f = t(202) + , s = t(166) + , a = t(227) + , l = t(41) + , g = t(16) + , m = t(29) + , b = t(46).enforce + , v = t(171) + , _ = t(20) + , y = t(167) + , w = t(168) + , O = _("match") + , x = n.RegExp + , S = x.prototype + , C = n.SyntaxError + , E = i(S.exec) + , k = i("".charAt) + , A = i("".replace) + , j = i("".indexOf) + , H = i("".slice) + , B = /^\?<[^\s\d!#%&*+<=>@^][^\s!#%&*+<=>@^]*>/ + , T = /a/g + , L = /a/g + , t = new x(T) !== T + , P = s.MISSED_STICKY + , W = s.UNSUPPORTED_Y + , _ = e && (!t || P || y || w || g(function() { + return L[O] = !1, + x(T) !== T || x(L) === L || "/a/i" !== String(x(T, "i")) + })); + if (o("RegExp", _)) { + for (var R = function(t, e) { + var n, i, o = h(S, this), r = d(t), s = void 0 === e, a = [], l = t; + if (!o && r && s && t.constructor === R) + return t; + if ((r || h(S, t)) && (t = t.source, + s) && (e = f(l)), + t = void 0 === t ? "" : p(t), + e = void 0 === e ? "" : p(e), + l = t, + r = e = y && "dotAll"in T && (n = !!e && -1 < j(e, "s")) ? A(e, /s/g, "") : e, + P && "sticky"in T && (i = !!e && -1 < j(e, "y")) && W && (e = A(e, /y/g, "")), + w && (t = (s = function(t) { + for (var e, n = t.length, i = 0, o = "", r = [], s = {}, a = !1, l = !1, c = 0, u = ""; i <= n; i++) { + if ("\\" === (e = k(t, i))) + e += k(t, ++i); + else if ("]" === e) + a = !1; + else if (!a) + switch (!0) { + case "[" === e: + a = !0; + break; + case "(" === e: + E(B, H(t, i + 1)) && (i += 2, + l = !0), + o += e, + c++; + continue; + case ">" === e && l: + if ("" === u || m(s, u)) + throw new C("Invalid capture group name"); + s[u] = !0, + l = !(r[r.length] = [u, c]), + u = ""; + continue + } + l ? u += e : o += e + } + return [o, r] + }(t))[0], + a = s[1]), + s = c(x(t, e), o ? this : S, R), + (n || i || a.length) && (e = b(s), + n && (e.dotAll = !0, + e.raw = R(function(t) { + for (var e, n = t.length, i = 0, o = "", r = !1; i <= n; i++) + "\\" === (e = k(t, i)) ? o += e + k(t, ++i) : r || "." !== e ? ("[" === e ? r = !0 : "]" === e && (r = !1), + o += e) : o += "[\\s\\S]"; + return o + }(t), r)), + i && (e.sticky = !0), + a.length) && (e.groups = a), + t !== l) + try { + u(s, "source", "" === l ? "(?:)" : l) + } catch (t) {} + return s + }, M = r(x), I = 0; M.length > I; ) + a(R, x, M[I++]); + (S.constructor = R).prototype = S, + l(n, "RegExp", R, { + constructor: !0 + }) + } + v("RegExp") + } + , function(t, e, n) { + "use strict"; + var i = n(74) + , o = TypeError; + t.exports = function(t) { + if (i(t)) + throw o("Can't call method on " + t); + return t + } + } + , function(t, e, n) { + "use strict"; + t.exports = function(t) { + return null == t + } + } + , function(t, e, n) { + "use strict"; + var i = n(26) + , o = n(229).trim; + i({ + target: "String", + proto: !0, + forced: n(230)("trim") + }, { + trim: function() { + return o(this) + } + }) + } + , function(t, e, n) { + "use strict"; + t.exports = function(t, e) { + return { + enumerable: !(1 & t), + configurable: !(2 & t), + writable: !(4 & t), + value: e + } + } + } + , function(t, e, n) { + "use strict"; + var i = n(112) + , o = n(73); + t.exports = function(t) { + return i(o(t)) + } + } + , function(t, e, n) { + "use strict"; + var i = String; + t.exports = function(t) { + try { + return i(t) + } catch (t) { + return "Object" + } + } + } + , function(t, e, n) { + "use strict"; + var i = n(150) + , o = n(40); + t.exports = function(t, e, n) { + return n.get && i(n.get, e, { + getter: !0 + }), + n.set && i(n.set, e, { + setter: !0 + }), + o.f(t, e, n) + } + } + , function(t, e, n) { + "use strict"; + function i() {} + function o(t) { + t.write(g("")), + t.close(); + var e = t.parentWindow.Object; + return t = null, + e + } + var r, s = n(30), a = n(213), l = n(121), c = n(120), u = n(160), h = n(91), n = n(119), d = "prototype", p = "script", f = n("IE_PROTO"), g = function(t) { + return "<" + p + ">" + t + "" + }, m = function() { + try { + r = new ActiveXObject("htmlfile") + } catch (t) {} + m = "undefined" == typeof document || document.domain && r ? o(r) : (t = h("iframe"), + e = "java" + p + ":", + t.style.display = "none", + u.appendChild(t), + t.src = String(e), + (e = t.contentWindow.document).open(), + e.write(g("document.F=Object")), + e.close(), + e.F); + for (var t, e, n = l.length; n--; ) + delete m[d][l[n]]; + return m() + }; + c[f] = !0, + t.exports = Object.create || function(t, e) { + var n; + return null !== t ? (i[d] = s(t), + n = new i, + i[d] = null, + n[f] = t) : n = m(), + void 0 === e ? n : a.f(n, e) + } + } + , function(t, e, n) { + "use strict"; + t.exports = {} + } + , function(t, e, n) { + "use strict"; + var i = n(40).f + , o = n(29) + , r = n(20)("toStringTag"); + t.exports = function(t, e, n) { + (t = t && !n ? t.prototype : t) && !o(t, r) && i(t, r, { + configurable: !0, + value: e + }) + } + } + , function(t, e, n) { + "use strict"; + var i = n(13) + , n = n(55); + t.exports = "process" === n(i.process) + } + , function(t, e, n) { + "use strict"; + n = n(13); + t.exports = n.Promise + } + , function(t, e, n) { + "use strict"; + var i = n(13) + , o = n(84) + , r = n(15) + , s = n(122) + , a = n(118) + , l = n(20) + , c = n(245) + , u = n(181) + , h = n(43) + , d = n(90) + , p = o && o.prototype + , f = l("species") + , g = !1 + , m = r(i.PromiseRejectionEvent) + , n = s("Promise", function() { + var t = a(o) + , e = t !== String(o); + if (!e && 66 === d) + return !0; + if (h && (!p.catch || !p.finally)) + return !0; + if (!d || d < 51 || !/native code/.test(t)) { + var t = new o(function(t) { + t(1) + } + ) + , n = function(t) { + t(function() {}, function() {}) + }; + if ((t.constructor = {})[f] = n, + !(g = t.then(function() {})instanceof n)) + return !0 + } + return !e && (c || u) && !m + }); + t.exports = { + CONSTRUCTOR: n, + REJECTION_EVENT: m, + SUBCLASSING: g + } + } + , function(t, e, n) { + "use strict"; + function i(t) { + var n, i; + this.promise = new t(function(t, e) { + if (void 0 !== n || void 0 !== i) + throw r("Bad Promise constructor"); + n = t, + i = e + } + ), + this.resolve = o(n), + this.reject = o(i) + } + var o = n(39) + , r = TypeError; + t.exports.f = function(t) { + return new i(t) + } + } + , function(t, e, n) { + "use strict"; + function i() { + var t = navigator.userAgentData; + return null != t && t.brands && Array.isArray(t.brands) ? t.brands.map(function(t) { + return t.brand + "/" + t.version + }).join(" ") : navigator.userAgent + } + n.d(e, "a", function() { + return i + }) + } + , function(t, e, n) { + "use strict"; + var i = n(39) + , o = n(74); + t.exports = function(t, e) { + t = t[e]; + return o(t) ? void 0 : i(t) + } + } + , function(t, e, n) { + "use strict"; + n = n(16); + t.exports = !n(function() { + var t = function() {} + .bind(); + return "function" != typeof t || t.hasOwnProperty("prototype") + }) + } + , function(t, e, n) { + "use strict"; + var i, o, r = n(13), n = n(49), s = r.process, r = r.Deno, s = s && s.versions || r && r.version, r = s && s.v8; + !(o = r ? 0 < (i = r.split("."))[0] && i[0] < 4 ? 1 : +(i[0] + i[1]) : o) && n && (!(i = n.match(/Edge\/(\d+)/)) || 74 <= i[1]) && (i = n.match(/Chrome\/(\d+)/)) && (o = +i[1]), + t.exports = o + } + , function(t, e, n) { + "use strict"; + var i = n(13) + , n = n(35) + , o = i.document + , r = n(o) && n(o.createElement); + t.exports = function(t) { + return r ? o.createElement(t) : {} + } + } + , function(t, e, n) { + "use strict"; + var i = n(211); + t.exports = function(t) { + t = +t; + return t != t || 0 == t ? 0 : i(t) + } + } + , function(t, e, n) { + "use strict"; + var i = n(212) + , o = n(15) + , r = n(55) + , s = n(20)("toStringTag") + , a = Object + , l = "Arguments" === r(function() { + return arguments + }()); + t.exports = i ? r : function(t) { + var e; + return void 0 === t ? "Undefined" : null === t ? "Null" : "string" == typeof (e = function(t, e) { + try { + return t[e] + } catch (t) {} + }(t = a(t), s)) ? e : l ? r(t) : "Object" === (e = r(t)) && o(t.callee) ? "Arguments" : e + } + } + , function(t, e, n) { + "use strict"; + var i = n(60) + , o = (n.d(e, "a", function() { + return i.a + }), + n(97)) + , r = (n.d(e, "b", function() { + return o.a + }), + n(61)) + , s = (n.d(e, "c", function() { + return r.a + }), + n(62)) + , a = (n.d(e, "d", function() { + return s.a + }), + n(100)) + , l = (n.d(e, "e", function() { + return a.a + }), + n(98)) + , c = (n.d(e, "f", function() { + return l.a + }), + n(99)) + , u = (n.d(e, "g", function() { + return c.a + }), + n(63)) + , h = (n.d(e, "h", function() { + return u.a + }), + n(101)); + n.d(e, "i", function() { + return h.a + }) + } + , function(t, e, n) { + "use strict"; + n.d(e, "a", function() { + return s + }); + var e = n(44) + , i = n(62) + , o = n(63) + , r = n(61) + , n = n(60) + , i = [i.a, o.a, r.a, n.a] + , s = Object(e.b)({ + defaultModifiers: i + }) + } + , function(t, e, n) { + "use strict"; + var i = n(93) + , o = n(88) + , r = n(74) + , s = n(81) + , a = n(20)("iterator"); + t.exports = function(t) { + if (!r(t)) + return o(t, a) || o(t, "@@iterator") || s[i(t)] + } + } + , function(t, e, n) { + "use strict"; + var h = n(25) + , d = n(65) + , i = n(107) + , p = n(42) + , f = n(64) + , g = n(51) + , m = n(103) + , b = n(105) + , v = n(5); + e.a = { + name: "arrow", + enabled: !0, + phase: "main", + fn: function(t) { + var e, n, i, o, r = t.state, s = t.name, t = t.options, a = r.elements.arrow, l = r.modifiersData.popperOffsets, c = Object(h.a)(r.placement), u = Object(f.a)(c), c = 0 <= [v.l, v.s].indexOf(c) ? "height" : "width"; + a && l && (t = t.padding, + i = r, + t = "function" == typeof t ? t(Object.assign({}, i.rects, { + placement: i.placement + })) : t, + i = Object(m.a)("number" != typeof t ? t : Object(b.a)(t, v.e)), + t = Object(d.a)(a), + n = "y" === u ? v.u : v.l, + o = "y" === u ? v.i : v.s, + e = r.rects.reference[c] + r.rects.reference[u] - l[u] - r.rects.popper[c], + l = l[u] - r.rects.reference[u], + a = (a = Object(p.a)(a)) ? "y" === u ? a.clientHeight || 0 : a.clientWidth || 0 : 0, + n = i[n], + i = a - t[c] - i[o], + o = a / 2 - t[c] / 2 + (e / 2 - l / 2), + a = Object(g.a)(n, o, i), + r.modifiersData[s] = ((t = {})[u] = a, + t.centerOffset = a - o, + t)) + }, + effect: function(t) { + var e = t.state; + null != (t = void 0 === (t = t.options.element) ? "[data-popper-arrow]" : t) && ("string" != typeof t || (t = e.elements.popper.querySelector(t))) && Object(i.a)(e.elements.popper, t) && (e.elements.arrow = t) + }, + requires: ["popperOffsets"], + requiresIfExists: ["preventOverflow"] + } + } + , function(t, e, n) { + "use strict"; + var i = n(5) + , a = n(32); + function l(t, e, n) { + return { + top: t.top - e.height - (n = void 0 === n ? { + x: 0, + y: 0 + } : n).y, + right: t.right - e.width + n.x, + bottom: t.bottom - e.height + n.y, + left: t.left - e.width - n.x + } + } + function c(e) { + return [i.u, i.s, i.i, i.l].some(function(t) { + return 0 <= e[t] + }) + } + e.a = { + name: "hide", + enabled: !0, + phase: "main", + requiresIfExists: ["preventOverflow"], + fn: function(t) { + var e = t.state + , t = t.name + , n = e.rects.reference + , i = e.rects.popper + , o = e.modifiersData.preventOverflow + , r = Object(a.a)(e, { + elementContext: "reference" + }) + , s = Object(a.a)(e, { + altBoundary: !0 + }) + , r = l(r, n) + , n = l(s, i, o) + , s = c(r) + , i = c(n); + e.modifiersData[t] = { + referenceClippingOffsets: r, + popperEscapeOffsets: n, + isReferenceHidden: s, + hasPopperEscaped: i + }, + e.attributes.popper = Object.assign({}, e.attributes.popper, { + "data-popper-reference-hidden": s, + "data-popper-escaped": i + }) + } + } + } + , function(t, e, n) { + "use strict"; + var l = n(25) + , c = n(5); + e.a = { + name: "offset", + enabled: !0, + phase: "main", + requires: ["popperOffsets"], + fn: function(t) { + var s = t.state + , e = t.options + , t = t.name + , a = void 0 === (e = e.offset) ? [0, 0] : e + , e = c.o.reduce(function(t, e) { + var n, i, o, r; + return t[e] = (e = e, + n = s.rects, + i = a, + o = Object(l.a)(e), + r = 0 <= [c.l, c.u].indexOf(o) ? -1 : 1, + e = (n = "function" == typeof i ? i(Object.assign({}, n, { + placement: e + })) : i)[0] || 0, + i = (n[1] || 0) * r, + 0 <= [c.l, c.s].indexOf(o) ? { + x: i, + y: e + } : { + x: e, + y: i + }), + t + }, {}) + , n = (i = e[s.placement]).x + , i = i.y; + null != s.modifiersData.popperOffsets && (s.modifiersData.popperOffsets.x += n, + s.modifiersData.popperOffsets.y += i), + s.modifiersData[t] = e + } + } + } + , function(t, e, n) { + "use strict"; + var i = { + left: "right", + right: "left", + bottom: "top", + top: "bottom" + }; + function k(t) { + return t.replace(/left|right|bottom|top/g, function(t) { + return i[t] + }) + } + var A = n(25) + , o = { + start: "end", + end: "start" + }; + function j(t) { + return t.replace(/start|end/g, function(t) { + return o[t] + }) + } + var T = n(32) + , L = n(37) + , P = n(5); + e.a = { + name: "flip", + enabled: !0, + phase: "main", + fn: function(t) { + var h = t.state + , e = t.options + , t = t.name; + if (!h.modifiersData[t]._skip) { + for (var n = e.mainAxis, i = void 0 === n || n, n = e.altAxis, o = void 0 === n || n, n = e.fallbackPlacements, d = e.padding, p = e.boundary, f = e.rootBoundary, r = e.altBoundary, s = e.flipVariations, g = void 0 === s || s, m = e.allowedAutoPlacements, s = h.options.placement, e = Object(A.a)(s), n = n || (e === s || !g ? [k(s)] : (n = s, + Object(A.a)(n) === P.d ? [] : (e = k(n), + [j(n), e, j(e)]))), a = [s].concat(n).reduce(function(t, e) { + return t.concat(Object(A.a)(e) === P.d ? (n = h, + i = (t = t = void 0 === (t = { + placement: e, + boundary: p, + rootBoundary: f, + padding: d, + flipVariations: g, + allowedAutoPlacements: m + }) ? {} : t).placement, + o = t.boundary, + r = t.rootBoundary, + s = t.padding, + a = t.flipVariations, + l = void 0 === (t = t.allowedAutoPlacements) ? P.o : t, + c = Object(L.a)(i), + t = c ? a ? P.v : P.v.filter(function(t) { + return Object(L.a)(t) === c + }) : P.e, + u = (i = 0 === (i = t.filter(function(t) { + return 0 <= l.indexOf(t) + })).length ? t : i).reduce(function(t, e) { + return t[e] = Object(T.a)(n, { + placement: e, + boundary: o, + rootBoundary: r, + padding: s + })[Object(A.a)(e)], + t + }, {}), + Object.keys(u).sort(function(t, e) { + return u[t] - u[e] + })) : e); + var n, i, o, r, s, a, l, c, u + }, []), l = h.rects.reference, c = h.rects.popper, u = new Map, b = !0, v = a[0], _ = 0; _ < a.length; _++) { + var y = a[_] + , w = Object(A.a)(y) + , O = Object(L.a)(y) === P.t + , x = 0 <= [P.u, P.i].indexOf(w) + , S = x ? "width" : "height" + , C = Object(T.a)(h, { + placement: y, + boundary: p, + rootBoundary: f, + altBoundary: r, + padding: d + }) + , x = x ? O ? P.s : P.l : O ? P.i : P.u + , O = (l[S] > c[S] && (x = k(x)), + k(x)) + , S = []; + if (i && S.push(C[w] <= 0), + o && S.push(C[x] <= 0, C[O] <= 0), + S.every(function(t) { + return t + })) { + v = y, + b = !1; + break + } + u.set(y, S) + } + if (b) + for (var E = g ? 3 : 1; 0 < E; E--) + if ("break" === function(e) { + var t = a.find(function(t) { + t = u.get(t); + if (t) + return t.slice(0, e).every(function(t) { + return t + }) + }); + if (t) + return v = t, + "break" + }(E)) + break; + h.placement !== v && (h.modifiersData[t]._skip = !0, + h.placement = v, + h.reset = !0) + } + }, + requiresIfExists: ["offset"], + data: { + _skip: !1 + } + } + } + , function(t, e, n) { + "use strict"; + var E = n(5) + , k = n(25) + , A = n(64); + var j = n(51) + , T = n(65) + , L = n(42) + , P = n(32) + , R = n(37) + , M = n(104) + , I = n(18); + e.a = { + name: "preventOverflow", + enabled: !0, + phase: "main", + fn: function(t) { + var e, n, i, o, r, s, a, l, c, u = t.state, h = t.options, t = t.name, d = void 0 === (d = h.mainAxis) || d, p = void 0 !== (p = h.altAxis) && p, f = h.boundary, g = h.rootBoundary, m = h.altBoundary, b = h.padding, v = void 0 === (v = h.tether) || v, h = void 0 === (h = h.tetherOffset) ? 0 : h, f = Object(P.a)(u, { + boundary: f, + rootBoundary: g, + padding: b, + altBoundary: m + }), g = Object(k.a)(u.placement), m = !(b = Object(R.a)(u.placement)), _ = Object(A.a)(g), y = "x" === _ ? "y" : "x", w = u.modifiersData.popperOffsets, O = u.rects.reference, x = u.rects.popper, h = "number" == typeof (h = "function" == typeof h ? h(Object.assign({}, u.rects, { + placement: u.placement + })) : h) ? { + mainAxis: h, + altAxis: h + } : Object.assign({ + mainAxis: 0, + altAxis: 0 + }, h), S = u.modifiersData.offset ? u.modifiersData.offset[u.placement] : null, C = { + x: 0, + y: 0 + }; + w && (d && (d = "y" === _ ? E.u : E.l, + s = "y" === _ ? E.i : E.s, + i = "y" === _ ? "height" : "width", + e = (c = w[_]) + f[d], + a = c - f[s], + r = v ? -x[i] / 2 : 0, + o = (b === E.t ? O : x)[i], + b = b === E.t ? -x[i] : -O[i], + n = u.elements.arrow, + n = v && n ? Object(T.a)(n) : { + width: 0, + height: 0 + }, + d = (l = u.modifiersData["arrow#persistent"] ? u.modifiersData["arrow#persistent"].padding : Object(M.a)())[d], + l = l[s], + s = Object(j.a)(0, O[i], n[i]), + n = m ? O[i] / 2 - r - s - d - h.mainAxis : o - s - d - h.mainAxis, + o = m ? -O[i] / 2 + r + s + l + h.mainAxis : b + s + l + h.mainAxis, + m = (d = u.elements.arrow && Object(L.a)(u.elements.arrow)) ? "y" === _ ? d.clientTop || 0 : d.clientLeft || 0 : 0, + b = c + n - (r = null != (i = null == S ? void 0 : S[_]) ? i : 0) - m, + s = c + o - r, + l = Object(j.a)(v ? Object(I.b)(e, b) : e, c, v ? Object(I.a)(a, s) : a), + w[_] = l, + C[_] = l - c), + p && (d = "x" === _ ? E.u : E.l, + n = "x" === _ ? E.i : E.s, + i = "y" == y ? "height" : "width", + o = (m = w[y]) + f[d], + r = m - f[n], + b = -1 !== [E.u, E.l].indexOf(g), + s = null != (e = null == S ? void 0 : S[y]) ? e : 0, + a = b ? o : m - O[i] - x[i] - s + h.altAxis, + l = b ? m + O[i] + x[i] - s - h.altAxis : r, + c = v && b ? Object(j.b)(a, m, l) : Object(j.a)(v ? a : o, m, v ? l : r), + w[y] = c, + C[y] = c - m), + u.modifiersData[t] = C) + }, + requiresIfExists: ["offset"] + } + } + , function(t, e, n) { + "use strict"; + n(17); + var i = n(3) + , o = n(7) + , r = n(1) + , s = n(0) + , a = n(2); + n(236); + const l = "input" + , c = "mdb.input"; + n = "form-outline"; + const u = "active" + , h = "form-notch" + , d = "form-notch-leading" + , p = "form-notch-middle"; + const f = ".".concat(n, " input") + , g = ".".concat(n, " textarea") + , m = ".".concat(h) + , b = ".".concat(d) + , v = ".".concat(p) + , _ = ".".concat("form-helper"); + class y { + constructor(t) { + this._element = t, + this._label = null, + this._labelWidth = 0, + this._labelMarginLeft = 0, + this._notchLeading = null, + this._notchMiddle = null, + this._notchTrailing = null, + this._initiated = !1, + this._helper = null, + this._counter = !1, + this._counterElement = null, + this._maxLength = 0, + this._leadingIcon = null, + this._element && (o.a.setData(t, c, this), + this.init()) + } + static get NAME() { + return l + } + get input() { + return a.a.findOne("input", this._element) || a.a.findOne("textarea", this._element) + } + init() { + this._initiated || (this._getLabelData(), + this._applyDivs(), + this._applyNotch(), + this._activate(), + this._getHelper(), + this._getCounter(), + this._initiated = !0) + } + update() { + this._getLabelData(), + this._getNotchData(), + this._applyNotch(), + this._activate(), + this._getHelper(), + this._getCounter() + } + forceActive() { + s.a.addClass(this.input, u) + } + forceInactive() { + s.a.removeClass(this.input, u) + } + dispose() { + this._removeBorder(), + o.a.removeData(this._element, c), + this._element = null + } + _getLabelData() { + this._label = a.a.findOne("label", this._element), + null === this._label ? this._showPlaceholder() : (this._getLabelWidth(), + this._getLabelPositionInInputGroup(), + this._toggleDefaultDatePlaceholder()) + } + _getHelper() { + this._helper = a.a.findOne(_, this._element) + } + _getCounter() { + this._counter = s.a.getDataAttribute(this.input, "showcounter"), + this._counter && (this._maxLength = this.input.maxLength, + this._showCounter()) + } + _showCounter() { + var t; + 0 < a.a.find(".form-counter", this._element).length || (this._counterElement = document.createElement("div"), + s.a.addClass(this._counterElement, "form-counter"), + t = this.input.value.length, + this._counterElement.innerHTML = "".concat(t, " / ").concat(this._maxLength), + this._helper.appendChild(this._counterElement), + this._bindCounter()) + } + _bindCounter() { + r.b.on(this.input, "input", ()=>{ + var t = this.input.value.length; + this._counterElement.innerHTML = "".concat(t, " / ").concat(this._maxLength) + } + ) + } + _toggleDefaultDatePlaceholder() { + var t = 0 < arguments.length && void 0 !== arguments[0] ? arguments[0] : this.input; + "date" === t.getAttribute("type") && (document.activeElement === t || t.value ? t.style.opacity = 1 : t.style.opacity = 0) + } + _showPlaceholder() { + s.a.addClass(this.input, "placeholder-active") + } + _getNotchData() { + this._notchMiddle = a.a.findOne(v, this._element), + this._notchLeading = a.a.findOne(b, this._element) + } + _getLabelWidth() { + this._labelWidth = .8 * this._label.clientWidth + 8 + } + _getLabelPositionInInputGroup() { + var t; + this._labelMarginLeft = 0, + this._element.classList.contains("input-group") && (t = this.input, + t = a.a.prev(t, ".input-group-text")[0], + this._labelMarginLeft = void 0 === t ? 0 : t.offsetWidth - 1) + } + _applyDivs() { + var t = a.a.find(m, this._element) + , e = Object(i.b)("div"); + s.a.addClass(e, h), + this._notchLeading = Object(i.b)("div"), + s.a.addClass(this._notchLeading, d), + this._notchMiddle = Object(i.b)("div"), + s.a.addClass(this._notchMiddle, p), + this._notchTrailing = Object(i.b)("div"), + s.a.addClass(this._notchTrailing, "form-notch-trailing"), + 1 <= t.length || (e.append(this._notchLeading), + e.append(this._notchMiddle), + e.append(this._notchTrailing), + this._element.append(e)) + } + _applyNotch() { + this._notchMiddle.style.width = "".concat(this._labelWidth, "px"), + this._notchLeading.style.width = "".concat(this._labelMarginLeft + 9, "px"), + null !== this._label && (this._label.style.marginLeft = "".concat(this._labelMarginLeft, "px")) + } + _removeBorder() { + var t = a.a.findOne(m, this._element); + t && t.remove() + } + _activate(e) { + Object(i.i)(()=>{ + this._getElements(e); + var t = e ? e.target : this.input; + "" !== t.value && s.a.addClass(t, u), + this._toggleDefaultDatePlaceholder(t) + } + ) + } + _getElements(t) { + var e; + t && (this._element = t.target.parentNode, + this._label = a.a.findOne("label", this._element)), + t && this._label && (e = this._labelWidth, + this._getLabelData(), + e !== this._labelWidth) && (this._notchMiddle = a.a.findOne(".form-notch-middle", t.target.parentNode), + this._notchLeading = a.a.findOne(b, t.target.parentNode), + this._applyNotch()) + } + _deactivate(t) { + t = t ? t.target : this.input; + "" === t.value && t.classList.remove(u), + this._toggleDefaultDatePlaceholder(t) + } + static activate(e) { + return function(t) { + e._activate(t) + } + } + static deactivate(e) { + return function(t) { + e._deactivate(t) + } + } + static jQueryInterface(n, i) { + return this.each(function() { + let t = o.a.getData(this, c); + var e = "object" == typeof n && n; + if ((t || !/dispose/.test(n)) && (t = t || new y(this,e), + "string" == typeof n)) { + if (void 0 === t[n]) + throw new TypeError('No method named "'.concat(n, '"')); + t[n](i) + } + }) + } + static getInstance(t) { + return o.a.getData(t, c) + } + static getOrCreateInstance(t) { + var e = 1 < arguments.length && void 0 !== arguments[1] ? arguments[1] : {}; + return this.getInstance(t) || new this(t,"object" == typeof e ? e : null) + } + } + r.b.on(document, "focus", f, y.activate(new y)), + r.b.on(document, "input", f, y.activate(new y)), + r.b.on(document, "blur", f, y.deactivate(new y)), + r.b.on(document, "focus", g, y.activate(new y)), + r.b.on(document, "input", g, y.activate(new y)), + r.b.on(document, "blur", g, y.deactivate(new y)), + r.b.on(window, "shown.bs.modal", t=>{ + a.a.find(f, t.target).forEach(t=>{ + t = y.getInstance(t.parentNode); + t && t.update() + } + ), + a.a.find(g, t.target).forEach(t=>{ + t = y.getInstance(t.parentNode); + t && t.update() + } + ) + } + ), + r.b.on(window, "shown.bs.dropdown", t=>{ + t = t.target.parentNode.querySelector(".dropdown-menu"); + t && (a.a.find(f, t).forEach(t=>{ + t = y.getInstance(t.parentNode); + t && t.update() + } + ), + a.a.find(g, t).forEach(t=>{ + t = y.getInstance(t.parentNode); + t && t.update() + } + )) + } + ), + r.b.on(window, "shown.bs.tab", t=>{ + let e; + e = (t.target.href || s.a.getDataAttribute(t.target, "target")).split("#")[1]; + t = a.a.findOne("#".concat(e)); + a.a.find(f, t).forEach(t=>{ + t = y.getInstance(t.parentNode); + t && t.update() + } + ), + a.a.find(g, t).forEach(t=>{ + t = y.getInstance(t.parentNode); + t && t.update() + } + ) + } + ), + a.a.find(".".concat(n)).map(t=>new y(t)), + r.b.on(window, "reset", t=>{ + a.a.find(f, t.target).forEach(t=>{ + t = y.getInstance(t.parentNode); + t && t.forceInactive() + } + ), + a.a.find(g, t.target).forEach(t=>{ + t = y.getInstance(t.parentNode); + t && t.forceInactive() + } + ) + } + ), + r.b.on(window, "onautocomplete", t=>{ + var e = y.getInstance(t.target.parentNode); + e && t.cancelable && e.forceActive() + } + ), + Object(i.i)(()=>{ + const t = Object(i.f)(); + if (t) { + const e = t.fn[l]; + t.fn[l] = y.jQueryInterface, + t.fn[l].Constructor = y, + t.fn[l].noConflict = ()=>(t.fn[l] = e, + y.jQueryInterface) + } + } + ), + e.a = y + } + , function(t, e, n) { + "use strict"; + n.d(e, "a", function() { + return o + }); + var i = n(104); + function o(t) { + return Object.assign({}, Object(i.a)(), t) + } + } + , function(t, e, n) { + "use strict"; + function i() { + return { + top: 0, + right: 0, + bottom: 0, + left: 0 + } + } + n.d(e, "a", function() { + return i + }) + } + , function(t, e, n) { + "use strict"; + function i(n, t) { + return t.reduce(function(t, e) { + return t[e] = n, + t + }, {}) + } + n.d(e, "a", function() { + return i + }) + } + , function(t, e, n) { + "use strict"; + n.d(e, "a", function() { + return o + }); + var i = n(87); + function o() { + return !/^((?!chrome|android).)*safari/i.test(Object(i.a)()) + } + } + , function(t, e, n) { + "use strict"; + n.d(e, "a", function() { + return i + }); + var o = n(10); + function i(t, e) { + var n = e.getRootNode && e.getRootNode(); + if (t.contains(e)) + return !0; + if (n && Object(o.c)(n)) { + var i = e; + do { + if (i && t.isSameNode(i)) + return !0 + } while (i = i.parentNode || i.host) + } + return !1 + } + } + , function(t, e, n) { + "use strict"; + n.d(e, "a", function() { + return i + }); + var c = n(25) + , u = n(37) + , h = n(64) + , d = n(5); + function i(t) { + var e, n = t.reference, i = t.element, t = t.placement, o = t ? Object(c.a)(t) : null, t = t ? Object(u.a)(t) : null, r = n.x + n.width / 2 - i.width / 2, s = n.y + n.height / 2 - i.height / 2; + switch (o) { + case d.u: + e = { + x: r, + y: n.y - i.height + }; + break; + case d.i: + e = { + x: r, + y: n.y + n.height + }; + break; + case d.s: + e = { + x: n.x + n.width, + y: s + }; + break; + case d.l: + e = { + x: n.x - i.width, + y: s + }; + break; + default: + e = { + x: n.x, + y: n.y + } + } + var a = o ? Object(h.a)(o) : null; + if (null != a) { + var l = "y" === a ? "height" : "width"; + switch (t) { + case d.t: + e[a] = e[a] - (n[l] / 2 - i[l] / 2); + break; + case d.k: + e[a] = e[a] + (n[l] / 2 - i[l] / 2) + } + } + return e + } + } + , function(t, e, n) { + "use strict"; + n(133), + n(11), + n(12); + var i = n(2) + , o = n(3); + const r = { + position: "top", + container: null, + refresh: 1e3, + filter: t=>t + } + , s = { + position: "string", + container: "(undefined|null|string)", + refresh: "number", + filter: "function" + }; + e.a = class { + constructor(t, e, n) { + this._element = t, + this._selector = e, + this._options = this._getConfig(n), + this._offset = null, + this._options.container && (this._parent = i.a.findOne(this._options.container)) + } + get stackableElements() { + return i.a.find(this._selector).filter((t,e)=>this._options.filter(t, e)).map(t=>({ + el: t, + rect: t.getBoundingClientRect() + })).filter(t=>{ + var {el: t, rect: e} = t + , t = t !== this._element && Object(o.h)(t); + return null === this._offset ? t : t && this._getBoundryOffset(e) < this._offset + } + ).sort((t,e)=>this._getBoundryOffset(e.rect) - this._getBoundryOffset(t.rect)) + } + get nextElements() { + return i.a.find(this._selector).filter(t=>t !== this._element).filter((t,e)=>this._options.filter(t, e)).filter(t=>(this._offset = null, + this._getBoundryOffset(t.getBoundingClientRect()) > this._offset)) + } + _getConfig(t) { + t = { + ...r, + ...t + }; + return Object(o.j)("Stack", t, s), + t + } + _getBoundryOffset(t) { + var e, n = this._options["position"]; + let i = 0 + , o = window.innerHeight; + return this._parent && (e = this._parent.getBoundingClientRect(), + i = e.top, + o = e.bottom), + "top" === n ? t.top - i : o - t.bottom + } + calculateOffset() { + var [t] = this.stackableElements; + return this._offset = t ? this._getBoundryOffset(t.rect) + t.rect.height : 0, + this._offset + } + } + } + , function(t, e, n) { + "use strict"; + n(17), + n(53), + n(72); + var l = n(3) + , i = n(7) + , r = n(1) + , c = n(0) + , s = n(2); + const o = "ripple" + , a = "mdb.ripple" + , u = "ripple-surface" + , h = "ripple-wave" + , d = "input-wrapper" + , p = [".btn", ".ripple"] + , f = "ripple-surface-unbound" + , g = [0, 0, 0] + , m = ["primary", "secondary", "success", "danger", "warning", "info", "light", "dark"] + , b = { + rippleCentered: !1, + rippleColor: "", + rippleDuration: "500ms", + rippleRadius: 0, + rippleUnbound: !1 + } + , v = { + rippleCentered: "boolean", + rippleColor: "string", + rippleDuration: "string", + rippleRadius: "number", + rippleUnbound: "boolean" + }; + class _ { + constructor(t, e) { + this._element = t, + this._options = this._getConfig(e), + this._element && (i.a.setData(t, a, this), + c.a.addClass(this._element, u)), + this._clickHandler = this._createRipple.bind(this), + this._rippleTimer = null, + this._isMinWidthSet = !1, + this._rippleInSpan = !1, + this.init() + } + static get NAME() { + return o + } + init() { + this._addClickEvent(this._element) + } + dispose() { + i.a.removeData(this._element, a), + r.b.off(this._element, "click", this._clickHandler), + this._element = null, + this._options = null + } + _autoInit(e) { + if (p.forEach(t=>{ + s.a.closest(e.target, t) && (this._element = s.a.closest(e.target, t)) + } + ), + this._options = this._getConfig(), + "input" === this._element.tagName.toLowerCase()) { + var t = this._element.parentNode; + if (this._rippleInSpan = !0, + "span" === t.tagName.toLowerCase() && t.classList.contains(u)) + this._element = t; + else { + var n = getComputedStyle(this._element).boxShadow; + const o = this._element; + var i = document.createElement("span"); + o.classList.contains("btn-block") && (i.style.display = "block"), + r.b.one(i, "mouseup", t=>{ + 0 === t.button && o.click() + } + ), + i.classList.add(u, d), + c.a.addStyle(i, { + border: 0, + "box-shadow": n + }), + t.replaceChild(i, this._element), + i.appendChild(this._element), + this._element = i + } + this._element.focus() + } + this._element.style.minWidth || (c.a.style(this._element, { + "min-width": "".concat(getComputedStyle(this._element).width) + }), + this._isMinWidthSet = !0), + c.a.addClass(this._element, u), + this._createRipple(e) + } + _addClickEvent(t) { + r.b.on(t, "mousedown", this._clickHandler) + } + _getEventLayer(t) { + return { + layerX: Math.round(t.clientX - t.target.getBoundingClientRect().x), + layerY: Math.round(t.clientY - t.target.getBoundingClientRect().y) + } + } + _createRipple(t) { + var e, n, i, o, r, s, a; + null !== this._element && (c.a.hasClass(this._element, u) || c.a.addClass(this._element, u), + {layerX: t, layerY: e} = this._getEventLayer(t), + t = t, + e = e, + n = this._element.offsetHeight, + a = this._element.offsetWidth, + i = this._durationToMsNumber(this._options.rippleDuration), + o = { + offsetX: this._options.rippleCentered ? n / 2 : t, + offsetY: this._options.rippleCentered ? a / 2 : e, + height: n, + width: a + }, + o = this._getDiameter(o), + r = this._options.rippleRadius || o / 2, + s = { + delay: .5 * i, + duration: i - .5 * i + }, + a = { + left: this._options.rippleCentered ? "".concat(a / 2 - r, "px") : "".concat(t - r, "px"), + top: this._options.rippleCentered ? "".concat(n / 2 - r, "px") : "".concat(e - r, "px"), + height: "".concat(2 * this._options.rippleRadius || o, "px"), + width: "".concat(2 * this._options.rippleRadius || o, "px"), + transitionDelay: "0s, ".concat(s.delay, "ms"), + transitionDuration: "".concat(i, "ms, ").concat(s.duration, "ms") + }, + t = Object(l.b)("div"), + this._createHTMLRipple({ + wrapper: this._element, + ripple: t, + styles: a + }), + this._removeHTMLRipple({ + ripple: t, + duration: i + })) + } + _createHTMLRipple(t) { + let {wrapper: e, ripple: n, styles: i} = t; + Object.keys(i).forEach(t=>n.style[t] = i[t]), + n.classList.add(h), + "" !== this._options.rippleColor && (this._removeOldColorClasses(e), + this._addColor(n, e)), + this._toggleUnbound(e), + this._appendRipple(n, e) + } + _removeHTMLRipple(t) { + let {ripple: e, duration: n} = t; + this._rippleTimer && (clearTimeout(this._rippleTimer), + this._rippleTimer = null), + this._rippleTimer = setTimeout(()=>{ + e && (e.remove(), + this._element) && (s.a.find(".".concat(h), this._element).forEach(t=>{ + t.remove() + } + ), + this._isMinWidthSet && (c.a.style(this._element, { + "min-width": "" + }), + this._isMinWidthSet = !1), + this._rippleInSpan && this._element.classList.contains(d) ? this._removeWrapperSpan() : c.a.removeClass(this._element, u)) + } + , n) + } + _removeWrapperSpan() { + var t = this._element.firstChild; + this._element.replaceWith(t), + this._element = t, + this._element.focus(), + this._rippleInSpan = !1 + } + _durationToMsNumber(t) { + return Number(t.replace("ms", "").replace("s", "000")) + } + _getConfig() { + var t = 0 < arguments.length && void 0 !== arguments[0] ? arguments[0] : {} + , e = c.a.getDataAttributes(this._element) + , t = { + ...b, + ...e, + ...t + }; + return Object(l.j)(o, t, v), + t + } + _getDiameter(t) { + var {offsetX: t, offsetY: e, height: n, width: i} = t + , o = e <= n / 2 + , r = t <= i / 2 + , s = (t,e)=>Math.sqrt(t ** 2 + e ** 2) + , a = e === n / 2 && t === i / 2; + const l = !0 == o && !1 == r + , c = !0 == o && !0 == r + , u = !1 == o && !0 == r + , h = !1 == o && !1 == r; + o = { + topLeft: s(t, e), + topRight: s(i - t, e), + bottomLeft: s(t, n - e), + bottomRight: s(i - t, n - e) + }; + let d = 0; + return a || h ? d = o.topLeft : u ? d = o.topRight : c ? d = o.bottomRight : l && (d = o.bottomLeft), + 2 * d + } + _appendRipple(t, e) { + e.appendChild(t), + setTimeout(()=>{ + c.a.addClass(t, "active") + } + , 50) + } + _toggleUnbound(t) { + !0 === this._options.rippleUnbound ? c.a.addClass(t, f) : t.classList.remove(f) + } + _addColor(t, e) { + m.find(t=>t === this._options.rippleColor.toLowerCase()) ? c.a.addClass(e, "".concat(u, "-").concat(this._options.rippleColor.toLowerCase())) : (e = this._colorToRGB(this._options.rippleColor).join(","), + e = "rgba({{color}}, 0.2) 0, rgba({{color}}, 0.3) 40%, rgba({{color}}, 0.4) 50%, rgba({{color}}, 0.5) 60%, rgba({{color}}, 0) 70%".split("{{color}}").join("".concat(e)), + t.style.backgroundImage = "radial-gradient(circle, ".concat(e, ")")) + } + _removeOldColorClasses(e) { + var t = new RegExp("".concat(u, "-[a-z]+"),"gi"); + (e.classList.value.match(t) || []).forEach(t=>{ + e.classList.remove(t) + } + ) + } + _colorToRGB(t) { + var e, n, i; + return "transparent" === t.toLowerCase() ? g : "#" === t[0] ? ((e = t).length < 7 && (e = "#".concat(e[1]).concat(e[1]).concat(e[2]).concat(e[2]).concat(e[3]).concat(e[3])), + [parseInt(e.substr(1, 2), 16), parseInt(e.substr(3, 2), 16), parseInt(e.substr(5, 2), 16)]) : (-1 === t.indexOf("rgb") && (e = t, + n = document.body.appendChild(document.createElement("fictum")), + i = "rgb(1, 2, 3)", + n.style.color = i, + t = n.style.color !== i || (n.style.color = e, + n.style.color === i) || "" === n.style.color ? g : (e = getComputedStyle(n).color, + document.body.removeChild(n), + e)), + 0 === t.indexOf("rgb") ? ((i = (i = t).match(/[.\d]+/g).map(t=>+Number(t))).length = 3, + i) : g) + } + static autoInitial(e) { + return function(t) { + e._autoInit(t) + } + } + static jQueryInterface(t) { + return this.each(function() { + return i.a.getData(this, a) ? null : new _(this,t) + }) + } + static getInstance(t) { + return i.a.getData(t, a) + } + static getOrCreateInstance(t) { + var e = 1 < arguments.length && void 0 !== arguments[1] ? arguments[1] : {}; + return this.getInstance(t) || new this(t,"object" == typeof e ? e : null) + } + } + p.forEach(t=>{ + r.b.one(document, "mousedown", t, _.autoInitial(new _)) + } + ), + Object(l.i)(()=>{ + const t = Object(l.f)(); + if (t) { + const e = t.fn[o]; + t.fn[o] = _.jQueryInterface, + t.fn[o].Constructor = _, + t.fn[o].noConflict = ()=>(t.fn[o] = e, + _.jQueryInterface) + } + } + ), + e.a = _ + } + , function(t, e, n) { + "use strict"; + var i = n(23) + , o = n(22) + , r = n(142) + , s = n(76) + , a = n(77) + , l = n(113) + , c = n(29) + , u = n(148) + , h = Object.getOwnPropertyDescriptor; + e.f = i ? h : function(t, e) { + if (t = a(t), + e = l(e), + u) + try { + return h(t, e) + } catch (t) {} + if (c(t, e)) + return s(!o(r.f, t, e), t[e]) + } + } + , function(t, e, n) { + "use strict"; + var i = n(14) + , o = n(16) + , r = n(55) + , s = Object + , a = i("".split); + t.exports = o(function() { + return !s("z").propertyIsEnumerable(0) + }) ? function(t) { + return "String" === r(t) ? a(t, "") : s(t) + } + : s + } + , function(t, e, n) { + "use strict"; + var i = n(207) + , o = n(144); + t.exports = function(t) { + t = i(t, "string"); + return o(t) ? t : t + "" + } + } + , function(t, e, n) { + "use strict"; + var i = n(43) + , o = n(115); + (t.exports = function(t, e) { + return o[t] || (o[t] = void 0 !== e ? e : {}) + } + )("versions", []).push({ + version: "3.32.2", + mode: i ? "pure" : "global", + copyright: "© 2014-2023 Denis Pushkarev (zloirock.ru)", + license: "https://github.com/zloirock/core-js/blob/v3.32.2/LICENSE", + source: "https://github.com/zloirock/core-js" + }) + } + , function(t, e, n) { + "use strict"; + var i = n(13) + , n = n(116) + , o = "__core-js_shared__" + , i = i[o] || n(o, {}); + t.exports = i + } + , function(t, e, n) { + "use strict"; + var i = n(13) + , o = Object.defineProperty; + t.exports = function(e, n) { + try { + o(i, e, { + value: n, + configurable: !0, + writable: !0 + }) + } catch (t) { + i[e] = n + } + return n + } + } + , function(t, e, n) { + "use strict"; + var i = n(23) + , n = n(29) + , o = Function.prototype + , r = i && Object.getOwnPropertyDescriptor + , n = n(o, "name") + , s = n && "something" === function() {} + .name + , i = n && (!i || r(o, "name").configurable); + t.exports = { + EXISTS: n, + PROPER: s, + CONFIGURABLE: i + } + } + , function(t, e, n) { + "use strict"; + var i = n(14) + , o = n(15) + , n = n(115) + , r = i(Function.toString); + o(n.inspectSource) || (n.inspectSource = function(t) { + return r(t) + } + ), + t.exports = n.inspectSource + } + , function(t, e, n) { + "use strict"; + var i = n(114) + , o = n(147) + , r = i("keys"); + t.exports = function(t) { + return r[t] || (r[t] = o(t)) + } + } + , function(t, e, n) { + "use strict"; + t.exports = {} + } + , function(t, e, n) { + "use strict"; + t.exports = ["constructor", "hasOwnProperty", "isPrototypeOf", "propertyIsEnumerable", "toLocaleString", "toString", "valueOf"] + } + , function(t, e, n) { + "use strict"; + function i(t, e) { + return (t = l[a(t)]) === u || t !== c && (r(e) ? o(e) : !!e) + } + var o = n(16) + , r = n(15) + , s = /#|\.prototype\./ + , a = i.normalize = function(t) { + return String(t).replace(s, ".").toLowerCase() + } + , l = i.data = {} + , c = i.NATIVE = "N" + , u = i.POLYFILL = "P"; + t.exports = i + } + , function(t, e, n) { + "use strict"; + var o = n(215) + , r = n(30) + , s = n(216); + t.exports = Object.setPrototypeOf || ("__proto__"in {} ? function() { + var n, i = !1, t = {}; + try { + (n = o(Object.prototype, "__proto__", "set"))(t, []), + i = t instanceof Array + } catch (t) {} + return function(t, e) { + return r(t), + s(e), + i ? n(t, e) : t.__proto__ = e, + t + } + }() : void 0) + } + , function(t, e, n) { + "use strict"; + var f = n(22) + , i = n(14) + , g = n(38) + , m = n(125) + , o = n(166) + , r = n(114) + , b = n(80) + , v = n(46).get + , s = n(167) + , n = n(168) + , _ = r("native-string-replace", String.prototype.replace) + , y = RegExp.prototype.exec + , w = y + , O = i("".charAt) + , x = i("".indexOf) + , S = i("".replace) + , C = i("".slice) + , E = (r = /b*/g, + f(y, i = /a/, "a"), + f(y, r, "a"), + 0 !== i.lastIndex || 0 !== r.lastIndex) + , k = o.BROKEN_CARET + , A = void 0 !== /()??/.exec("")[1]; + (E || A || k || s || n) && (w = function(t) { + var e, n, i, o, r, s, a = this, l = v(a), t = g(t), c = l.raw; + if (c) + return c.lastIndex = a.lastIndex, + h = f(w, c, t), + a.lastIndex = c.lastIndex, + h; + var u = l.groups + , c = k && a.sticky + , h = f(m, a) + , l = a.source + , d = 0 + , p = t; + if (c && (h = S(h, "y", ""), + -1 === x(h, "g") && (h += "g"), + p = C(t, a.lastIndex), + 0 < a.lastIndex && (!a.multiline || a.multiline && "\n" !== O(t, a.lastIndex - 1)) && (l = "(?: " + l + ")", + p = " " + p, + d++), + e = new RegExp("^(?:" + l + ")",h)), + A && (e = new RegExp("^" + l + "$(?!\\s)",h)), + E && (n = a.lastIndex), + i = f(y, c ? e : a, p), + c ? i ? (i.input = C(i.input, d), + i[0] = C(i[0], d), + i.index = a.lastIndex, + a.lastIndex += i[0].length) : a.lastIndex = 0 : E && i && (a.lastIndex = a.global ? i.index + i[0].length : n), + A && i && 1 < i.length && f(_, i[0], e, function() { + for (o = 1; o < arguments.length - 2; o++) + void 0 === arguments[o] && (i[o] = void 0) + }), + i && u) + for (i.groups = r = b(null), + o = 0; o < u.length; o++) + r[(s = u[o])[0]] = i[s[1]]; + return i + } + ), + t.exports = w + } + , function(t, e, n) { + "use strict"; + var i = n(30); + t.exports = function() { + var t = i(this) + , e = ""; + return t.hasIndices && (e += "d"), + t.global && (e += "g"), + t.ignoreCase && (e += "i"), + t.multiline && (e += "m"), + t.dotAll && (e += "s"), + t.unicode && (e += "u"), + t.unicodeSets && (e += "v"), + t.sticky && (e += "y"), + e + } + } + , function(t, e, n) { + "use strict"; + function i(o) { + return function(t, e) { + var n, t = s(a(t)), e = r(e), i = t.length; + return e < 0 || i <= e ? o ? "" : void 0 : (n = c(t, e)) < 55296 || 56319 < n || e + 1 === i || (i = c(t, e + 1)) < 56320 || 57343 < i ? o ? l(t, e) : n : o ? u(t, e, e + 2) : i - 56320 + (n - 55296 << 10) + 65536 + } + } + var o = n(14) + , r = n(92) + , s = n(38) + , a = n(73) + , l = o("".charAt) + , c = o("".charCodeAt) + , u = o("".slice); + t.exports = { + codeAt: i(!1), + charAt: i(!0) + } + } + , function(t, e, n) { + "use strict"; + var i = n(56) + , o = TypeError; + t.exports = function(t, e) { + if (i(e, t)) + return t; + throw o("Incorrect invocation") + } + } + , function(t, e, n) { + "use strict"; + var i = TypeError; + t.exports = function(t, e) { + if (t < e) + throw i("Not enough arguments"); + return t + } + } + , function(t, e, n) { + "use strict"; + t.exports = function(t) { + try { + return { + error: !1, + value: t() + } + } catch (t) { + return { + error: !0, + value: t + } + } + } + } + , function(t, e, n) { + "use strict"; + var i = n(22) + , o = n(39) + , r = n(30) + , s = n(78) + , a = n(96) + , l = TypeError; + t.exports = function(t, e) { + e = arguments.length < 2 ? a(t) : e; + if (o(e)) + return r(i(e, t)); + throw l(s(t) + " is not iterable") + } + } + , function(t, e, n) { + "use strict"; + n(11), + n(12); + var i = n(8) + , o = n(34) + , r = n(4); + const s = ".fixed-top, .fixed-bottom, .is-fixed, .sticky-top" + , a = ".sticky-top" + , l = "padding-right" + , c = "margin-right"; + e.a = class { + constructor() { + this._element = document.body + } + getWidth() { + var t = document.documentElement.clientWidth; + return Math.abs(window.innerWidth - t) + } + hide() { + const e = this.getWidth(); + this._disableOverFlow(), + this._setElementAttributes(this._element, l, t=>t + e), + this._setElementAttributes(s, l, t=>t + e), + this._setElementAttributes(a, c, t=>t - e) + } + reset() { + this._resetElementAttributes(this._element, "overflow"), + this._resetElementAttributes(this._element, l), + this._resetElementAttributes(s, l), + this._resetElementAttributes(a, c) + } + isOverflowing() { + return 0 < this.getWidth() + } + _disableOverFlow() { + this._saveInitialAttribute(this._element, "overflow"), + this._element.style.overflow = "hidden" + } + _setElementAttributes(t, n, i) { + const o = this.getWidth(); + this._applyManipulationCallback(t, t=>{ + var e; + t !== this._element && window.innerWidth > t.clientWidth + o || (this._saveInitialAttribute(t, n), + e = window.getComputedStyle(t).getPropertyValue(n), + t.style.setProperty(n, "".concat(i(Number.parseFloat(e)), "px"))) + } + ) + } + _saveInitialAttribute(t, e) { + var n = t.style.getPropertyValue(e); + n && o.a.setDataAttribute(t, e, n) + } + _resetElementAttributes(t, n) { + this._applyManipulationCallback(t, t=>{ + var e = o.a.getDataAttribute(t, n); + null === e ? t.style.removeProperty(n) : (o.a.removeDataAttribute(t, n), + t.style.setProperty(n, e)) + } + ) + } + _applyManipulationCallback(t, e) { + if (Object(r.l)(t)) + e(t); + else + for (const n of i.a.find(t, this._element)) + e(n) + } + } + } + , function(t, e, n) { + "use strict"; + n(28); + var i = n(2) + , o = n(3); + e.a = class { + constructor(t) { + var e = 1 < arguments.length && void 0 !== arguments[1] ? arguments[1] : {} + , n = 2 < arguments.length ? arguments[2] : void 0; + this._element = t, + this._toggler = n, + this._event = e.event || "blur", + this._condition = e.condition || (()=>!0), + this._selector = e.selector || 'button, a, input, select, textarea, [tabindex]:not([tabindex="-1"])', + this._onlyVisible = e.onlyVisible || !1, + this._focusableElements = [], + this._firstElement = null, + this._lastElement = null, + this.handler = t=>{ + this._condition(t) && t.target === this._lastElement && (t.preventDefault(), + this._firstElement.focus()) + } + } + trap() { + this._setElements(), + this._init(), + this._setFocusTrap() + } + disable() { + this._focusableElements.forEach(t=>{ + t.removeEventListener(this._event, this.handler) + } + ), + this._toggler && this._toggler.focus() + } + update() { + this._setElements(), + this._setFocusTrap() + } + _init() { + const e = t=>{ + this._firstElement && "Tab" === t.key && !this._focusableElements.includes(t.target) && (t.preventDefault(), + this._firstElement.focus(), + window.removeEventListener("keydown", e)) + } + ; + window.addEventListener("keydown", e) + } + _filterVisible(t) { + return t.filter(t=>{ + if (!Object(o.h)(t)) + return !1; + var e = i.a.parents(t, "*"); + for (let t = 0; t < e.length; t++) { + var n = window.getComputedStyle(e[t]); + if (n && ("none" === n.display || "hidden" === n.visibility)) + return !1 + } + return !0 + } + ) + } + _setElements() { + var t = i.a.find(this._selector, this._element); + this._focusableElements = t.filter(t=>{ + var e = "true" === t.getAttribute("data-mdb-disabled") || t.hasAttribute("disabled"); + return t.disabled || e ? null : t + } + ), + this._onlyVisible && (this._focusableElements = this._filterVisible(this._focusableElements)), + this._firstElement = this._focusableElements[0], + this._lastElement = this._focusableElements[this._focusableElements.length - 1] + } + _setFocusTrap() { + this._focusableElements.forEach((t,e)=>{ + e === this._focusableElements.length - 1 ? t.addEventListener(this._event, this.handler) : t.removeEventListener(this._event, this.handler) + } + ) + } + } + } + , function(t, e, n) { + "use strict"; + var i = n(26) + , o = n(14) + , a = n(39) + , l = n(50) + , c = n(58) + , u = n(231) + , h = n(38) + , r = n(16) + , d = n(173) + , s = n(176) + , p = n(232) + , f = n(233) + , g = n(90) + , m = n(234) + , b = [] + , v = o(b.sort) + , _ = o(b.push) + , n = r(function() { + b.sort(void 0) + }) + , o = r(function() { + b.sort(null) + }) + , s = s("sort") + , y = !r(function() { + if (g) + return g < 70; + if (!(p && 3 < p)) { + if (f) + return !0; + if (m) + return m < 603; + for (var t, e, n, i = "", o = 65; o < 76; o++) { + switch (t = String.fromCharCode(o), + o) { + case 66: + case 69: + case 70: + case 72: + e = 3; + break; + case 68: + case 71: + e = 4; + break; + default: + e = 2 + } + for (n = 0; n < 47; n++) + b.push({ + k: t + n, + v: e + }) + } + for (b.sort(function(t, e) { + return e.v - t.v + }), + n = 0; n < b.length; n++) + t = b[n].k.charAt(0), + i.charAt(i.length - 1) !== t && (i += t); + return "DGBEFHACIJK" !== i + } + }); + i({ + target: "Array", + proto: !0, + forced: n || !o || !s || !y + }, { + sort: function(t) { + void 0 !== t && a(t); + var e = l(this); + if (y) + return void 0 === t ? v(e) : v(e, t); + for (var n, i, o = [], r = c(e), s = 0; s < r; s++) + s in e && _(o, e[s]); + for (d(o, (i = t, + function(t, e) { + return void 0 === e ? -1 : void 0 === t ? 1 : void 0 !== i ? +i(t, e) || 0 : h(t) > h(e) ? 1 : -1 + } + )), + n = c(o), + s = 0; s < n; ) + e[s] = o[s++]; + for (; s < r; ) + u(e, s++); + return e + } + }) + } + , function(D, t, e) { + "use strict"; + e(11), + e(12), + e(28), + e(17); + var n = e(141) + , o = e(7) + , i = e(1) + , h = e(0) + , r = e(2) + , d = e(3) + , s = e(102); + const a = ".form-check-input" + , l = "selected"; + var p = class { + constructor(t, e, n, i, o, r, s, a, l, c, u) { + this.id = t, + this.nativeOption = e, + this.multiple = n, + this.value = i, + this.label = o, + this.selected = r, + this.disabled = s, + this.hidden = a, + this.secondaryText = l, + this.groupId = c, + this.icon = u, + this.node = null, + this.active = !1 + } + select() { + this.multiple ? this._selectMultiple() : this._selectSingle() + } + _selectSingle() { + this.selected || (h.a.addClass(this.node, l), + this.node.setAttribute("aria-selected", !0), + this.selected = !0, + this.nativeOption && (this.nativeOption.selected = !0)) + } + _selectMultiple() { + this.selected || (r.a.findOne(a, this.node).checked = !0, + h.a.addClass(this.node, l), + this.node.setAttribute("aria-selected", !0), + this.selected = !0, + this.nativeOption && (this.nativeOption.selected = !0)) + } + deselect() { + this.multiple ? this._deselectMultiple() : this._deselectSingle() + } + _deselectSingle() { + this.selected && (h.a.removeClass(this.node, l), + this.node.setAttribute("aria-selected", !1), + this.selected = !1, + this.nativeOption) && (this.nativeOption.selected = !1) + } + _deselectMultiple() { + this.selected && (r.a.findOne(a, this.node).checked = !1, + h.a.removeClass(this.node, l), + this.node.setAttribute("aria-selected", !1), + this.selected = !1, + this.nativeOption) && (this.nativeOption.selected = !1) + } + setNode(t) { + this.node = t + } + setActiveStyles() { + this.active || this.multiple || (this.active = !0, + h.a.addClass(this.node, "active")) + } + removeActiveStyles() { + this.active && (this.active = !1, + h.a.removeClass(this.node, "active")) + } + } + ; + var c = class { + constructor() { + this._multiple = 0 < arguments.length && void 0 !== arguments[0] && arguments[0], + this._selections = [] + } + select(t) { + this._multiple ? this._selections.push(t) : this._selections = [t] + } + deselect(e) { + var t; + this._multiple ? (t = this._selections.findIndex(t=>e === t), + this._selections.splice(t, 1)) : this._selections = [] + } + clear() { + this._selections = [] + } + get selection() { + return this._selections[0] + } + get selections() { + return this._selections + } + get label() { + return this._selections[0] && this.selection.label + } + get labels() { + return this._selections.map(t=>t.label).join(", ") + } + get value() { + return this.selections[0] && this.selection.value + } + get values() { + return this._selections.map(t=>t.value) + } + } + , u = e(9); + function f(t) { + return t.filter(t=>!t.disabled).every(t=>t.selected) + } + const g = t=>{ + "Tab" !== t.code && "Esc" !== t.code && t.preventDefault() + } + ; + function m(t, e, n, i, o, r, s) { + var a = document.createElement("div") + , t = (a.classList.add("select-dropdown-container"), + a.setAttribute("id", "".concat(t)), + a.style.width = "".concat(n, "px"), + document.createElement("div")) + , n = (t.setAttribute("tabindex", 0), + t.classList.add("select-dropdown"), + Object(d.b)("div")) + , i = (h.a.addClass(n, "select-options-wrapper"), + n.style.maxHeight = "".concat(i, "px"), + b(r, o, e)); + return n.appendChild(i), + e.filter && t.appendChild((r = e.searchPlaceholder, + o = Object(d.b)("div"), + h.a.addClass(o, "input-group"), + i = Object(d.b)("input"), + h.a.addClass(i, "form-control"), + h.a.addClass(i, "select-filter-input"), + i.placeholder = r, + i.setAttribute("role", "searchbox"), + i.setAttribute("type", "text"), + o.appendChild(i), + o)), + t.appendChild(n), + s && t.appendChild(s), + a.appendChild(t), + a + } + function b(t, e, n) { + const i = Object(d.b)("div"); + h.a.addClass(i, "select-options-list"); + let o; + return (o = n.multiple ? function(t, e, n) { + let i = null; + n.selectAll && (i = function(t, e, n) { + var e = f(e) + , i = Object(d.b)("div"); + h.a.addClass(i, "select-option"), + h.a.addClass(i, "select-all-option"), + h.a.addStyle(i, { + height: "".concat(n.optionHeight, "px") + }), + i.setAttribute("role", "option"), + i.setAttribute("aria-selected", e), + e && h.a.addClass(i, "selected"); + return i.appendChild(y(t, n)), + t.setNode(i), + i + }(e, t, n)); + e = v(t, n), + t = i ? [i, ...e] : e; + return t + }(t, e, n) : function(t, e) { + t = v(t, e); + return t + }(t, n)).forEach(t=>{ + i.appendChild(t) + } + ), + i + } + function v(t, n) { + const i = []; + return t.forEach(t=>{ + var e; + t.hasOwnProperty("options") ? (e = function(t, e) { + const n = Object(d.b)("div"); + h.a.addClass(n, "select-option-group"), + n.setAttribute("role", "group"), + n.setAttribute("id", t.id), + t.hidden && h.a.addClass(n, "d-none"); + var i = Object(d.b)("label"); + return h.a.addClass(i, "select-option-group-label"), + h.a.addStyle(i, { + height: "".concat(e.optionHeight, "px") + }), + i.setAttribute("for", t.id), + i.textContent = t.label, + n.appendChild(i), + t.options.forEach(t=>{ + n.appendChild(_(t, e)) + } + ), + n + }(t, n), + i.push(e)) : i.push(_(t, n)) + } + ), + i + } + function _(t, e) { + var n, i, o; + return t.node || (n = Object(d.b)("div"), + h.a.addClass(n, "select-option"), + h.a.addStyle(n, { + height: "".concat(e.optionHeight, "px") + }), + h.a.setDataAttribute(n, "id", t.id), + n.setAttribute("role", "option"), + n.setAttribute("aria-selected", t.selected), + n.setAttribute("aria-disabled", t.disabled), + t.selected && h.a.addClass(n, "selected"), + t.disabled && h.a.addClass(n, "disabled"), + t.hidden && h.a.addClass(n, "d-none"), + n.appendChild(y(t, e)), + t.icon && n.appendChild((e = t, + i = Object(d.b)("span"), + h.a.addClass(i, "select-option-icon-container"), + o = Object(d.b)("img"), + h.a.addClass(o, "select-option-icon"), + h.a.addClass(o, "rounded-circle"), + o.src = e.icon, + i.appendChild(o), + i)), + t.setNode(n), + n) + } + function y(t, e) { + var n = Object(d.b)("span") + , i = (h.a.addClass(n, "select-option-text"), + document.createTextNode(t.label)); + return e.multiple && n.appendChild(function(t) { + var e = Object(d.b)("input") + , n = (e.setAttribute("type", "checkbox"), + h.a.addClass(e, "form-check-input"), + Object(d.b)("label")); + t.selected && e.setAttribute("checked", !0); + t.disabled && e.setAttribute("disabled", !0); + return e.appendChild(n), + e + }(t)), + n.appendChild(i), + !t.secondaryText && "number" != typeof t.secondaryText || n.appendChild((e = t.secondaryText, + i = Object(d.b)("span"), + h.a.addClass(i, "select-option-secondary-text"), + e = document.createTextNode(e), + i.appendChild(e), + i)), + n + } + const w = { + autoSelect: !1, + container: "body", + clearButton: !1, + disabled: !1, + displayedLabels: 5, + formWhite: !1, + multiple: !1, + optionsSelectedLabel: "options selected", + optionHeight: 38, + selectAll: !0, + selectAllLabel: "Select all", + searchPlaceholder: "Search...", + size: "default", + visibleOptions: 5, + filter: !1, + filterDebounce: 300, + noResultText: "No results", + validation: !1, + validFeedback: "Valid", + invalidFeedback: "Invalid", + placeholder: "", + filterFn: null + } + , O = { + autoSelect: "boolean", + container: "string", + clearButton: "boolean", + disabled: "boolean", + displayedLabels: "number", + formWhite: "boolean", + multiple: "boolean", + optionsSelectedLabel: "string", + optionHeight: "number", + selectAll: "boolean", + selectAllLabel: "string", + searchPlaceholder: "string", + size: "string", + visibleOptions: "number", + filter: "boolean", + filterDebounce: "number", + noResultText: "string", + validation: "boolean", + validFeedback: "string", + invalidFeedback: "string", + placeholder: "", + filterFn: "(function|null)" + } + , x = "select" + , S = "mdb.select"; + e = ".".concat(S); + const C = "close".concat(e) + , N = "open".concat(e) + , E = "optionSelect".concat(e) + , k = "optionDeselect".concat(e) + , H = "valueChange".concat(e) + , B = "shown".concat(e) + , W = "hidden".concat(e); + const A = ".select-input" + , j = ".select-options-list" + , T = ".form-outline" + , L = "select-initialized" + , P = "active" + , R = "focused"; + class M { + constructor(t, e) { + this._element = t, + this._config = this._getConfig(e), + this._optionsToRender = this._getOptionsToRender(t), + this._plainOptions = this._getPlainOptions(this._optionsToRender), + this._filteredOptionsList = null, + this._selectionModel = new c(this.multiple), + this._activeOptionIndex = -1, + this._activeOption = null, + this._wrapperId = this._element.id ? "select-wrapper-".concat(this._element.id) : Object(d.e)("select-wrapper-"), + this._dropdownContainerId = this._element.id ? "select-dropdown-container-".concat(this._element.id) : Object(d.e)("select-dropdown-container-"), + this._selectAllId = this._element.id ? "select-all-".concat(this._element.id) : Object(d.e)("select-all-"), + this._debounceTimeoutId = null, + this._dropdownHeight = this._config.optionHeight * this._config.visibleOptions, + this._popper = null, + this._input = null, + this._label = r.a.next(this._element, ".select-label")[0], + this._fakeValue = null, + this._isFakeValueActive = !1, + this._customContent = r.a.next(t, ".select-custom-content")[0], + this._toggleButton = null, + this._elementToggle = null, + this._wrapper = null, + this._inputEl = null, + this._dropdownContainer = null, + this._container = null, + this._selectAllOption = null, + this._init(), + this._mutationObserver = null, + this._isOpen = !1, + this._addMutationObserver(), + this._element && o.a.setData(t, S, this) + } + static get NAME() { + return x + } + get filterInput() { + return r.a.findOne(".select-filter-input", this._dropdownContainer) + } + get dropdown() { + return r.a.findOne(".select-dropdown", this._dropdownContainer) + } + get optionsList() { + return r.a.findOne(j, this._dropdownContainer) + } + get optionsWrapper() { + return r.a.findOne(".select-options-wrapper", this._dropdownContainer) + } + get clearButton() { + return r.a.findOne(".select-clear-btn", this._wrapper) + } + get options() { + return this._filteredOptionsList || this._plainOptions + } + get value() { + return this.multiple ? this._selectionModel.values : this._selectionModel.value + } + get multiple() { + return this._config.multiple + } + get hasSelectAll() { + return this.multiple && this._config.selectAll + } + get hasSelection() { + return this._selectionModel.selection || 0 < this._selectionModel.selections.length + } + _getConfig(t) { + var e = h.a.getDataAttributes(this._element); + return t = { + ...w, + ...e, + ...t + }, + this._element.hasAttribute("multiple") && (t.multiple = !0), + this._element.hasAttribute("disabled") && (t.disabled = !0), + this._element.tabIndex && (t.tabIndex = this._element.getAttribute("tabIndex")), + Object(d.j)(x, t, O), + t + } + _getOptionsToRender(t) { + const n = []; + return t.childNodes.forEach(t=>{ + if ("OPTGROUP" === t.nodeName) { + const e = { + id: t.id ? "group-".concat(t.id) : Object(d.e)("group-"), + label: t.label, + disabled: t.hasAttribute("disabled"), + hidden: t.hasAttribute("hidden"), + options: [] + }; + t.childNodes.forEach(t=>{ + "OPTION" === t.nodeName && e.options.push(this._createOptionObject(t, e)) + } + ), + n.push(e) + } else + "OPTION" === t.nodeName && n.push(this._createOptionObject(t)) + } + ), + n + } + _getPlainOptions(t) { + if (!r.a.findOne("optgroup", this._element)) + return t; + const e = []; + return t.forEach(t=>{ + t.hasOwnProperty("options") ? t.options.forEach(t=>{ + e.push(t) + } + ) : e.push(t) + } + ), + e + } + _createOptionObject(t) { + var e = 1 < arguments.length && void 0 !== arguments[1] ? arguments[1] : {} + , n = t.id ? "option-".concat(t.id) : Object(d.e)("option-") + , i = e.id || null + , o = e.disabled || !1 + , r = t.selected || t.hasAttribute("selected") + , o = t.hasAttribute("disabled") || o + , e = t.hasAttribute("hidden") || e && e.hidden + , s = this.multiple + , a = t.value + , l = t.label + , c = h.a.getDataAttribute(t, "secondaryText") + , u = h.a.getDataAttribute(t, "icon"); + return new p(n,t,s,a,l,r,o,e,c,i,u) + } + _getNavigationOptions() { + var t = this.options.filter(t=>!t.hidden); + return this.hasSelectAll ? [this._selectAllOption, ...t] : t + } + _init() { + this._renderMaterialWrapper(), + this._wrapper = r.a.findOne("#".concat(this._wrapperId)), + this._input = r.a.findOne(A, this._wrapper), + "off" === this._element.getAttribute("autocomplete") && this._input.setAttribute("autocomplete", "off"); + var t = this._config.container; + this._container = "body" === t ? document.body : r.a.findOne(t), + this._initOutlineInput(), + this._setDefaultSelections(), + this._updateInputValue(), + this._appendFakeValue(), + this._updateFakeLabelPosition(), + this._updateLabelPosition(), + this._updateClearButtonVisibility(), + this._bindComponentEvents(), + this.hasSelectAll && (this._selectAllOption = this._createSelectAllOption()), + this._dropdownContainer = m(this._dropdownContainerId, this._config, this._input.offsetWidth, this._dropdownHeight, this._selectAllOption, this._optionsToRender, this._customContent), + this._setFirstActiveOption() + } + _renderMaterialWrapper() { + t = this._wrapperId, + e = this._config, + n = this._label, + (i = document.createElement("div")).setAttribute("id", t), + i.classList.add("select-wrapper"), + t = Object(d.b)("div"), + h.a.addClass(t, "form-outline"), + e.formWhite && h.a.addClass(t, "form-white"), + l = Object(d.b)("input"), + o = e.filter ? "combobox" : "listbox", + r = e.multiple ? "true" : "false", + s = e.disabled ? "true" : "false", + h.a.addClass(l, "form-control"), + h.a.addClass(l, "select-input"), + "sm" === e.size && h.a.addClass(l, "form-control-sm"), + "lg" === e.size && h.a.addClass(l, "form-control-lg"), + l.setAttribute("type", "text"), + l.setAttribute("role", o), + l.setAttribute("aria-multiselectable", r), + l.setAttribute("aria-disabled", s), + l.setAttribute("aria-haspopup", "true"), + l.setAttribute("aria-expanded", !1), + e.tabIndex && l.setAttribute("tabIndex", e.tabIndex), + e.disabled && l.setAttribute("disabled", ""), + "" !== e.placeholder && l.setAttribute("placeholder", e.placeholder), + e.validation ? (h.a.addStyle(l, { + "pointer-events": "none", + "caret-color": "transparent" + }), + h.a.addStyle(t, { + cursor: "pointer" + })) : l.setAttribute("readonly", "true"), + e.validation && (l.setAttribute("required", "true"), + l.setAttribute("aria-required", "true"), + l.addEventListener("keydown", g)), + o = Object(d.b)("div"), + h.a.addClass(o, "valid-feedback"), + r = document.createTextNode("".concat(e.validFeedback)), + o.appendChild(r), + s = Object(d.b)("div"), + h.a.addClass(s, "invalid-feedback"), + r = document.createTextNode("".concat(e.invalidFeedback)), + s.appendChild(r), + r = Object(d.b)("span"), + h.a.addClass(r, "select-clear-btn"), + a = document.createTextNode("✕"), + r.appendChild(a), + r.setAttribute("tabindex", "0"), + a = Object(d.b)("span"), + h.a.addClass(a, "select-arrow"), + t.appendChild(l), + n && t.appendChild(n), + e.validation && (t.appendChild(o), + t.appendChild(s)), + e.clearButton && t.appendChild(r), + t.appendChild(a), + i.appendChild(t); + var t, e, n, i, o, r, s, a, l = i; + this._element.parentNode.insertBefore(l, this._element), + h.a.addClass(this._element, L), + l.appendChild(this._element) + } + _initOutlineInput() { + var t = r.a.findOne(T, this._wrapper); + new s.a(t).init() + } + _bindComponentEvents() { + this._listenToComponentKeydown(), + this._listenToWrapperClick(), + this._listenToClearBtnClick(), + this._listenToClearBtnKeydown() + } + _setDefaultSelections() { + this.options.forEach(t=>{ + t.selected && this._selectionModel.select(t) + } + ) + } + _listenToComponentKeydown() { + i.b.on(this._wrapper, "keydown", this._handleKeydown.bind(this)) + } + _handleKeydown(t) { + this._isOpen && !this._config.filter ? this._handleOpenKeydown(t) : this._handleClosedKeydown(t) + } + _handleOpenKeydown(t) { + var e = t.keyCode + , n = e === u.f || e === u.n && t.altKey || e === u.m; + if (e === u.m && this._config.autoSelect && !this.multiple && this._handleAutoSelection(this._activeOption), + n) + this.close(), + this._input.focus(); + else { + switch (e) { + case u.c: + this._setNextOptionActive(), + this._scrollToOption(this._activeOption); + break; + case u.n: + this._setPreviousOptionActive(), + this._scrollToOption(this._activeOption); + break; + case u.g: + this._setFirstOptionActive(), + this._scrollToOption(this._activeOption); + break; + case u.d: + this._setLastOptionActive(), + this._scrollToOption(this._activeOption); + break; + case u.e: + return t.preventDefault(), + void (this._activeOption && (this.hasSelectAll && 0 === this._activeOptionIndex ? this._handleSelectAll() : this._handleSelection(this._activeOption))); + default: + return + } + t.preventDefault() + } + } + _handleClosedKeydown(t) { + var e = t.keyCode + , n = (e === u.e && t.preventDefault(), + e === u.e || e === u.c && t.altKey || e === u.c && this.multiple); + if (n && this.open(), + this.multiple) + switch (e) { + case u.c: + case u.n: + this.open(); + break; + default: + return + } + else + switch (e) { + case u.c: + if (t.altKey) + return; + this._setNextOptionActive(), + this._handleSelection(this._activeOption); + break; + case u.n: + this._setPreviousOptionActive(), + this._handleSelection(this._activeOption); + break; + case u.g: + this._setFirstOptionActive(), + this._handleSelection(this._activeOption); + break; + case u.d: + this._setLastOptionActive(), + this._handleSelection(this._activeOption); + break; + default: + return + } + t.preventDefault() + } + _scrollToOption(e) { + if (e) { + let t; + var n = this.options.filter(t=>!t.hidden) + , n = (t = this.hasSelectAll ? n.indexOf(e) + 1 : n.indexOf(e), + this._getNumberOfGroupsBeforeOption(t)) + , e = t + n + , n = this.optionsWrapper + , i = n.offsetHeight + , o = this._config.optionHeight + , r = n.scrollTop; + -1 < t && (n.scrollTop = (n = e * o) < r ? n : r + i < n + o ? n - i + o : r) + } + } + _getNumberOfGroupsBeforeOption(t) { + var e = this.options.filter(t=>!t.hidden) + , n = this._optionsToRender.filter(t=>!t.hidden) + , i = this.hasSelectAll ? t - 1 : t; + let o = 0; + for (let t = 0; t <= i; t++) + e[t].groupId && n[o] && n[o].id && e[t].groupId === n[o].id && o++; + return o + } + _setNextOptionActive() { + let t = this._activeOptionIndex + 1; + var e = this._getNavigationOptions(); + if (e[t]) { + for (; e[t].disabled; ) + if (!e[t += 1]) + return; + this._updateActiveOption(e[t], t) + } + } + _setPreviousOptionActive() { + let t = this._activeOptionIndex - 1; + var e = this._getNavigationOptions(); + if (e[t]) { + for (; e[t].disabled; ) + if (!e[--t]) + return; + this._updateActiveOption(e[t], t) + } + } + _setFirstOptionActive() { + var t = this._getNavigationOptions(); + this._updateActiveOption(t[0], 0) + } + _setLastOptionActive() { + var t = this._getNavigationOptions() + , e = t.length - 1; + this._updateActiveOption(t[e], e) + } + _updateActiveOption(t, e) { + var n = this._activeOption; + n && n.removeActiveStyles(), + t.setActiveStyles(), + this._activeOptionIndex = e, + this._activeOption = t + } + _listenToWrapperClick() { + i.b.on(this._wrapper, "click", ()=>{ + this.toggle() + } + ) + } + _listenToClearBtnClick() { + i.b.on(this.clearButton, "click", t=>{ + t.preventDefault(), + t.stopPropagation(), + this._handleClear() + } + ) + } + _listenToClearBtnKeydown() { + i.b.on(this.clearButton, "keydown", t=>{ + t.keyCode === u.e && (this._handleClear(), + t.preventDefault(), + t.stopPropagation()) + } + ) + } + _handleClear() { + var t; + this.multiple ? (this._selectionModel.clear(), + this._deselectAllOptions(this.options), + this.hasSelectAll && this._updateSelectAllState()) : (t = this._selectionModel.selection, + this._selectionModel.clear(), + t.deselect()), + this._updateInputValue(), + this._updateFakeLabelPosition(), + this._updateLabelPosition(), + this._updateClearButtonVisibility(), + this._emitValueChangeEvent(null), + this._emitNativeChangeEvent() + } + _listenToOptionsClick() { + i.b.on(this.optionsWrapper, "click", t=>{ + var e = t.target.classList.contains("select-option-group-label"); + if (!e) { + e = "DIV" === t.target.nodeName ? t.target : r.a.closest(t.target, ".select-option"); + if (e.classList.contains("select-all-option")) + this._handleSelectAll(); + else { + const n = e.dataset.mdbId; + t = this.options.find(t=>t.id === n); + t && !t.disabled && this._handleSelection(t) + } + } + } + ) + } + _handleSelectAll() { + this._selectAllOption.selected ? (this._deselectAllOptions(this.options), + this._selectAllOption.deselect()) : (this._selectAllOptions(this.options), + this._selectAllOption.select()), + this._updateInputValue(), + this._updateFakeLabelPosition(), + this._updateLabelPosition(), + this._updateClearButtonVisibility(), + this._emitValueChangeEvent(this.value), + this._emitNativeChangeEvent() + } + _selectAllOptions(t) { + t.forEach(t=>{ + t.selected || t.disabled || (this._selectionModel.select(t), + t.select()) + } + ) + } + _deselectAllOptions(t) { + t.forEach(t=>{ + t.selected && !t.disabled && (this._selectionModel.deselect(t), + t.deselect()) + } + ) + } + _handleSelection(t) { + this.multiple ? (this._handleMultiSelection(t), + this.hasSelectAll && this._updateSelectAllState()) : this._handleSingleSelection(t), + this._updateInputValue(), + this._updateFakeLabelPosition(), + this._updateLabelPosition(), + this._updateClearButtonVisibility() + } + _handleAutoSelection(t) { + this._singleOptionSelect(t), + this._updateInputValue(), + this._updateFakeLabelPosition(), + this._updateLabelPosition(), + this._updateClearButtonVisibility() + } + _handleSingleSelection(t) { + this._singleOptionSelect(t), + this.close(), + this._input.focus() + } + _singleOptionSelect(t) { + var e = this._selectionModel.selections[0]; + e && e !== t && (this._selectionModel.deselect(e), + e.deselect(), + e.node.setAttribute("selected", !1), + i.b.trigger(this._element, k, { + value: e.value + })), + e && t === e || (this._selectionModel.select(t), + t.select(), + t.node.setAttribute("selected", !0), + i.b.trigger(this._element, E, { + value: t.value + }), + this._emitValueChangeEvent(this.value), + this._emitNativeChangeEvent()) + } + _handleMultiSelection(t) { + t.selected ? (this._selectionModel.deselect(t), + t.deselect(), + t.node.setAttribute("selected", !1), + i.b.trigger(this._element, k, { + value: t.value + })) : (this._selectionModel.select(t), + t.select(), + t.node.setAttribute("selected", !0), + i.b.trigger(this._element, E, { + value: t.value + })), + this._emitValueChangeEvent(this.value), + this._emitNativeChangeEvent() + } + _emitValueChangeEvent(t) { + i.b.trigger(this._element, H, { + value: t + }) + } + _emitNativeChangeEvent() { + i.b.trigger(this._element, "change") + } + _updateInputValue() { + var t = this.multiple ? this._selectionModel.labels : this._selectionModel.label; + let e; + e = this.multiple && -1 !== this._config.displayedLabels && this._selectionModel.selections.length > this._config.displayedLabels ? "".concat(this._selectionModel.selections.length, " ").concat(this._config.optionsSelectedLabel) : t, + this.multiple || this._isSelectionValid(this._selectionModel.selection) ? this._isLabelEmpty(this._selectionModel.selection) ? this._input.value = " " : e ? this._input.value = e : this.multiple || !this._optionsToRender[0] ? this._input.value = "" : this._input.value = this._optionsToRender[0].label : this._input.value = "" + } + _isSelectionValid(t) { + return !t || !t.disabled && "" !== t.value + } + _isLabelEmpty(t) { + return !(!t || "" !== t.label) + } + _appendFakeValue() { + var t, e; + this._selectionModel.selection && !this._selectionModel._multiple && (t = this._selectionModel.selection.label, + this._fakeValue = (t = t, + (e = Object(d.b)("div")).textContent = t, + h.a.addClass(e, "form-label"), + h.a.addClass(e, "select-fake-value"), + e), + r.a.findOne(T, this._wrapper).appendChild(this._fakeValue)) + } + _updateLabelPosition() { + var t = h.a.hasClass(this._element, L) + , e = "" !== this._input.value; + this._label && (t && (e || this._isOpen || this._isFakeValueActive) ? h.a.addClass(this._label, P) : h.a.removeClass(this._label, P)) + } + _updateLabelPositionWhileClosing() { + this._label && ("" !== this._input.value || this._isFakeValueActive ? h.a.addClass(this._label, P) : h.a.removeClass(this._label, P)) + } + _updateFakeLabelPosition() { + this._fakeValue && (this.hasSelection && (this._fakeValue.textContent = this.hasSelection.label), + "" === this._input.value && "" !== this._fakeValue.innerHTML ? (this._isFakeValueActive = !0, + h.a.addClass(this._fakeValue, P)) : (this._isFakeValueActive = !1, + h.a.removeClass(this._fakeValue, P))) + } + _updateClearButtonVisibility() { + this.clearButton && (this._selectionModel.selection || 0 < this._selectionModel.selections.length ? h.a.addStyle(this.clearButton, { + display: "block" + }) : h.a.addStyle(this.clearButton, { + display: "none" + })) + } + _updateSelectAllState() { + var t = this._selectAllOption.selected + , e = f(this.options); + !e && t ? this._selectAllOption.deselect() : e && !t && this._selectAllOption.select() + } + toggle() { + this._isOpen ? this.close() : this.open() + } + open() { + var t = this._config.disabled + , e = i.b.trigger(this._element, N); + this._isOpen || t || e.defaultPrevented || (this._openDropdown(), + this._updateDropdownWidth(), + this._setFirstActiveOption(), + this._scrollToOption(this._activeOption), + this._config.filter && (setTimeout(()=>{ + this.filterInput.focus() + } + , 0), + this._listenToSelectSearch(), + this._listenToDropdownKeydown()), + this._listenToOptionsClick(), + this._listenToOutsideClick(), + this._listenToWindowResize(), + this._isOpen = !0, + i.b.trigger(this._element, B), + this._updateLabelPosition(), + this._setInputActiveStyles()) + } + _openDropdown() { + this._popper = Object(n.a)(this._input, this._dropdownContainer, { + placement: "bottom-start", + modifiers: [{ + name: "offset", + options: { + offset: [0, 1] + } + }] + }), + this._container.appendChild(this._dropdownContainer), + setTimeout(()=>{ + h.a.addClass(this.dropdown, "open") + } + , 0) + } + _updateDropdownWidth() { + var t = this._input.offsetWidth; + h.a.addStyle(this._dropdownContainer, { + width: "".concat(t, "px") + }) + } + _setFirstActiveOption() { + var t = this._getNavigationOptions() + , e = this._activeOption; + e && e.removeActiveStyles(); + const n = this.multiple ? this._selectionModel.selections[0] : this._selectionModel.selection; + n ? ((this._activeOption = n).setActiveStyles(), + this._activeOptionIndex = t.findIndex(t=>t === n)) : (this._activeOption = null, + this._activeOptionIndex = -1) + } + _setInputActiveStyles() { + h.a.addClass(this._input, R) + } + _listenToWindowResize() { + i.b.on(window, "resize", this._handleWindowResize.bind(this)) + } + _handleWindowResize() { + this._dropdownContainer && this._updateDropdownWidth() + } + _listenToSelectSearch() { + this.filterInput.addEventListener("input", t=>{ + var t = t.target.value + , e = this._config.filterDebounce; + this._debounceFilter(t, e) + } + ) + } + _debounceFilter(t, e) { + this._debounceTimeoutId && clearTimeout(this._debounceTimeoutId), + this._debounceTimeoutId = setTimeout(()=>{ + this._filterOptions(t) + } + , e) + } + _filterOptions(o) { + const r = [] + , s = this._config.filterFn; + this._optionsToRender.forEach(t=>{ + var e = t.hasOwnProperty("options") + , n = !e && t.label.toLowerCase().includes(o.toLowerCase()) + , i = {}; + e && (i.label = t.label, + i.options = this._filter(o, t.options), + 0 < i.options.length) && r.push(i), + s && !e ? s(o, t) && r.push(t) : n && r.push(t) + } + ); + var t = "" !== this._config.noResultText + , e = 0 !== r.length; + e ? (this._updateOptionsListTemplate(r), + this._popper.forceUpdate(), + this._filteredOptionsList = this._getPlainOptions(r), + this.hasSelectAll && this._updateSelectAllState(), + this._setFirstActiveOption()) : !e && t && (e = this._getNoResultTemplate(), + this.optionsWrapper.innerHTML = e) + } + _updateOptionsListTemplate(t) { + var e = r.a.findOne(j, this._dropdownContainer) || r.a.findOne(".select-no-results", this._dropdownContainer) + , t = b(t, this._selectAllOption, this._config); + this.optionsWrapper.removeChild(e), + this.optionsWrapper.appendChild(t) + } + _getNoResultTemplate() { + return '
').concat(this._config.noResultText, "
") + } + _filter(e, t) { + const n = this._config.filterFn; + if (n) + return t.filter(t=>n(e, t)); + const i = e.toLowerCase(); + return t.filter(t=>t.label.toLowerCase().includes(i)) + } + _listenToDropdownKeydown() { + i.b.on(this.dropdown, "keydown", this._handleOpenKeydown.bind(this)) + } + _listenToOutsideClick() { + this._outsideClick = this._handleOutSideClick.bind(this), + i.b.on(document, "click", this._outsideClick) + } + _handleOutSideClick(n) { + var t = this._wrapper && this._wrapper.contains(n.target) + , e = n.target === this._dropdownContainer + , i = this._dropdownContainer && this._dropdownContainer.contains(n.target); + let o; + this._toggleButton || (this._elementToggle = r.a.find("[data-mdb-toggle]")), + this._elementToggle && this._elementToggle.forEach(t=>{ + var e = h.a.getDataAttribute(t, "toggle"); + e !== this._element.id && !this._element.classList.contains(e) || (this._toggleButton = t, + o = this._toggleButton.contains(n.target)) + } + ), + t || e || i || o || this.close() + } + close() { + var t = i.b.trigger(this._element, C); + this._isOpen && !t.defaultPrevented && (this._config.filter && this.hasSelectAll && (this._resetFilterState(), + this._updateOptionsListTemplate(this._optionsToRender), + this._config.multiple) && this._updateSelectAllState(), + this._removeDropdownEvents(), + h.a.removeClass(this.dropdown, "open"), + setTimeout(()=>{ + h.a.removeClass(this._input, R), + this._label && !this.hasSelection && (h.a.removeClass(this._label, P), + h.a.removeClass(this._input, P)), + this._updateLabelPositionWhileClosing() + } + , 0), + setTimeout(()=>{ + this._container && this._dropdownContainer.parentNode === this._container && this._container.removeChild(this._dropdownContainer), + this._popper.destroy(), + this._isOpen = !1, + i.b.off(this.dropdown, "transitionend"), + i.b.trigger(this._element, W) + } + , 200)) + } + _resetFilterState() { + this.filterInput.value = "", + this._filteredOptionsList = null + } + _removeDropdownEvents() { + i.b.off(document, "click", this._outsideClick), + this._config.filter && i.b.off(this.dropdown, "keydown"), + i.b.off(this.optionsWrapper, "click") + } + _addMutationObserver() { + this._mutationObserver = new MutationObserver(()=>{ + this._wrapper && (this._updateSelections(), + this._updateDisabledState()) + } + ), + this._observeMutationObserver() + } + _updateSelections() { + this._optionsToRender = this._getOptionsToRender(this._element), + this._plainOptions = this._getPlainOptions(this._optionsToRender), + this._selectionModel.clear(), + this._setDefaultSelections(), + this._updateInputValue(), + this._updateFakeLabelPosition(), + this._updateLabelPosition(), + this._updateClearButtonVisibility(), + this.hasSelectAll && this._updateSelectAllState(); + var t = this._config.filter && this.filterInput && this.filterInput.value; + this._isOpen && !t ? (this._updateOptionsListTemplate(this._optionsToRender), + this._setFirstActiveOption()) : this._isOpen && t ? (this._filterOptions(this.filterInput.value), + this._setFirstActiveOption()) : this._dropdownContainer = m(this._dropdownContainerId, this._config, this._input.offsetWidth, this._dropdownHeight, this._selectAllOption, this._optionsToRender, this._customContent) + } + _updateDisabledState() { + var t = r.a.findOne(A, this._wrapper); + this._element.hasAttribute("disabled") ? (this._config.disabled = !0, + t.setAttribute("disabled", "")) : (this._config.disabled = !1, + t.removeAttribute("disabled")) + } + _observeMutationObserver() { + this._mutationObserver && this._mutationObserver.observe(this._element, { + attributes: !0, + childList: !0, + characterData: !0, + subtree: !0 + }) + } + _disconnectMutationObserver() { + this._mutationObserver && (this._mutationObserver.disconnect(), + this._mutationObserver = null) + } + _createSelectAllOption() { + var t = this._selectAllId + , e = this._config.selectAllLabel + , n = f(this.options); + return new p(t,null,!0,"select-all",e,n,!1,!1,null,null,null) + } + dispose() { + this._disconnectMutationObserver(), + this._removeComponentEvents(), + this._destroyMaterialSelect(), + o.a.removeData(this._element, S) + } + _removeComponentEvents() { + i.b.off(this.input, "click"), + i.b.off(this.wrapper, this._handleKeydown.bind(this)), + i.b.off(this.clearButton, "click"), + i.b.off(this.clearButton, "keydown"), + i.b.off(window, "resize", this._handleWindowResize.bind(this)) + } + _destroyMaterialSelect() { + this._isOpen && this.close(), + this._destroyMaterialTemplate() + } + _destroyMaterialTemplate() { + const e = this._wrapper.parentNode; + var t = r.a.find("label", this._wrapper); + e.appendChild(this._element), + t.forEach(t=>{ + e.appendChild(t) + } + ), + t.forEach(t=>{ + h.a.removeClass(t, P) + } + ), + h.a.removeClass(this._element, L), + e.removeChild(this._wrapper) + } + setValue(t) { + this.options.filter(t=>t.selected).forEach(t=>t.nativeOption.selected = !1), + Array.isArray(t) ? t.forEach(t=>{ + this._selectByValue(t) + } + ) : this._selectByValue(t), + this._updateSelections() + } + _selectByValue(e) { + var t = this.options.find(t=>t.value === e); + return !!t && (t.nativeOption.selected = !0) + } + static jQueryInterface(n, i) { + return this.each(function() { + let t = o.a.getData(this, S); + var e = "object" == typeof n && n; + if ((t || !/dispose/.test(n)) && (t = t || new M(this,e), + "string" == typeof n)) { + if (void 0 === t[n]) + throw new TypeError('No method named "'.concat(n, '"')); + t[n](i) + } + }) + } + static getInstance(t) { + return o.a.getData(t, S) + } + static getOrCreateInstance(t) { + var e = 1 < arguments.length && void 0 !== arguments[1] ? arguments[1] : {}; + return this.getInstance(t) || new this(t,"object" == typeof e ? e : null) + } + } + t.a = M; + const I = Object(d.f)(); + r.a.find(".select").forEach(t=>{ + var e = M.getInstance(t); + e || new M(t) + } + ), + Object(d.i)(()=>{ + if (I) { + const t = I.fn[x]; + I.fn[x] = M.jQueryInterface, + I.fn[x].Constructor = M, + I.fn[x].noConflict = ()=>(I.fn[x] = t, + M.jQueryInterface) + } + } + ) + } + , function(t, e, n) { + "use strict"; + n.d(e, "a", function() { + return C + }); + n(17); + function p(t) { + return getComputedStyle(t) + } + function a(e, n) { + for (const i in n) { + let t = n[i]; + "number" == typeof t && (t = "".concat(t, "px")), + e.style[i] = t + } + } + function l(t) { + var e = document.createElement("div"); + return e.className = t, + e + } + const i = "undefined" != typeof Element && (Element.prototype.matches || Element.prototype.webkitMatchesSelector || Element.prototype.mozMatchesSelector || Element.prototype.msMatchesSelector); + function c(t, e) { + if (i) + return i.call(t, e); + throw new Error("No element matching method supported") + } + function s(t) { + t.remove ? t.remove() : t.parentNode && t.parentNode.removeChild(t) + } + function u(t, e) { + return Array.prototype.filter.call(t.children, t=>c(t, e)) + } + const o = { + main: "ps", + rtl: "ps__rtl", + element: { + thumb: t=>"ps__thumb-".concat(t), + rail: t=>"ps__rail-".concat(t), + consuming: "ps__child--consume" + }, + state: { + focus: "ps--focus", + clicking: "ps--clicking", + active: t=>"ps--active-".concat(t), + scrolling: t=>"ps--scrolling-".concat(t) + } + }; + var v = o; + const r = { + x: null, + y: null + }; + function _(t, e) { + var t = t.element.classList + , n = o.state.scrolling(e); + t.contains(n) ? clearTimeout(r[e]) : t.add(n) + } + function y(t, e) { + r[e] = setTimeout(()=>t.isAlive && t.element.classList.remove(o.state.scrolling(e)), t.settings.scrollingThreshold) + } + class h { + constructor(t) { + this.element = t, + this.handlers = {} + } + bind(t, e) { + void 0 === this.handlers[t] && (this.handlers[t] = []), + this.handlers[t].push(e), + this.element.addEventListener(t, e, !1) + } + unbind(e, n) { + this.handlers[e] = this.handlers[e].filter(t=>!(!n || t === n) || (this.element.removeEventListener(e, t, !1), + !1)) + } + unbindAll() { + for (const t in this.handlers) + this.unbind(t) + } + get isEmpty() { + return Object.keys(this.handlers).every(t=>0 === this.handlers[t].length) + } + } + class d { + constructor() { + this.eventElements = [] + } + eventElement(e) { + let t = this.eventElements.filter(t=>t.element === e)[0]; + return t || (t = new h(e), + this.eventElements.push(t)), + t + } + bind(t, e, n) { + this.eventElement(t).bind(e, n) + } + unbind(t, e, n) { + t = this.eventElement(t); + t.unbind(e, n), + t.isEmpty && this.eventElements.splice(this.eventElements.indexOf(t), 1) + } + unbindAll() { + this.eventElements.forEach(t=>t.unbindAll()), + this.eventElements = [] + } + once(t, e, n) { + const i = this.eventElement(t) + , o = t=>{ + i.unbind(e, o), + n(t) + } + ; + i.bind(e, o) + } + } + n(11), + n(12); + function f(t) { + var e; + return "function" == typeof window.CustomEvent ? new CustomEvent(t) : ((e = document.createEvent("CustomEvent")).initCustomEvent(t, !1, !1, void 0), + e) + } + function g(t, e, n) { + var i = !(3 < arguments.length && void 0 !== arguments[3]) || arguments[3] + , o = 4 < arguments.length && void 0 !== arguments[4] && arguments[4]; + let r; + if ("top" === e) + r = ["contentHeight", "containerHeight", "scrollTop", "y", "up", "down"]; + else { + if ("left" !== e) + throw new Error("A proper axis should be provided"); + r = ["contentWidth", "containerWidth", "scrollLeft", "x", "left", "right"] + } + !function(t, e, n) { + var [n,i,o,r,s,a] = n + , l = !(3 < arguments.length && void 0 !== arguments[3]) || arguments[3] + , c = 4 < arguments.length && void 0 !== arguments[4] && arguments[4]; + var u = t.element; + t.reach[r] = null, + u[o] < 1 && (t.reach[r] = "start"); + u[o] > t[n] - t[i] - 1 && (t.reach[r] = "end"); + e && (u.dispatchEvent(f("ps-scroll-".concat(r))), + e < 0 ? u.dispatchEvent(f("ps-scroll-".concat(s))) : 0 < e && u.dispatchEvent(f("ps-scroll-".concat(a))), + l) && !function(t, e) { + _(t, e), + y(t, e) + }(t, r); + t.reach[r] && (e || c) && u.dispatchEvent(f("ps-".concat(r, "-reach-").concat(t.reach[r]))) + }(t, n, r, i, o) + } + function m(t) { + return parseInt(t, 10) || 0 + } + const b = { + isWebKit: "undefined" != typeof document && "WebkitAppearance"in document.documentElement.style, + supportsTouch: "undefined" != typeof window && ("ontouchstart"in window || "maxTouchPoints"in window.navigator && 0 < window.navigator.maxTouchPoints || window.DocumentTouch && document instanceof window.DocumentTouch), + supportsIePointer: "undefined" != typeof navigator && navigator.msMaxTouchPoints, + isChrome: "undefined" != typeof navigator && /Chrome/i.test(navigator && navigator.userAgent) + }; + var w = function(t) { + var e = t.element + , n = Math.floor(e.scrollTop) + , i = e.getBoundingClientRect() + , i = (t.containerWidth = Math.floor(i.width), + t.containerHeight = Math.floor(i.height), + t.contentWidth = e.scrollWidth, + t.contentHeight = e.scrollHeight, + e.contains(t.scrollbarXRail) || (u(e, v.element.rail("x")).forEach(t=>s(t)), + e.appendChild(t.scrollbarXRail)), + e.contains(t.scrollbarYRail) || (u(e, v.element.rail("y")).forEach(t=>s(t)), + e.appendChild(t.scrollbarYRail)), + !t.settings.suppressScrollX && t.containerWidth + t.settings.scrollXMarginOffset < t.contentWidth ? (t.scrollbarXActive = !0, + t.railXWidth = t.containerWidth - t.railXMarginWidth, + t.railXRatio = t.containerWidth / t.railXWidth, + t.scrollbarXWidth = O(t, m(t.railXWidth * t.containerWidth / t.contentWidth)), + t.scrollbarXLeft = m((t.negativeScrollAdjustment + e.scrollLeft) * (t.railXWidth - t.scrollbarXWidth) / (t.contentWidth - t.containerWidth))) : t.scrollbarXActive = !1, + !t.settings.suppressScrollY && t.containerHeight + t.settings.scrollYMarginOffset < t.contentHeight ? (t.scrollbarYActive = !0, + t.railYHeight = t.containerHeight - t.railYMarginHeight, + t.railYRatio = t.containerHeight / t.railYHeight, + t.scrollbarYHeight = O(t, m(t.railYHeight * t.containerHeight / t.contentHeight)), + t.scrollbarYTop = m(n * (t.railYHeight - t.scrollbarYHeight) / (t.contentHeight - t.containerHeight))) : t.scrollbarYActive = !1, + t.scrollbarXLeft >= t.railXWidth - t.scrollbarXWidth && (t.scrollbarXLeft = t.railXWidth - t.scrollbarXWidth), + t.scrollbarYTop >= t.railYHeight - t.scrollbarYHeight && (t.scrollbarYTop = t.railYHeight - t.scrollbarYHeight), + e) + , n = t + , o = { + width: n.railXWidth + } + , r = Math.floor(i.scrollTop); + n.isRtl ? o.left = n.negativeScrollAdjustment + i.scrollLeft + n.containerWidth - n.contentWidth : o.left = i.scrollLeft, + n.isScrollbarXUsingBottom ? o.bottom = n.scrollbarXBottom - r : o.top = n.scrollbarXTop + r, + a(n.scrollbarXRail, o), + o = { + top: r, + height: n.railYHeight + }, + n.isScrollbarYUsingRight ? n.isRtl ? o.right = n.contentWidth - (n.negativeScrollAdjustment + i.scrollLeft) - n.scrollbarYRight - n.scrollbarYOuterWidth - 9 : o.right = n.scrollbarYRight - i.scrollLeft : n.isRtl ? o.left = n.negativeScrollAdjustment + i.scrollLeft + 2 * n.containerWidth - n.contentWidth - n.scrollbarYLeft - n.scrollbarYOuterWidth : o.left = n.scrollbarYLeft + i.scrollLeft, + a(n.scrollbarYRail, o), + a(n.scrollbarX, { + left: n.scrollbarXLeft, + width: n.scrollbarXWidth - n.railBorderXWidth + }), + a(n.scrollbarY, { + top: n.scrollbarYTop, + height: n.scrollbarYHeight - n.railBorderYWidth + }), + t.scrollbarXActive ? e.classList.add(v.state.active("x")) : (e.classList.remove(v.state.active("x")), + t.scrollbarXWidth = 0, + t.scrollbarXLeft = 0, + e.scrollLeft = !0 === t.isRtl ? t.contentWidth : 0), + t.scrollbarYActive ? e.classList.add(v.state.active("y")) : (e.classList.remove(v.state.active("y")), + t.scrollbarYHeight = 0, + t.scrollbarYTop = 0, + e.scrollTop = 0) + }; + function O(t, e) { + return t.settings.minScrollbarLength && (e = Math.max(e, t.settings.minScrollbarLength)), + e = t.settings.maxScrollbarLength ? Math.min(e, t.settings.maxScrollbarLength) : e + } + function x(n, t) { + let[i,o,r,s,e,a,l,c,u] = t; + const h = n.element; + let d = null + , p = null + , f = null; + function g(t) { + t.touches && t.touches[0] && (t[r] = t.touches[0].pageY), + h[l] = d + f * (t[r] - p), + _(n, c), + w(n), + t.stopPropagation(), + t.preventDefault() + } + function m() { + y(n, c), + n[u].classList.remove(v.state.clicking), + n.event.unbind(n.ownerDocument, "mousemove", g) + } + function b(t, e) { + d = h[l], + e && t.touches && (t[r] = t.touches[0].pageY), + p = t[r], + f = (n[o] - n[i]) / (n[s] - n[a]), + e ? n.event.bind(n.ownerDocument, "touchmove", g) : (n.event.bind(n.ownerDocument, "mousemove", g), + n.event.once(n.ownerDocument, "mouseup", m), + t.preventDefault()), + n[u].classList.add(v.state.clicking), + t.stopPropagation() + } + n.event.bind(n[e], "mousedown", t=>{ + b(t) + } + ), + n.event.bind(n[e], "touchstart", t=>{ + b(t, !0) + } + ) + } + const S = { + "click-rail": function(n) { + n.event.bind(n.scrollbarY, "mousedown", t=>t.stopPropagation()), + n.event.bind(n.scrollbarYRail, "mousedown", t=>{ + var e = t.pageY - window.pageYOffset - n.scrollbarYRail.getBoundingClientRect().top > n.scrollbarYTop ? 1 : -1; + n.element.scrollTop += e * n.containerHeight, + w(n), + t.stopPropagation() + } + ), + n.event.bind(n.scrollbarX, "mousedown", t=>t.stopPropagation()), + n.event.bind(n.scrollbarXRail, "mousedown", t=>{ + var e = t.pageX - window.pageXOffset - n.scrollbarXRail.getBoundingClientRect().left > n.scrollbarXLeft ? 1 : -1; + n.element.scrollLeft += e * n.containerWidth, + w(n), + t.stopPropagation() + } + ) + }, + "drag-thumb": function(t) { + x(t, ["containerWidth", "contentWidth", "pageX", "railXWidth", "scrollbarX", "scrollbarXWidth", "scrollLeft", "x", "scrollbarXRail"]), + x(t, ["containerHeight", "contentHeight", "pageY", "railYHeight", "scrollbarY", "scrollbarYHeight", "scrollTop", "y", "scrollbarYRail"]) + }, + keyboard: function(r) { + const s = r.element; + r.event.bind(r.ownerDocument, "keydown", i=>{ + if (!(i.isDefaultPrevented && i.isDefaultPrevented() || i.defaultPrevented) && (c(s, ":hover") || c(r.scrollbarX, ":focus") || c(r.scrollbarY, ":focus"))) { + let t = document.activeElement || r.ownerDocument.activeElement; + if (t) { + if ("IFRAME" === t.tagName) + t = t.contentDocument.activeElement; + else + for (; t.shadowRoot; ) + t = t.shadowRoot.activeElement; + if (c(o = t, "input,[contenteditable]") || c(o, "select,[contenteditable]") || c(o, "textarea,[contenteditable]") || c(o, "button,[contenteditable]")) + return + } + var o; + let e = 0 + , n = 0; + switch (i.which) { + case 37: + e = i.metaKey ? -r.contentWidth : i.altKey ? -r.containerWidth : -30; + break; + case 38: + n = i.metaKey ? r.contentHeight : i.altKey ? r.containerHeight : 30; + break; + case 39: + e = i.metaKey ? r.contentWidth : i.altKey ? r.containerWidth : 30; + break; + case 40: + n = i.metaKey ? -r.contentHeight : i.altKey ? -r.containerHeight : -30; + break; + case 32: + n = i.shiftKey ? r.containerHeight : -r.containerHeight; + break; + case 33: + n = r.containerHeight; + break; + case 34: + n = -r.containerHeight; + break; + case 36: + n = r.contentHeight; + break; + case 35: + n = -r.contentHeight; + break; + default: + return + } + r.settings.suppressScrollX && 0 !== e || r.settings.suppressScrollY && 0 !== n || (s.scrollTop -= n, + s.scrollLeft += e, + w(r), + !function(t, e) { + var n = Math.floor(s.scrollTop); + if (0 === t) { + if (!r.scrollbarYActive) + return; + if (0 === n && 0 < e || n >= r.contentHeight - r.containerHeight && e < 0) + return !r.settings.wheelPropagation + } + if (n = s.scrollLeft, + 0 === e) { + if (!r.scrollbarXActive) + return; + if (0 === n && t < 0 || n >= r.contentWidth - r.containerWidth && 0 < t) + return !r.settings.wheelPropagation + } + return 1 + }(e, n)) || i.preventDefault() + } + } + ) + }, + wheel: function(a) { + const l = a.element; + function t(e) { + var [n,i] = function(t) { + let e = t.deltaX + , n = -1 * t.deltaY; + return void 0 !== e && void 0 !== n || (e = -1 * t.wheelDeltaX / 6, + n = t.wheelDeltaY / 6), + t.deltaMode && 1 === t.deltaMode && (e *= 10, + n *= 10), + e != e && n != n && (e = 0, + n = t.wheelDelta), + t.shiftKey ? [-n, -e] : [e, n] + }(e); + if (!function(e, n, i) { + if (!b.isWebKit && l.querySelector("select:focus")) + return 1; + if (l.contains(e)) { + let t = e; + for (; t && t !== l; ) { + if (t.classList.contains(v.element.consuming)) + return 1; + var o = p(t); + if (i && o.overflowY.match(/(scroll|auto)/)) { + var r = t.scrollHeight - t.clientHeight; + if (0 < r && (0 < t.scrollTop && i < 0 || t.scrollTop < r && 0 < i)) + return 1 + } + if (n && o.overflowX.match(/(scroll|auto)/)) { + r = t.scrollWidth - t.clientWidth; + if (0 < r && (0 < t.scrollLeft && n < 0 || t.scrollLeft < r && 0 < n)) + return 1 + } + t = t.parentNode + } + } + }(e.target, n, i)) { + let t = !1; + a.settings.useBothWheelAxes ? a.scrollbarYActive && !a.scrollbarXActive ? (i ? l.scrollTop -= i * a.settings.wheelSpeed : l.scrollTop += n * a.settings.wheelSpeed, + t = !0) : a.scrollbarXActive && !a.scrollbarYActive && (n ? l.scrollLeft += n * a.settings.wheelSpeed : l.scrollLeft -= i * a.settings.wheelSpeed, + t = !0) : (l.scrollTop -= i * a.settings.wheelSpeed, + l.scrollLeft += n * a.settings.wheelSpeed), + w(a), + (t = t || function(t, e) { + var n = Math.floor(l.scrollTop) + , i = 0 === l.scrollTop + , n = n + l.offsetHeight === l.scrollHeight + , o = 0 === l.scrollLeft + , r = l.scrollLeft + l.offsetWidth === l.scrollWidth; + let s; + return !(s = Math.abs(e) > Math.abs(t) ? i || n : o || r) || !a.settings.wheelPropagation + }(n, i)) && !e.ctrlKey && (e.stopPropagation(), + e.preventDefault()) + } + } + void 0 !== window.onwheel ? a.event.bind(l, "wheel", t) : void 0 !== window.onmousewheel && a.event.bind(l, "mousewheel", t) + }, + touch: function(l) { + if (b.supportsTouch || b.supportsIePointer) { + const d = l.element; + let r = {} + , s = 0 + , a = {} + , e = null; + function c(t, e) { + d.scrollTop -= e, + d.scrollLeft -= t, + w(l) + } + function u(t) { + return t.targetTouches ? t.targetTouches[0] : t + } + function h(t) { + return (!t.pointerType || "pen" !== t.pointerType || 0 !== t.buttons) && (t.targetTouches && 1 === t.targetTouches.length || !(!t.pointerType || "mouse" === t.pointerType || t.pointerType === t.MSPOINTER_TYPE_MOUSE)) + } + function t(t) { + h(t) && (t = u(t), + r.pageX = t.pageX, + r.pageY = t.pageY, + s = (new Date).getTime(), + null !== e) && clearInterval(e) + } + function n(t) { + var e, n, i, o; + h(t) && (e = (i = { + pageX: (i = u(t)).pageX, + pageY: i.pageY + }).pageX - r.pageX, + n = i.pageY - r.pageY, + !function(e, n, i) { + if (d.contains(e)) { + let t = e; + for (; t && t !== d; ) { + if (t.classList.contains(v.element.consuming)) + return 1; + var o = p(t); + if (i && o.overflowY.match(/(scroll|auto)/)) { + var r = t.scrollHeight - t.clientHeight; + if (0 < r && (0 < t.scrollTop && i < 0 || t.scrollTop < r && 0 < i)) + return 1 + } + if (n && o.overflowX.match(/(scroll|auto)/)) { + r = t.scrollWidth - t.clientWidth; + if (0 < r && (0 < t.scrollLeft && n < 0 || t.scrollLeft < r && 0 < n)) + return 1 + } + t = t.parentNode + } + } + }(t.target, e, n)) && (c(e, n), + r = i, + 0 < (o = (i = (new Date).getTime()) - s) && (a.x = e / o, + a.y = n / o, + s = i), + function(t, e) { + var n = Math.floor(d.scrollTop) + , i = d.scrollLeft + , o = Math.abs(t) + , r = Math.abs(e); + if (o < r) { + if (e < 0 && n === l.contentHeight - l.containerHeight || 0 < e && 0 === n) + return 0 === window.scrollY && 0 < e && b.isChrome + } else if (r < o && (t < 0 && i === l.contentWidth - l.containerWidth || 0 < t && 0 === i)) + ;return 1 + }(e, n)) && t.preventDefault() + } + function i() { + l.settings.swipeEasing && (clearInterval(e), + e = setInterval(function() { + l.isInitialized || !a.x && !a.y || Math.abs(a.x) < .01 && Math.abs(a.y) < .01 ? clearInterval(e) : (c(30 * a.x, 30 * a.y), + a.x *= .8, + a.y *= .8) + }, 10)) + } + b.supportsTouch ? (l.event.bind(d, "touchstart", t), + l.event.bind(d, "touchmove", n), + l.event.bind(d, "touchend", i)) : b.supportsIePointer && (window.PointerEvent ? (l.event.bind(d, "pointerdown", t), + l.event.bind(d, "pointermove", n), + l.event.bind(d, "pointerup", i)) : window.MSPointerEvent && (l.event.bind(d, "MSPointerDown", t), + l.event.bind(d, "MSPointerMove", n), + l.event.bind(d, "MSPointerUp", i))) + } + } + }; + class C { + constructor(t) { + var e = 1 < arguments.length && void 0 !== arguments[1] ? arguments[1] : {}; + if (!(t = "string" == typeof t ? document.querySelector(t) : t) || !t.nodeName) + throw new Error("no element is specified to initialize PerfectScrollbar"); + (this.element = t).classList.add(v.main), + this.settings = { + handlers: ["click-rail", "drag-thumb", "keyboard", "wheel", "touch"], + maxScrollbarLength: null, + minScrollbarLength: null, + scrollingThreshold: 1e3, + scrollXMarginOffset: 0, + scrollYMarginOffset: 0, + suppressScrollX: !1, + suppressScrollY: !1, + swipeEasing: !0, + useBothWheelAxes: !1, + wheelPropagation: !0, + wheelSpeed: 1 + }; + for (const s in e) + this.settings[s] = e[s]; + this.containerWidth = null, + this.containerHeight = null, + this.contentWidth = null, + this.contentHeight = null; + var n = ()=>t.classList.add(v.state.focus) + , i = ()=>t.classList.remove(v.state.focus) + , o = (this.isRtl = "rtl" === p(t).direction, + !0 === this.isRtl && t.classList.add(v.rtl), + this.isNegativeScroll = (o = t.scrollLeft, + t.scrollLeft = -1, + r = t.scrollLeft < 0, + t.scrollLeft = o, + r), + this.negativeScrollAdjustment = this.isNegativeScroll ? t.scrollWidth - t.clientWidth : 0, + this.event = new d, + this.ownerDocument = t.ownerDocument || document, + this.scrollbarXRail = l(v.element.rail("x")), + t.appendChild(this.scrollbarXRail), + this.scrollbarX = l(v.element.thumb("x")), + this.scrollbarXRail.appendChild(this.scrollbarX), + this.scrollbarX.setAttribute("tabindex", 0), + this.event.bind(this.scrollbarX, "focus", n), + this.event.bind(this.scrollbarX, "blur", i), + this.scrollbarXActive = null, + this.scrollbarXWidth = null, + this.scrollbarXLeft = null, + p(this.scrollbarXRail)) + , r = (this.scrollbarXBottom = parseInt(o.bottom, 10), + isNaN(this.scrollbarXBottom) ? (this.isScrollbarXUsingBottom = !1, + this.scrollbarXTop = m(o.top)) : this.isScrollbarXUsingBottom = !0, + this.railBorderXWidth = m(o.borderLeftWidth) + m(o.borderRightWidth), + a(this.scrollbarXRail, { + display: "block" + }), + this.railXMarginWidth = m(o.marginLeft) + m(o.marginRight), + a(this.scrollbarXRail, { + display: "" + }), + this.railXWidth = null, + this.railXRatio = null, + this.scrollbarYRail = l(v.element.rail("y")), + t.appendChild(this.scrollbarYRail), + this.scrollbarY = l(v.element.thumb("y")), + this.scrollbarYRail.appendChild(this.scrollbarY), + this.scrollbarY.setAttribute("tabindex", 0), + this.event.bind(this.scrollbarY, "focus", n), + this.event.bind(this.scrollbarY, "blur", i), + this.scrollbarYActive = null, + this.scrollbarYHeight = null, + this.scrollbarYTop = null, + p(this.scrollbarYRail)); + this.scrollbarYRight = parseInt(r.right, 10), + isNaN(this.scrollbarYRight) ? (this.isScrollbarYUsingRight = !1, + this.scrollbarYLeft = m(r.left)) : this.isScrollbarYUsingRight = !0, + this.scrollbarYOuterWidth = this.isRtl ? m((o = p(o = this.scrollbarY)).width) + m(o.paddingLeft) + m(o.paddingRight) + m(o.borderLeftWidth) + m(o.borderRightWidth) : null, + this.railBorderYWidth = m(r.borderTopWidth) + m(r.borderBottomWidth), + a(this.scrollbarYRail, { + display: "block" + }), + this.railYMarginHeight = m(r.marginTop) + m(r.marginBottom), + a(this.scrollbarYRail, { + display: "" + }), + this.railYHeight = null, + this.railYRatio = null, + this.reach = { + x: t.scrollLeft <= 0 ? "start" : t.scrollLeft >= this.contentWidth - this.containerWidth ? "end" : null, + y: t.scrollTop <= 0 ? "start" : t.scrollTop >= this.contentHeight - this.containerHeight ? "end" : null + }, + this.isAlive = !0, + this.settings.handlers.forEach(t=>S[t](this)), + this.lastScrollTop = Math.floor(t.scrollTop), + this.lastScrollLeft = t.scrollLeft, + this.event.bind(this.element, "scroll", t=>this.onScroll(t)), + w(this) + } + update() { + this.isAlive && (this.negativeScrollAdjustment = this.isNegativeScroll ? this.element.scrollWidth - this.element.clientWidth : 0, + a(this.scrollbarXRail, { + display: "block" + }), + a(this.scrollbarYRail, { + display: "block" + }), + this.railXMarginWidth = m(p(this.scrollbarXRail).marginLeft) + m(p(this.scrollbarXRail).marginRight), + this.railYMarginHeight = m(p(this.scrollbarYRail).marginTop) + m(p(this.scrollbarYRail).marginBottom), + a(this.scrollbarXRail, { + display: "none" + }), + a(this.scrollbarYRail, { + display: "none" + }), + w(this), + g(this, "top", 0, !1, !0), + g(this, "left", 0, !1, !0), + a(this.scrollbarXRail, { + display: "" + }), + a(this.scrollbarYRail, { + display: "" + })) + } + onScroll(t) { + this.isAlive && (w(this), + g(this, "top", this.element.scrollTop - this.lastScrollTop), + g(this, "left", this.element.scrollLeft - this.lastScrollLeft), + this.lastScrollTop = Math.floor(this.element.scrollTop), + this.lastScrollLeft = this.element.scrollLeft) + } + destroy() { + this.isAlive && (this.event.unbindAll(), + s(this.scrollbarX), + s(this.scrollbarY), + s(this.scrollbarXRail), + s(this.scrollbarYRail), + this.removePsClasses(), + this.element = null, + this.scrollbarX = null, + this.scrollbarY = null, + this.scrollbarXRail = null, + this.scrollbarYRail = null, + this.isAlive = !1) + } + removePsClasses() { + this.element.className = this.element.className.split(" ").filter(t=>!t.match(/^ps([-_].+|)$/)).join(" ") + } + } + } + , function(t, e, n) { + "use strict"; + var i = n(3) + , o = n(1) + , r = n(69) + , n = n(2); + const s = "tooltip" + , a = [{ + name: "show" + }, { + name: "shown" + }, { + name: "hide" + }, { + name: "hidden" + }, { + name: "inserted" + }]; + class l extends r.a { + constructor(t, e) { + super(t, e), + this._init() + } + dispose() { + o.b.off(this._element, "show.bs.tooltip"), + o.b.off(this._element, "shown.bs.tooltip"), + o.b.off(this._element, "hide.bs.tooltip"), + o.b.off(this._element, "hidden.bs.tooltip"), + o.b.off(this._element, "inserted.bs.tooltip"), + super.dispose() + } + static get NAME() { + return s + } + _init() { + this._bindMdbEvents() + } + _bindMdbEvents() { + o.b.extend(this._element, a, s) + } + } + n.a.find('[data-mdb-toggle="tooltip"]').forEach(t=>{ + var e = l.getInstance(t); + e || new l(t) + } + ), + Object(i.i)(()=>{ + const t = Object(i.f)(); + if (t) { + const e = t.fn[s]; + t.fn[s] = l.jQueryInterface, + t.fn[s].Constructor = l, + t.fn[s].noConflict = ()=>(t.fn[s] = e, + l.jQueryInterface) + } + } + ), + e.a = l + } + , function(t, e, n) { + "use strict"; + var i, o, r, s, a, l, c, u = n(26), h = n(23), d = n(13), p = n(14), f = n(29), g = n(15), m = n(56), b = n(38), v = n(79), n = n(151), _ = d.Symbol, y = _ && _.prototype; + !h || !g(_) || "description"in y && void 0 === _().description || (i = {}, + n(d = function() { + var t = arguments.length < 1 || void 0 === arguments[0] ? void 0 : b(arguments[0]) + , e = m(y, this) ? new _(t) : void 0 === t ? _() : _(t); + return "" === t && (i[e] = !0), + e + } + , _), + (d.prototype = y).constructor = d, + o = "Symbol(description detection)" === String(_("description detection")), + r = p(y.valueOf), + s = p(y.toString), + a = /^Symbol\((.*)\)[^)]+$/, + l = p("".replace), + c = p("".slice), + v(y, "description", { + configurable: !0, + get: function() { + var t = r(this); + return f(i, t) ? "" : (t = s(t), + "" === (t = o ? c(t, 7, -1) : l(t, a, "$1")) ? void 0 : t) + } + }), + u({ + global: !0, + constructor: !0, + forced: !0 + }, { + Symbol: d + })) + } + , function(t, e, n) { + "use strict"; + var i = n(3) + , o = n(7) + , r = n(0) + , s = n(2) + , a = n(1); + const l = "animation" + , c = "mdb.animation"; + const u = { + animation: "string", + animationStart: "string", + animationShowOnLoad: "boolean", + onStart: "(null|function)", + onEnd: "(null|function)", + onHide: "(null|function)", + onShow: "(null|function)", + animationOnScroll: "(string)", + animationWindowHeight: "number", + animationOffset: "(number|string)", + animationDelay: "(number|string)", + animationDuration: "(number|string)", + animationReverse: "boolean", + animationInterval: "(number|string)", + animationRepeat: "(number|boolean)", + animationReset: "boolean" + } + , h = { + animation: "fade", + animationStart: "onClick", + animationShowOnLoad: !0, + onStart: null, + onEnd: null, + onHide: null, + onShow: null, + animationOnScroll: "once", + animationWindowHeight: 0, + animationOffset: 0, + animationDelay: 0, + animationDuration: 500, + animationReverse: !1, + animationInterval: 0, + animationRepeat: !1, + animationReset: !1 + }; + class d { + constructor(t, e) { + this._element = t, + this._animateElement = this._getAnimateElement(), + this._isFirstScroll = !0, + this._repeatAnimateOnScroll = !0, + this._options = this._getConfig(e), + this._element && o.a.setData(t, c, this) + } + static get NAME() { + return l + } + init() { + this._init() + } + startAnimation() { + this._startAnimation() + } + stopAnimation() { + this._clearAnimationClass() + } + changeAnimationType(t) { + this._options.animation = t + } + dispose() { + a.b.off(this._element, "mousedown"), + a.b.off(this._animateElement, "animationend"), + a.b.off(window, "scroll"), + a.b.off(this._element, "mouseover"), + o.a.removeData(this._element, c), + this._element = null, + this._animateElement = null, + this._isFirstScroll = null, + this._repeatAnimateOnScroll = null, + this._options = null + } + _init() { + switch (this._options.animationStart) { + case "onHover": + this._bindHoverEvents(); + break; + case "onLoad": + this._startAnimation(); + break; + case "onScroll": + this._bindScrollEvents(); + break; + case "onClick": + this._bindClickEvents() + } + this._bindTriggerOnEndCallback(), + this._options.animationReset && this._bindResetAnimationAfterFinish() + } + _getAnimateElement() { + var t = r.a.getDataAttribute(this._element, "animation-target"); + return t ? s.a.find(t)[0] : this._element + } + _getConfig(t) { + var e = r.a.getDataAttributes(this._animateElement); + return t = { + ...h, + ...e, + ...t + }, + Object(i.j)(l, t, u), + t + } + _animateOnScroll() { + var t = r.a.offset(this._animateElement).top + , e = this._animateElement.offsetHeight + , n = window.innerHeight + , n = t + this._options.animationOffset <= n && 0 <= t + this._options.animationOffset + e + , t = "visible" === this._animateElement.style.visibility; + switch (!0) { + case n && this._isFirstScroll: + this._isFirstScroll = !1, + this._startAnimation(); + break; + case !n && this._isFirstScroll: + this._isFirstScroll = !1, + this._hideAnimateElement(); + break; + case n && !t && this._repeatAnimateOnScroll: + "repeat" !== this._options.animationOnScroll && (this._repeatAnimateOnScroll = !1), + this._callback(this._options.onShow), + this._showAnimateElement(), + this._startAnimation(); + break; + case !n && t && this._repeatAnimateOnScroll: + this._hideAnimateElement(), + this._clearAnimationClass(), + this._callback(this._options.onHide) + } + } + _addAnimatedClass() { + r.a.addClass(this._animateElement, "animation"), + r.a.addClass(this._animateElement, this._options.animation) + } + _clearAnimationClass() { + this._animateElement.classList.remove(this._options.animation, "animation") + } + _removeInvisibleClass() { + r.a.removeClass(this._animateElement, "invisible") + } + _startAnimation() { + this._callback(this._options.onStart), + this._removeInvisibleClass(), + this._addAnimatedClass(), + this._options.animationRepeat && !this._options.animationInterval && this._setAnimationRepeat(), + this._options.animationReverse && this._setAnimationReverse(), + this._options.animationDelay && this._setAnimationDelay(), + this._options.animationDuration && this._setAnimationDuration(), + this._options.animationInterval && this._setAnimationInterval() + } + _setAnimationReverse() { + r.a.style(this._animateElement, { + animationIterationCount: !0 === this._options.animationRepeat ? "infinite" : "2", + animationDirection: "alternate" + }) + } + _setAnimationDuration() { + r.a.style(this._animateElement, { + animationDuration: "".concat(this._options.animationDuration, "ms") + }) + } + _setAnimationDelay() { + r.a.style(this._animateElement, { + animationDelay: "".concat(this._options.animationDelay, "ms") + }) + } + _setAnimationRepeat() { + r.a.style(this._animateElement, { + animationIterationCount: !0 === this._options.animationRepeat ? "infinite" : this._options.animationRepeat + }) + } + _setAnimationInterval() { + a.b.on(this._animateElement, "animationend", ()=>{ + this._clearAnimationClass(), + setTimeout(()=>{ + this._addAnimatedClass() + } + , this._options.animationInterval) + } + ) + } + _hideAnimateElement() { + r.a.style(this._animateElement, { + visibility: "hidden" + }) + } + _showAnimateElement() { + r.a.style(this._animateElement, { + visibility: "visible" + }) + } + _bindResetAnimationAfterFinish() { + a.b.on(this._animateElement, "animationend", ()=>{ + this._clearAnimationClass() + } + ) + } + _bindTriggerOnEndCallback() { + a.b.on(this._animateElement, "animationend", ()=>{ + this._callback(this._options.onEnd) + } + ) + } + _bindScrollEvents() { + this._options.animationShowOnLoad || this._animateOnScroll(), + a.b.on(window, "scroll", ()=>{ + this._animateOnScroll() + } + ) + } + _bindClickEvents() { + a.b.on(this._element, "mousedown", ()=>{ + this._startAnimation() + } + ) + } + _bindHoverEvents() { + a.b.one(this._element, "mouseover", ()=>{ + this._startAnimation() + } + ), + a.b.one(this._animateElement, "animationend", ()=>{ + setTimeout(()=>{ + this._bindHoverEvents() + } + , 100) + } + ) + } + _callback(t) { + t instanceof Function && t() + } + static autoInit(t) { + t._init() + } + static jQueryInterface(t) { + new d(this[0],t).init() + } + static getInstance(t) { + return o.a.getData(t, c) + } + static getOrCreateInstance(t) { + var e = 1 < arguments.length && void 0 !== arguments[1] ? arguments[1] : {}; + return this.getInstance(t) || new this(t,"object" == typeof e ? e : null) + } + } + s.a.find('[data-mdb-toggle="animation"]').forEach(t=>{ + d.autoInit(new d(t)) + } + ), + Object(i.i)(()=>{ + const t = Object(i.f)(); + if (t) { + const e = t.fn[l]; + t.fn[l] = d.jQueryInterface, + t.fn[l].Constructor = d, + t.fn[l].noConflict = ()=>(t.fn[l] = e, + d.jQueryInterface) + } + } + ), + e.a = d + } + , function(t, e, n) { + "use strict"; + var i = n(6) + , o = n(4) + , n = n(45); + const r = "mousedown.bs.".concat("backdrop") + , s = { + className: "modal-backdrop", + clickCallback: null, + isAnimated: !1, + isVisible: !0, + rootElement: "body" + } + , a = { + className: "string", + clickCallback: "(function|null)", + isAnimated: "boolean", + isVisible: "boolean", + rootElement: "(element|string)" + }; + class l extends n.a { + constructor(t) { + super(), + this._config = this._getConfig(t), + this._isAppended = !1, + this._element = null + } + static get Default() { + return s + } + static get DefaultType() { + return a + } + static get NAME() { + return "backdrop" + } + show(t) { + var e; + this._config.isVisible ? (this._append(), + e = this._getElement(), + this._config.isAnimated && Object(o.p)(e), + e.classList.add("show"), + this._emulateAnimation(()=>{ + Object(o.b)(t) + } + )) : Object(o.b)(t) + } + hide(t) { + this._config.isVisible ? (this._getElement().classList.remove("show"), + this._emulateAnimation(()=>{ + this.dispose(), + Object(o.b)(t) + } + )) : Object(o.b)(t) + } + dispose() { + this._isAppended && (i.a.off(this._element, r), + this._element.remove(), + this._isAppended = !1) + } + _getElement() { + var t; + return this._element || ((t = document.createElement("div")).className = this._config.className, + this._config.isAnimated && t.classList.add("fade"), + this._element = t), + this._element + } + _configAfterMerge(t) { + return t.rootElement = Object(o.e)(t.rootElement), + t + } + _append() { + var t; + this._isAppended || (t = this._getElement(), + this._config.rootElement.append(t), + i.a.on(t, r, ()=>{ + Object(o.b)(this._config.clickCallback) + } + ), + this._isAppended = !0) + } + _emulateAnimation(t) { + Object(o.c)(t, this._getElement(), this._config.isAnimated) + } + } + e.a = l + } + , function(t, e, n) { + "use strict"; + var i = n(6) + , o = n(8) + , n = n(45); + const r = ".".concat("bs.focustrap") + , s = "focusin".concat(r) + , a = "keydown.tab".concat(r) + , l = { + autofocus: !0, + trapElement: null + } + , c = { + autofocus: "boolean", + trapElement: "element" + }; + class u extends n.a { + constructor(t) { + super(), + this._config = this._getConfig(t), + this._isActive = !1, + this._lastTabNavDirection = null + } + static get Default() { + return l + } + static get DefaultType() { + return c + } + static get NAME() { + return "focustrap" + } + activate() { + this._isActive || (this._config.autofocus && this._config.trapElement.focus(), + i.a.off(document, r), + i.a.on(document, s, t=>this._handleFocusin(t)), + i.a.on(document, a, t=>this._handleKeydown(t)), + this._isActive = !0) + } + deactivate() { + this._isActive && (this._isActive = !1, + i.a.off(document, r)) + } + _handleFocusin(t) { + var e = this._config["trapElement"]; + t.target === document || t.target === e || e.contains(t.target) || (0 === (t = o.a.focusableChildren(e)).length ? e : "backward" === this._lastTabNavDirection ? t[t.length - 1] : t[0]).focus() + } + _handleKeydown(t) { + "Tab" === t.key && (this._lastTabNavDirection = t.shiftKey ? "backward" : "forward") + } + } + e.a = u + } + , function(t, e, n) { + "use strict"; + n.d(e, "a", function() { + return h + }); + var e = n(44) + , i = n(62) + , o = n(63) + , r = n(61) + , s = n(60) + , a = n(99) + , l = n(100) + , c = n(101) + , u = n(97) + , n = n(98) + , i = [i.a, o.a, r.a, s.a, a.a, l.a, c.a, u.a, n.a] + , h = Object(e.b)({ + defaultModifiers: i + }) + } + , function(t, e, n) { + "use strict"; + var i = {}.propertyIsEnumerable + , o = Object.getOwnPropertyDescriptor + , r = o && !i.call({ + 1: 2 + }, 1); + e.f = r ? function(t) { + t = o(this, t); + return !!t && t.enumerable + } + : i + } + , function(t, e, n) { + "use strict"; + var i = "object" == typeof document && document.all; + t.exports = { + all: i, + IS_HTMLDDA: void 0 === i && void 0 !== i + } + } + , function(t, e, n) { + "use strict"; + var i = n(48) + , o = n(15) + , r = n(56) + , n = n(145) + , s = Object; + t.exports = n ? function(t) { + return "symbol" == typeof t + } + : function(t) { + var e = i("Symbol"); + return o(e) && r(e.prototype, s(t)) + } + } + , function(t, e, n) { + "use strict"; + n = n(146); + t.exports = n && !Symbol.sham && "symbol" == typeof Symbol.iterator + } + , function(t, e, n) { + "use strict"; + var i = n(90) + , o = n(16) + , r = n(13).String; + t.exports = !!Object.getOwnPropertySymbols && !o(function() { + var t = Symbol("symbol detection"); + return !r(t) || !(Object(t)instanceof Symbol) || !Symbol.sham && i && i < 41 + }) + } + , function(t, e, n) { + "use strict"; + var n = n(14) + , i = 0 + , o = Math.random() + , r = n(1..toString); + t.exports = function(t) { + return "Symbol(" + (void 0 === t ? "" : t) + ")_" + r(++i + o, 36) + } + } + , function(t, e, n) { + "use strict"; + var i = n(23) + , o = n(16) + , r = n(91); + t.exports = !i && !o(function() { + return 7 !== Object.defineProperty(r("div"), "a", { + get: function() { + return 7 + } + }).a + }) + } + , function(t, e, n) { + "use strict"; + var i = n(23) + , n = n(16); + t.exports = i && n(function() { + return 42 !== Object.defineProperty(function() {}, "prototype", { + value: 42, + writable: !1 + }).prototype + }) + } + , function(t, e, n) { + "use strict"; + var i = n(14) + , o = n(16) + , r = n(15) + , s = n(29) + , a = n(23) + , l = n(117).CONFIGURABLE + , c = n(118) + , n = n(46) + , u = n.enforce + , h = n.get + , d = String + , p = Object.defineProperty + , f = i("".slice) + , g = i("".replace) + , m = i([].join) + , b = a && !o(function() { + return 8 !== p(function() {}, "length", { + value: 8 + }).length + }) + , v = String(String).split("String") + , n = t.exports = function(t, e, n) { + "Symbol(" === f(d(e), 0, 7) && (e = "[" + g(d(e), /^Symbol\(([^)]*)\)/, "$1") + "]"), + n && n.getter && (e = "get " + e), + n && n.setter && (e = "set " + e), + (!s(t, "name") || l && t.name !== e) && (a ? p(t, "name", { + value: e, + configurable: !0 + }) : t.name = e), + b && n && s(n, "arity") && t.length !== n.arity && p(t, "length", { + value: n.arity + }); + try { + n && s(n, "constructor") && n.constructor ? a && p(t, "prototype", { + writable: !1 + }) : t.prototype && (t.prototype = void 0) + } catch (t) {} + n = u(t); + return s(n, "source") || (n.source = m(v, "string" == typeof e ? e : "")), + t + } + ; + Function.prototype.toString = n(function() { + return r(this) && h(this).source || c(this) + }, "toString") + } + , function(t, e, n) { + "use strict"; + var l = n(29) + , c = n(210) + , u = n(111) + , h = n(40); + t.exports = function(t, e, n) { + for (var i = c(e), o = h.f, r = u.f, s = 0; s < i.length; s++) { + var a = i[s]; + l(t, a) || n && l(n, a) || o(t, a, r(e, a)) + } + } + } + , function(t, e, n) { + "use strict"; + var i = n(153) + , o = n(121).concat("length", "prototype"); + e.f = Object.getOwnPropertyNames || function(t) { + return i(t, o) + } + } + , function(t, e, n) { + "use strict"; + var i = n(14) + , s = n(29) + , a = n(77) + , l = n(154).indexOf + , c = n(120) + , u = i([].push); + t.exports = function(t, e) { + var n, i = a(t), o = 0, r = []; + for (n in i) + !s(c, n) && s(i, n) && u(r, n); + for (; e.length > o; ) + !s(i, n = e[o++]) || ~l(r, n) || u(r, n); + return r + } + } + , function(t, e, n) { + "use strict"; + function i(a) { + return function(t, e, n) { + var i, o = l(t), r = u(o), s = c(n, r); + if (a && e != e) { + for (; s < r; ) + if ((i = o[s++]) != i) + return !0 + } else + for (; s < r; s++) + if ((a || s in o) && o[s] === e) + return a || s || 0; + return !a && -1 + } + } + var l = n(77) + , c = n(155) + , u = n(58); + t.exports = { + includes: i(!0), + indexOf: i(!1) + } + } + , function(t, e, n) { + "use strict"; + var i = n(92) + , o = Math.max + , r = Math.min; + t.exports = function(t, e) { + t = i(t); + return t < 0 ? o(t + e, 0) : r(t, e) + } + } + , function(t, e, n) { + "use strict"; + var i = n(92) + , o = Math.min; + t.exports = function(t) { + return 0 < t ? o(i(t), 9007199254740991) : 0 + } + } + , function(t, e, n) { + "use strict"; + e.f = Object.getOwnPropertySymbols + } + , function(t, e, n) { + "use strict"; + var i = n(20) + , o = n(80) + , n = n(40).f + , r = i("unscopables") + , s = Array.prototype; + void 0 === s[r] && n(s, r, { + configurable: !0, + value: o(null) + }), + t.exports = function(t) { + s[r][t] = !0 + } + } + , function(t, e, n) { + "use strict"; + var i = n(153) + , o = n(121); + t.exports = Object.keys || function(t) { + return i(t, o) + } + } + , function(t, e, n) { + "use strict"; + n = n(48); + t.exports = n("document", "documentElement") + } + , function(t, e, n) { + "use strict"; + function g() { + return this + } + var m = n(26) + , b = n(22) + , v = n(43) + , i = n(117) + , _ = n(15) + , y = n(162) + , w = n(164) + , O = n(123) + , x = n(82) + , S = n(57) + , C = n(41) + , o = n(20) + , E = n(81) + , n = n(163) + , k = i.PROPER + , A = i.CONFIGURABLE + , j = n.IteratorPrototype + , T = n.BUGGY_SAFARI_ITERATORS + , L = o("iterator") + , P = "values"; + t.exports = function(t, e, n, i, o, r, s) { + y(n, e, i); + function a(t) { + if (t === o && p) + return p; + if (!T && t && t in h) + return h[t]; + switch (t) { + case "keys": + case P: + case "entries": + return function() { + return new n(this,t) + } + } + return function() { + return new n(this) + } + } + var l, c, i = e + " Iterator", u = !1, h = t.prototype, d = h[L] || h["@@iterator"] || o && h[o], p = !T && d || a(o), f = "Array" === e && h.entries || d; + if (f && (f = w(f.call(new t))) !== Object.prototype && f.next && (v || w(f) === j || (O ? O(f, j) : _(f[L]) || C(f, L, g)), + x(f, i, !0, !0), + v) && (E[i] = g), + k && o === P && d && d.name !== P && (!v && A ? S(h, "name", P) : (u = !0, + p = function() { + return b(d, this) + } + )), + o) + if (l = { + values: a(P), + keys: r ? p : a("keys"), + entries: a("entries") + }, + s) + for (c in l) + !T && !u && c in h || C(h, c, l[c]); + else + m({ + target: e, + proto: !0, + forced: T || u + }, l); + return v && !s || h[L] === p || C(h, L, p, { + name: o + }), + E[e] = p, + l + } + } + , function(t, e, n) { + "use strict"; + function o() { + return this + } + var r = n(163).IteratorPrototype + , s = n(80) + , a = n(76) + , l = n(82) + , c = n(81); + t.exports = function(t, e, n, i) { + e += " Iterator"; + return t.prototype = s(r, { + next: a(+!i, n) + }), + l(t, e, !1, !0), + c[e] = o, + t + } + } + , function(t, e, n) { + "use strict"; + var i, o, r = n(16), s = n(15), a = n(35), l = n(80), c = n(164), u = n(41), h = n(20), n = n(43), d = h("iterator"), h = !1; + [].keys && ("next"in (o = [].keys()) ? (c = c(c(o))) !== Object.prototype && (i = c) : h = !0), + !a(i) || r(function() { + var t = {}; + return i[d].call(t) !== t + }) ? i = {} : n && (i = l(i)), + s(i[d]) || u(i, d, function() { + return this + }), + t.exports = { + IteratorPrototype: i, + BUGGY_SAFARI_ITERATORS: h + } + } + , function(t, e, n) { + "use strict"; + var i = n(29) + , o = n(15) + , r = n(50) + , s = n(119) + , n = n(214) + , a = s("IE_PROTO") + , l = Object + , c = l.prototype; + t.exports = n ? l.getPrototypeOf : function(t) { + var e, t = r(t); + return i(t, a) ? t[a] : (e = t.constructor, + o(e) && t instanceof e ? e.prototype : t instanceof l ? c : null) + } + } + , function(t, e, n) { + "use strict"; + t.exports = function(t, e) { + return { + value: t, + done: e + } + } + } + , function(t, e, n) { + "use strict"; + var i = n(16) + , o = n(13).RegExp + , n = i(function() { + var t = o("a", "y"); + return t.lastIndex = 2, + null !== t.exec("abcd") + }) + , r = n || i(function() { + return !o("a", "y").sticky + }) + , i = n || i(function() { + var t = o("^r", "gy"); + return t.lastIndex = 2, + null !== t.exec("str") + }); + t.exports = { + BROKEN_CARET: i, + MISSED_STICKY: r, + UNSUPPORTED_Y: n + } + } + , function(t, e, n) { + "use strict"; + var i = n(16) + , o = n(13).RegExp; + t.exports = i(function() { + var t = o(".", "s"); + return !(t.dotAll && t.exec("\n") && "s" === t.flags) + }) + } + , function(t, e, n) { + "use strict"; + var i = n(16) + , o = n(13).RegExp; + t.exports = i(function() { + var t = o("(?
b)", "g"); + return "b" !== t.exec("b").groups.a || "bc" !== "b".replace(t, "$c") + }) + } + , function(t, e, n) { + "use strict"; + var n = n(89) + , i = Function.prototype + , o = i.apply + , r = i.call; + t.exports = "object" == typeof Reflect && Reflect.apply || (n ? r.bind(o) : function() { + return r.apply(o, arguments) + } + ) + } + , function(t, e, n) { + "use strict"; + var i = n(55) + , o = n(14); + t.exports = function(t) { + if ("Function" === i(t)) + return o(t) + } + } + , function(t, e, n) { + "use strict"; + var i = n(48) + , o = n(79) + , r = n(20) + , s = n(23) + , a = r("species"); + t.exports = function(t) { + t = i(t); + s && t && !t[a] && o(t, a, { + configurable: !0, + get: function() { + return this + } + }) + } + } + , function(t, e, n) { + "use strict"; + t.exports = "\t\n\v\f\r                 \u2028\u2029\ufeff" + } + , function(t, e, n) { + "use strict"; + function v(t, e) { + var n = t.length + , i = y(n / 2); + if (n < 8) { + for (var o, r, s = t, a = e, l = s.length, c = 1; c < l; ) { + for (o = s[r = c]; r && 0 < a(s[r - 1], o); ) + s[r] = s[--r]; + r !== c++ && (s[r] = o) + } + return s + } + for (var u = t, h = v(_(t, 0, i), e), d = v(_(t, i), e), p = e, f = h.length, g = d.length, m = 0, b = 0; m < f || b < g; ) + u[m + b] = m < f && b < g ? p(h[m], d[b]) <= 0 ? h[m++] : d[b++] : m < f ? h[m++] : d[b++]; + return u + } + var _ = n(174) + , y = Math.floor; + t.exports = v + } + , function(t, e, n) { + "use strict"; + var l = n(155) + , c = n(58) + , u = n(175) + , h = Array + , d = Math.max; + t.exports = function(t, e, n) { + for (var i = c(t), o = l(e, i), r = l(void 0 === n ? i : n, i), s = h(d(r - o, 0)), a = 0; o < r; o++, + a++) + u(s, a, t[o]); + return s.length = a, + s + } + } + , function(t, e, n) { + "use strict"; + var i = n(113) + , o = n(40) + , r = n(76); + t.exports = function(t, e, n) { + e = i(e); + e in t ? o.f(t, e, r(0, n)) : t[e] = n + } + } + , function(t, e, n) { + "use strict"; + var i = n(16); + t.exports = function(t, e) { + var n = [][t]; + return !!n && i(function() { + n.call(null, e || function() { + return 1 + } + , 1) + }) + } + } + , function(t, e, n) { + "use strict"; + function i() {} + function o(t) { + if (!l(t)) + return !1; + try { + return p(i, d, t), + !0 + } catch (t) { + return !1 + } + } + function r(t) { + if (!l(t)) + return !1; + switch (c(t)) { + case "AsyncFunction": + case "GeneratorFunction": + case "AsyncGeneratorFunction": + return !1 + } + try { + return m || !!g(f, h(t)) + } catch (t) { + return !0 + } + } + var s = n(14) + , a = n(16) + , l = n(15) + , c = n(93) + , u = n(48) + , h = n(118) + , d = [] + , p = u("Reflect", "construct") + , f = /^\s*(?:class|function)\b/ + , g = s(f.exec) + , m = !f.exec(i); + r.sham = !0, + t.exports = !p || a(function() { + var t; + return o(o.call) || !o(Object) || !o(function() { + t = !0 + }) || t + }) ? r : o + } + , function(t, e, n) { + "use strict"; + function i(t) { + return function() { + j(t) + } + } + function o(t) { + j(t.data) + } + function r(t) { + l.postMessage(C(t), s.protocol + "//" + s.host) + } + var s, a, l = n(13), c = n(169), u = n(59), h = n(15), d = n(29), p = n(16), f = n(160), g = n(240), m = n(91), b = n(128), v = n(179), n = n(83), _ = l.setImmediate, y = l.clearImmediate, w = l.process, O = l.Dispatch, x = l.Function, S = l.MessageChannel, C = l.String, E = 0, k = {}, A = "onreadystatechange", j = (p(function() { + s = l.location + }), + function(t) { + var e; + d(k, t) && (e = k[t], + delete k[t], + e()) + } + ); + _ && y || (_ = function(t) { + b(arguments.length, 1); + var e = h(t) ? t : x(t) + , n = g(arguments, 1); + return k[++E] = function() { + c(e, void 0, n) + } + , + a(E), + E + } + , + y = function(t) { + delete k[t] + } + , + n ? a = function(t) { + w.nextTick(i(t)) + } + : O && O.now ? a = function(t) { + O.now(i(t)) + } + : S && !v ? (v = (n = new S).port2, + n.port1.onmessage = o, + a = u(v.postMessage, v)) : l.addEventListener && h(l.postMessage) && !l.importScripts && s && "file:" !== s.protocol && !p(r) ? (a = r, + l.addEventListener("message", o, !1)) : a = A in m("script") ? function(t) { + f.appendChild(m("script"))[A] = function() { + f.removeChild(this), + j(t) + } + } + : function(t) { + setTimeout(i(t), 0) + } + ), + t.exports = { + set: _, + clear: y + } + } + , function(t, e, n) { + "use strict"; + n = n(49); + t.exports = /(?:ipad|iphone|ipod).*applewebkit/i.test(n) + } + , function(t, e, n) { + "use strict"; + function i() { + this.head = null, + this.tail = null + } + i.prototype = { + add: function(t) { + var t = { + item: t, + next: null + } + , e = this.tail; + e ? e.next = t : this.head = t, + this.tail = t + }, + get: function() { + var t = this.head; + if (t) + return null === (this.head = t.next) && (this.tail = null), + t.item + } + }, + t.exports = i + } + , function(t, e, n) { + "use strict"; + t.exports = "object" == typeof Deno && Deno && "object" == typeof Deno.version + } + , function(t, e, n) { + "use strict"; + function b(t, e) { + this.stopped = t, + this.result = e + } + var v = n(59) + , _ = n(22) + , y = n(30) + , w = n(78) + , O = n(183) + , x = n(58) + , S = n(56) + , C = n(130) + , E = n(96) + , k = n(184) + , A = TypeError + , j = b.prototype; + t.exports = function(t, e, n) { + function i(t) { + return r && k(r, "normal", t), + new b(!0,t) + } + function o(t) { + return d ? (y(t), + g ? m(t[0], t[1], i) : m(t[0], t[1])) : g ? m(t, i) : m(t) + } + var r, s, a, l, c, u, h = n && n.that, d = !(!n || !n.AS_ENTRIES), p = !(!n || !n.IS_RECORD), f = !(!n || !n.IS_ITERATOR), g = !(!n || !n.INTERRUPTED), m = v(e, h); + if (p) + r = t.iterator; + else if (f) + r = t; + else { + if (!(n = E(t))) + throw A(w(t) + " is not iterable"); + if (O(n)) { + for (s = 0, + a = x(t); s < a; s++) + if ((l = o(t[s])) && S(j, l)) + return l; + return new b(!1) + } + r = C(t, n) + } + for (c = (p ? t : r).next; !(u = _(c, r)).done; ) { + try { + l = o(u.value) + } catch (t) { + k(r, "throw", t) + } + if ("object" == typeof l && l && S(j, l)) + return l + } + return new b(!1) + } + } + , function(t, e, n) { + "use strict"; + var i = n(20) + , o = n(81) + , r = i("iterator") + , s = Array.prototype; + t.exports = function(t) { + return void 0 !== t && (o.Array === t || s[r] === t) + } + } + , function(t, e, n) { + "use strict"; + var r = n(22) + , s = n(30) + , a = n(88); + t.exports = function(t, e, n) { + var i, o; + s(t); + try { + if (!(i = a(t, "return"))) { + if ("throw" === e) + throw n; + return n + } + i = r(i, t) + } catch (t) { + o = !0, + i = t + } + if ("throw" === e) + throw n; + if (o) + throw i; + return s(i), + n + } + } + , function(t, e, n) { + "use strict"; + var i = n(84) + , o = n(247) + , n = n(85).CONSTRUCTOR; + t.exports = n || !o(function(t) { + i.all(t).then(void 0, function() {}) + }) + } + , function(t, e, n) { + "use strict"; + var i = n(16) + , o = n(20) + , r = n(23) + , s = n(43) + , a = o("iterator"); + t.exports = !i(function() { + var t = new URL("b?a=1&b=2&c=3","http://a") + , n = t.searchParams + , e = new URLSearchParams("a=1&a=2&b=3") + , i = ""; + return t.pathname = "c%20d", + n.forEach(function(t, e) { + n.delete("b"), + i += e + t + }), + e.delete("a", 2), + e.delete("b", void 0), + s && (!t.toJSON || !e.has("a", 1) || e.has("a", 2) || !e.has("a", void 0) || e.has("b")) || !n.size && (s || !r) || !n.sort || "http://a/c%20d?a=1&c=3" !== t.href || "3" !== n.get("c") || "a=1" !== String(new URLSearchParams("?a=1")) || !n[a] || "a" !== new URL("https://a@b").username || "b" !== new URLSearchParams(new URLSearchParams("a=b")).get("a") || "xn--e1aybc" !== new URL("http://тест").host || "#%D0%B1" !== new URL("http://a#б").hash || "a1c3" !== i || "x" !== new URL("http://x",void 0).host + }) + } + , function(D, N, t) { + "use strict"; + t(11); + function e(t) { + var e; + return p ? (e = Z(u, t)) && e.value : u[t] + } + function H(e) { + try { + return nt(e) + } catch (t) { + return e + } + } + function o(t) { + var e, n = R(t, ut, " "), i = 4; + try { + return nt(n) + } catch (t) { + for (; i; ) + n = R(n, (e = i--, + ht[e - 1] || (ht[e - 1] = tt("((?:%[\\da-f]{2}){" + e + "})", "gi"))), H); + return n + } + } + function B(t) { + return pt[t] + } + function r(t) { + return R(it(t), dt, B) + } + function n(t) { + this.entries = [], + this.url = null, + void 0 !== t && (_(t) ? this.parseObject(t) : this.parseQuery("string" == typeof t ? "?" === ot(t, 0) ? ct(t, 1) : t : y(t))) + } + function i() { + b(this, I); + var t = k(this, new n(0 < arguments.length ? arguments[0] : void 0)); + p || (this.size = t.entries.length) + } + var s, a, l, c = t(26), u = t(13), h = t(22), d = t(14), p = t(23), f = t(186), g = t(41), W = t(79), Y = t(260), F = t(82), X = t(162), m = t(46), b = t(127), v = t(15), z = t(29), U = t(59), q = t(93), $ = t(30), _ = t(35), y = t(38), V = t(80), w = t(76), O = t(130), K = t(96), x = t(128), S = t(20), G = t(173), t = S("iterator"), C = "URLSearchParams", E = C + "Iterator", k = m.set, A = m.getterFor(C), Q = m.getterFor(E), Z = Object.getOwnPropertyDescriptor, J = e("fetch"), j = e("Request"), T = e("Headers"), L = j && j.prototype, S = T && T.prototype, tt = u.RegExp, et = u.TypeError, nt = u.decodeURIComponent, it = u.encodeURIComponent, ot = d("".charAt), rt = d([].join), P = d([].push), R = d("".replace), st = d([].shift), at = d([].splice), lt = d("".split), ct = d("".slice), ut = /\+/g, ht = Array(4), dt = /[!'()~]|%20/g, pt = { + "!": "%21", + "'": "%27", + "(": "%28", + ")": "%29", + "~": "%7E", + "%20": "+" + }, M = X(function(t, e) { + k(this, { + type: E, + iterator: O(A(t).entries), + kind: e + }) + }, "Iterator", function() { + var t = Q(this) + , e = t.kind + , t = t.iterator.next() + , n = t.value; + return t.done || (t.value = "keys" === e ? n.key : "values" === e ? n.value : [n.key, n.value]), + t + }, !0), I = (n.prototype = { + type: C, + bindURL: function(t) { + this.url = t, + this.update() + }, + parseObject: function(t) { + var e, n, i, o, r, s, a = K(t); + if (a) + for (n = (e = O(t, a)).next; !(i = h(n, e)).done; ) { + if (o = (i = O($(i.value))).next, + (r = h(o, i)).done || (s = h(o, i)).done || !h(o, i).done) + throw et("Expected sequence with length 2"); + P(this.entries, { + key: y(r.value), + value: y(s.value) + }) + } + else + for (var l in t) + z(t, l) && P(this.entries, { + key: l, + value: y(t[l]) + }) + }, + parseQuery: function(t) { + if (t) + for (var e, n = lt(t, "&"), i = 0; i < n.length; ) + (e = n[i++]).length && (e = lt(e, "="), + P(this.entries, { + key: o(st(e)), + value: o(rt(e, "=")) + })) + }, + serialize: function() { + for (var t, e = this.entries, n = [], i = 0; i < e.length; ) + t = e[i++], + P(n, r(t.key) + "=" + r(t.value)); + return rt(n, "&") + }, + update: function() { + this.entries.length = 0, + this.parseQuery(this.url.query) + }, + updateURL: function() { + this.url && this.url.update() + } + }, + i.prototype); + Y(I, { + append: function(t, e) { + var n = A(this); + x(arguments.length, 2), + P(n.entries, { + key: y(t), + value: y(e) + }), + p || this.length++, + n.updateURL() + }, + delete: function(t) { + for (var e = A(this), n = x(arguments.length, 1), i = e.entries, o = y(t), t = n < 2 ? void 0 : arguments[1], r = void 0 === t ? t : y(t), s = 0; s < i.length; ) { + var a = i[s]; + if (a.key !== o || void 0 !== r && a.value !== r) + s++; + else if (at(i, s, 1), + void 0 !== r) + break + } + p || (this.size = i.length), + e.updateURL() + }, + get: function(t) { + for (var e = A(this).entries, n = (x(arguments.length, 1), + y(t)), i = 0; i < e.length; i++) + if (e[i].key === n) + return e[i].value; + return null + }, + getAll: function(t) { + for (var e = A(this).entries, n = (x(arguments.length, 1), + y(t)), i = [], o = 0; o < e.length; o++) + e[o].key === n && P(i, e[o].value); + return i + }, + has: function(t) { + for (var e = A(this).entries, n = x(arguments.length, 1), i = y(t), t = n < 2 ? void 0 : arguments[1], o = void 0 === t ? t : y(t), r = 0; r < e.length; ) { + var s = e[r++]; + if (s.key === i && (void 0 === o || s.value === o)) + return !0 + } + return !1 + }, + set: function(t, e) { + for (var n, i = A(this), o = (x(arguments.length, 1), + i.entries), r = !1, s = y(t), a = y(e), l = 0; l < o.length; l++) + (n = o[l]).key === s && (r ? at(o, l--, 1) : (r = !0, + n.value = a)); + r || P(o, { + key: s, + value: a + }), + p || (this.size = o.length), + i.updateURL() + }, + sort: function() { + var t = A(this); + G(t.entries, function(t, e) { + return t.key > e.key ? 1 : -1 + }), + t.updateURL() + }, + forEach: function(t) { + for (var e, n = A(this).entries, i = U(t, 1 < arguments.length ? arguments[1] : void 0), o = 0; o < n.length; ) + i((e = n[o++]).value, e.key, this) + }, + keys: function() { + return new M(this,"keys") + }, + values: function() { + return new M(this,"values") + }, + entries: function() { + return new M(this,"entries") + } + }, { + enumerable: !0 + }), + g(I, t, I.entries, { + name: "entries" + }), + g(I, "toString", function() { + return A(this).serialize() + }, { + enumerable: !0 + }), + p && W(I, "size", { + get: function() { + return A(this).entries.length + }, + configurable: !0, + enumerable: !0 + }), + F(i, C), + c({ + global: !0, + constructor: !0, + forced: !f + }, { + URLSearchParams: i + }), + !f && v(T) && (s = d(S.has), + a = d(S.set), + l = function(t) { + if (_(t)) { + var e, n = t.body; + if (q(n) === C) + return e = t.headers ? new T(t.headers) : new T, + s(e, "content-type") || a(e, "content-type", "application/x-www-form-urlencoded;charset=UTF-8"), + V(t, { + body: w(0, y(n)), + headers: w(0, e) + }) + } + return t + } + , + v(J) && c({ + global: !0, + enumerable: !0, + dontCallGetSet: !0, + forced: !0 + }, { + fetch: function(t) { + return J(t, 1 < arguments.length ? l(arguments[1]) : {}) + } + }), + v(j)) && ((L.constructor = m = function(t) { + return b(this, L), + new j(t,1 < arguments.length ? l(arguments[1]) : {}) + } + ).prototype = L, + c({ + global: !0, + constructor: !0, + dontCallGetSet: !0, + forced: !0 + }, { + Request: m + })), + D.exports = { + URLSearchParams: i, + getState: A + } + } + , function(t, e, n) { + "use strict"; + n(11), + n(12), + n(253), + n(261), + n(199), + n(28), + n(203), + n(17); + var i = n(135) + , o = n(3) + , r = n(132) + , s = n(9) + , l = n(1); + const a = { + threshold: 10, + direction: "all" + }; + var c = class { + constructor(t, e) { + this._element = t, + this._startPosition = null, + this._options = { + ...a, + ...e + } + } + handleTouchStart(t) { + this._startPosition = this._getCoordinates(t) + } + handleTouchMove(t) { + var e; + if (this._startPosition) + return t = { + x: (t = this._getCoordinates(t)).x - this._startPosition.x, + y: t.y - this._startPosition.y + }, + t = this._getDirection(t), + "all" === this._options.direction ? t.y.value < this._options.threshold && t.x.value < this._options.threshold ? void 0 : (e = (t.y.value > t.x.value ? t.y : t.x).direction, + l.b.trigger(this._element, "swipe".concat(e)), + l.b.trigger(this._element, "swipe", { + direction: e + }), + void (this._startPosition = null)) : void (t[e = "left" === this._options.direction || "right" === this._options ? "x" : "y"].direction === this._options.direction && t[e].value > this._options.threshold && (l.b.trigger(this._element, "swipe".concat(t[e].direction)), + this._startPosition = null)) + } + handleTouchEnd() { + this._startPosition = null + } + _getCoordinates(t) { + var [t] = t.touches; + return { + x: t.clientX, + y: t.clientY + } + } + _getDirection(t) { + return { + x: { + direction: t.x < 0 ? "left" : "right", + value: Math.abs(t.x) + }, + y: { + direction: t.y < 0 ? "up" : "down", + value: Math.abs(t.y) + } + } + } + } + ; + var u = class { + constructor(t) { + var e = 1 < arguments.length && void 0 !== arguments[1] ? arguments[1] : "swipe" + , n = 2 < arguments.length && void 0 !== arguments[2] ? arguments[2] : {}; + this._element = t, + this._event = e, + this.swipe = new c(t,n), + this._touchStartHandler = this._handleTouchStart.bind(this), + this._touchMoveHandler = this._handleTouchMove.bind(this), + this._touchEndHandler = this._handleTouchEnd.bind(this) + } + dispose() { + this._element.removeEventListener("touchstart", this._touchStartHandler), + this._element.removeEventListener("touchmove", this._touchMoveHandler), + window.removeEventListener("touchend", this._touchEndHandler) + } + init() { + this._element.addEventListener("touchstart", t=>this._handleTouchStart(t)), + this._element.addEventListener("touchmove", t=>this._handleTouchMove(t)), + window.addEventListener("touchend", t=>this._handleTouchEnd(t)) + } + _handleTouchStart(t) { + this[this._event].handleTouchStart(t) + } + _handleTouchMove(t) { + this[this._event].handleTouchMove(t) + } + _handleTouchEnd(t) { + this[this._event].handleTouchEnd(t) + } + } + , h = n(52) + , d = n(7) + , p = n(0) + , f = n(2) + , g = n(110); + const m = "sidenav" + , b = "mdb.sidenav" + , v = "rotate-icon"; + const _ = '[data-mdb-toggle="sidenav"]' + , y = ".sidenav-collapse" + , w = ".sidenav-link" + , O = o.g ? 100 : -100 + , x = o.g ? -100 : 100; + let S = 0; + const C = { + accordion: "(boolean)", + backdrop: "(boolean)", + backdropClass: "(null|string)", + closeOnEsc: "(boolean)", + color: "(string)", + content: "(null|string)", + expandable: "(boolean)", + expandOnHover: "(boolean)", + focusTrap: "(boolean)", + hidden: "(boolean)", + mode: "(string)", + scrollContainer: "(null|string)", + slim: "(boolean)", + slimCollapsed: "(boolean)", + slimWidth: "(number)", + position: "(string)", + right: "(boolean)", + transitionDuration: "(number)", + width: "(number)" + } + , E = { + accordion: !1, + backdrop: !0, + backdropClass: null, + closeOnEsc: !0, + color: "primary", + content: null, + expandable: !0, + expandOnHover: !1, + focusTrap: !0, + hidden: !0, + mode: "over", + scrollContainer: null, + slim: !1, + slimCollapsed: !1, + slimWidth: 77, + position: "fixed", + right: !1, + transitionDuration: 300, + width: 240 + }; + class k { + constructor(t) { + var e = 1 < arguments.length && void 0 !== arguments[1] ? arguments[1] : {}; + this._element = t, + this._options = e, + S++, + this._ID = S, + this._backdrop = null, + this._content = null, + this._initialContentStyle = null, + this._slimCollapsed = !1, + this._activeNode = null, + this._tempSlim = !1, + this._focusTrap = null, + this._perfectScrollbar = null, + this._touch = null, + this.escHandler = t=>{ + t.keyCode === s.f && this.toggler && Object(o.h)(this.toggler) && (this._update(!1), + l.b.off(window, "keydown", this.escHandler)) + } + , + this.hashHandler = ()=>{ + this._setActiveElements() + } + , + t && (d.a.setData(t, b, this), + this._setup()) + } + static get NAME() { + return m + } + get container() { + if ("fixed" === this.options.position) + return f.a.findOne("body"); + const e = t=>{ + return t.parentNode && t.parentNode !== document ? "relative" === t.parentNode.style.position || t.parentNode.classList.contains("position-relative") ? t.parentNode : e(t.parentNode) : t + } + ; + return e(this._element) + } + get isVisible() { + let t = 0 + , e = window.innerWidth; + var n, i = ("fixed" !== this.options.position && (i = this.container.getBoundingClientRect(), + t = i.x, + e = i.x + i.width), + this._element.getBoundingClientRect())["x"]; + if (this.options.right && !o.g || !this.options.right && o.g) { + let t = 0; + return this.container.scrollHeight > this.container.clientHeight && (t = this.container.offsetWidth - this.container.clientWidth), + "BODY" === this.container.tagName && (n = document.documentElement.clientWidth, + t = Math.abs(window.innerWidth - n)), + 10 < Math.abs(i + t - e) + } + return Math.abs(i - t) < 10 + } + get links() { + return f.a.find(w, this._element) + } + get navigation() { + return f.a.find(".sidenav-menu", this._element) + } + get options() { + var t = { + ...E, + ...p.a.getDataAttributes(this._element), + ...this._options + }; + return Object(o.j)(m, t, C), + t + } + get sidenavStyle() { + return { + width: "".concat(this.width, "px"), + height: "fixed" === this.options.position ? "100vh" : "100%", + position: this.options.position, + transitionDuration: this.transitionDuration, + transitionProperty: "transform, width, padding, margin", + transitionTimingFunction: "linear" + } + } + get toggler() { + return f.a.find(_).find(t=>{ + t = p.a.getDataAttribute(t, "target"); + return f.a.findOne(t) === this._element + } + ) + } + get transitionDuration() { + return "".concat(this.options.transitionDuration / 1e3, "s") + } + get translation() { + return this.options.right ? x : O + } + get width() { + return this._slimCollapsed ? this.options.slimWidth : this.options.width + } + changeMode(t) { + this._setMode(t) + } + dispose() { + this._backdrop && this._removeBackdrop(), + l.b.off(window, "keydown", this.escHandler), + l.b.off(window, "hashchange", this.hashHandler), + this._touch.dispose(), + d.a.removeData(this._element, b), + this._element = null + } + hide() { + this._setVisibility(!1), + this._update(!1) + } + show() { + this._setVisibility(!0), + this._update(!0) + } + toggle() { + this._setVisibility(!this.isVisible), + this._update(!this.isVisible) + } + toggleSlim() { + this._setSlim(!this._slimCollapsed) + } + update(t) { + this._options = t, + this._setup() + } + _appendArrow(t) { + const e = Object(o.b)("i"); + ["fas", "fa-angle-down", v].forEach(t=>{ + p.a.addClass(e, t) + } + ), + 0 === f.a.find(".".concat(v), t).length && t.appendChild(e) + } + _collapseItems() { + this.navigation.forEach(t=>{ + f.a.find(y, t).forEach(t=>{ + h.a.getInstance(t).hide() + } + ) + } + ) + } + _setupBackdrop() { + var t, e = [], n = (this.options.backdropClass && e.push(this.options.backdropClass), + { + transition: "opacity ".concat(this.transitionDuration, " ease-out"), + position: this.options.position, + width: "fixed" === this.options.position ? "100vw" : "100%", + height: "fixed" === this.options.position ? "100vh" : "100%" + }); + this._backdrop || (t = Object(o.b)("div"), + e.push("sidenav-backdrop"), + n.opacity = 0, + l.b.on(t, "click", ()=>{ + this._setVisibility(!1), + this._update(!1) + } + ), + this._backdrop = t), + this._backdrop.classList.add(...e), + p.a.style(this._backdrop, n) + } + _getOffsetValue(t, e) { + var {index: e, property: n, offsets: i} = e; + return this._getPxValue(this._initialContentStyle[e][i[n].property]) + (t ? i[n].value : 0) + } + _getProperty() { + for (var t = arguments.length, e = new Array(t), n = 0; n < t; n++) + e[n] = arguments[n]; + return e.map((t,e)=>0 === e ? t : t[0].toUpperCase().concat(t.slice(1))).join("") + } + _getPxValue(t) { + return t ? parseFloat(t) : 0 + } + _handleSwipe(t, e) { + e && this._slimCollapsed && this.options.slim && this.options.expandable ? this.toggleSlim() : e || (!this._slimCollapsed && this.options.slim && this.options.expandable ? this.toggleSlim() : this.toggler && Object(o.h)(this.toggler) && this.toggle()) + } + _isActive(t, e) { + return e ? e === t : !!t.attributes.href && new URL(t,window.location.href).href === window.location.href + } + _isAllToBeCollapsed() { + return 0 === f.a.find('[data-mdb-toggle="collapse"]', this._element).filter(t=>"true" === t.getAttribute("aria-expanded")).length + } + _isAllCollapsed() { + return 0 === f.a.find(y, this._element).filter(t=>Object(o.h)(t)).length + } + _setup() { + this._setupTouch(), + this.options.focusTrap && this._setupFocusTrap(), + this.options.backdrop && (this._setupBackdrop(), + this.options.hidden || "over" !== this.options.mode || this._appendBackdrop()), + this._setupCollapse(), + this.options.slimCollapsed && p.a.addClass(this._element, "sidenav-slim"), + this.options.slim && this._setupSlim(), + this._setupInitialStyling(), + this._setupScrolling(), + this.options.content && this._setupContent(), + this._setupActiveState(), + this._setupRippleEffect(), + this.options.hidden || (this.options.right && this.show(), + this._updateOffsets(!0, !0)) + } + _setupActiveState() { + this._setActiveElements(), + this.links.forEach(e=>{ + l.b.on(e, "click", ()=>this._setActiveElements(e)), + l.b.on(e, "keydown", t=>{ + t.keyCode === s.e && this._setActiveElements(e) + } + ) + } + ), + l.b.on(window, "hashchange", this.hashHandler) + } + _setupCollapse() { + this.navigation.forEach((n,i)=>{ + f.a.find(y, n).forEach((t,e)=>this._setupCollapseList({ + list: t, + index: e, + menu: n, + menuIndex: i + })) + } + ) + } + _generateCollpaseID(t, e) { + return "sidenav-collapse-".concat(this._ID, "-").concat(e, "-").concat(t) + } + _setupCollapseList(t) { + let {list: e, index: n, menu: i, menuIndex: o} = t; + t = this._generateCollpaseID(n, o); + e.classList.add("collapse"), + e.setAttribute("id", t); + const [r] = f.a.prev(e, w) + , s = (p.a.setDataAttribute(r, "toggle", "collapse"), + r.setAttribute("href", "#".concat(t)), + r.setAttribute("role", "button"), + h.a.getInstance(e) || new h.a(e,{ + toggle: !1, + parent: this.options.accordion ? i : e + })); + this._appendArrow(r), + p.a.hasClass(e, "show") && this._rotateArrow(r, 180), + l.b.on(r, "click", t=>{ + this._toggleCategory(t, s, e), + this._tempSlim && this._isAllToBeCollapsed() && (this._setSlim(!0), + this._tempSlim = !1), + "over" === this.options.mode && this._focusTrap && this._focusTrap.update() + } + ), + l.b.on(e, "show.bs.collapse", ()=>this._rotateArrow(r, 180)), + l.b.on(e, "hide.bs.collapse", ()=>this._rotateArrow(r, 0)), + l.b.on(e, "shown.bs.collapse", ()=>{ + "over" === this.options.mode && this._focusTrap && this._focusTrap.update() + } + ), + l.b.on(e, "hidden.bs.collapse", ()=>{ + this._tempSlim && this._isAllCollapsed() && (this._setSlim(!0), + this._tempSlim = !1), + "over" === this.options.mode && this._focusTrap && this._focusTrap.update() + } + ) + } + _setupContent() { + this._content = f.a.find(this.options.content), + this._initialContentStyle || (this._initialContentStyle = this._content.map(t=>{ + var {paddingLeft: t, paddingRight: e, marginLeft: n, marginRight: i, transition: o} = window.getComputedStyle(t); + return { + paddingLeft: t, + paddingRight: e, + marginLeft: n, + marginRight: i, + transition: o + } + } + )) + } + _setupFocusTrap() { + this._focusTrap = new r.a(this._element,{ + event: "keydown", + condition: t=>t.keyCode === s.m, + onlyVisible: !0 + },this.toggler) + } + _setupInitialStyling() { + this._setColor(), + p.a.style(this._element, this.sidenavStyle) + } + _setupScrolling() { + let e = this._element; + var t; + this.options.scrollContainer && (e = f.a.findOne(this.options.scrollContainer, this._element), + t = Object(o.a)(e.parentNode.children).filter(t=>t !== e).reduce((t,e)=>t + e.clientHeight, 0), + p.a.style(e, { + maxHeight: "calc(100% - ".concat(t, "px)"), + position: "relative" + })), + this._perfectScrollbar = new i.a(e,{ + suppressScrollX: !0, + handlers: ["click-rail", "drag-thumb", "wheel", "touch"] + }) + } + _setupSlim() { + this._slimCollapsed = this.options.slimCollapsed, + this._toggleSlimDisplay(this._slimCollapsed), + this.options.expandOnHover && (this._element.addEventListener("mouseenter", ()=>{ + this._slimCollapsed && this._setSlim(!1) + } + ), + this._element.addEventListener("mouseleave", ()=>{ + this._slimCollapsed || this._setSlim(!0) + } + )) + } + _setupRippleEffect() { + this.links.forEach(t=>{ + let e = g.a.getInstance(t); + if (e && e._options.color !== this.options.color) + e.dispose(); + else if (e) + return; + e = new g.a(t,{ + rippleColor: this.options.color + }) + } + ) + } + _setupTouch() { + this._touch = new u(this._element,"swipe",{ + threshold: 20 + }), + this._touch.init(), + l.b.on(this._element, "swipeleft", t=>this._handleSwipe(t, this.options.right)), + l.b.on(this._element, "swiperight", t=>this._handleSwipe(t, !this.options.right)) + } + _setActive(t, e) { + p.a.addClass(t, "active"), + this._activeNode && this._activeNode.classList.remove("active"), + this._activeNode = t; + var n, [t] = f.a.parents(this._activeNode, y); + t ? ([n] = f.a.prev(t, w), + this._setActiveCategory(n), + e || this._slimCollapsed || h.a.getInstance(t).show()) : this._setActiveCategory() + } + _setActiveCategory(e) { + this.navigation.forEach(t=>{ + f.a.find(y, t).forEach(t=>{ + var [t] = f.a.prev(t, w); + t !== e ? t.classList.remove("active") : p.a.addClass(t, "active") + } + ) + } + ) + } + _setActiveElements(e) { + this.navigation.forEach(t=>{ + f.a.find(w, t).filter(t=>0 === f.a.next(t, y).length).forEach(t=>{ + this._isActive(t, e) && t !== this._activeNode && this._setActive(t, e) + } + ) + } + ) + } + _setColor() { + var t = ["primary", "secondary", "success", "info", "warning", "danger", "light", "dark"] + , e = this.options["color"] + , e = t.includes(e) ? e : "primary"; + t.forEach(t=>{ + this._element.classList.remove("sidenav-".concat(t)) + } + ), + p.a.addClass(this._element, "sidenav-".concat(e)) + } + _setContentOffsets(r, s, a) { + this._content.forEach((t,e)=>{ + var n = this._getOffsetValue(r, { + index: e, + property: "padding", + offsets: s + }) + , i = this._getOffsetValue(r, { + index: e, + property: "margin", + offsets: s + }) + , o = {}; + a || (o.transition = "all ".concat(this.transitionDuration, " linear")), + o[s.padding.property] = "".concat(n, "px"), + o[s.margin.property] = "".concat(i, "px"), + p.a.style(t, o), + r && (a ? p.a.style(t, { + transition: this._initialContentStyle[e].transition + }) : l.b.on(t, "transitionend", ()=>{ + p.a.style(t, { + transition: this._initialContentStyle[e].transition + }) + } + )) + } + ) + } + _setMode(t) { + this.options.mode !== t && (this._options.mode = t, + this._update(this.isVisible)) + } + _setSlim(t) { + this._triggerEvents(...t ? ["collapse", "collapsed"] : ["expand", "expanded"]), + t ? (this._collapseItems(), + p.a.addClass(this._element, "sidenav-slim")) : p.a.removeClass(this._element, "sidenav-slim"), + this._slimCollapsed = t, + this._toggleSlimDisplay(t), + p.a.style(this._element, { + width: "".concat(this.width, "px") + }), + this._updateOffsets(this.isVisible) + } + _setTabindex(e) { + this.links.forEach(t=>{ + t.tabIndex = e ? 1 : -1 + } + ) + } + _setVisibility(t) { + this._triggerEvents(...t ? ["show", "shown"] : ["hide", "hidden"]) + } + _rotateArrow(t, e) { + var [t] = f.a.children(t, ".".concat(v)); + t && p.a.style(t, { + transform: "rotate(".concat(e, "deg)") + }) + } + async _toggleBackdrop(t) { + t && "over" === this.options.mode ? this._appendBackdrop() : (p.a.style(this._backdrop, { + opacity: 0 + }), + await setTimeout(()=>{ + this._removeBackdrop() + } + , this.options.transitionDuration)) + } + _removeBackdrop() { + this._backdrop.parentNode === this.container && this.container.removeChild(this._backdrop) + } + _appendBackdrop() { + this.container.appendChild(this._backdrop), + setTimeout(()=>p.a.style(this._backdrop, { + opacity: 1 + }), 0) + } + _toggleCategory(t, e) { + t.preventDefault(), + e.toggle(), + this._slimCollapsed && this.options.expandable && (this._tempSlim = !0, + this._setSlim(!1)) + } + _toggleSlimDisplay(t) { + const e = f.a.find('[data-mdb-slim="true"]', this._element) + , n = f.a.find('[data-mdb-slim="false"]', this._element) + , i = ()=>{ + e.forEach(t=>{ + p.a.style(t, { + display: this._slimCollapsed ? "unset" : "none" + }) + } + ), + n.forEach(t=>{ + p.a.style(t, { + display: this._slimCollapsed ? "none" : "unset" + }) + } + ) + } + ; + t ? setTimeout(()=>i(), this.options.transitionDuration) : i() + } + async _triggerEvents(t, e) { + l.b.trigger(this._element, "".concat(t, ".mdb.sidenav")), + e && await setTimeout(()=>{ + l.b.trigger(this._element, "".concat(e, ".mdb.sidenav")) + } + , this.options.transitionDuration + 5) + } + _update(t) { + this.toggler && this._updateTogglerAria(t), + this._updateDisplay(t), + this.options.backdrop && this._toggleBackdrop(t), + this._updateOffsets(t), + t && this.options.closeOnEsc && "side" !== this.options.mode && l.b.on(window, "keydown", this.escHandler), + this.options.focusTrap && this._updateFocus(t) + } + _updateDisplay(t) { + t = t ? 0 : this.translation; + p.a.style(this._element, { + transform: "translateX(".concat(t, "%)") + }) + } + _updateFocus(t) { + if (this._setTabindex(t), + "over" === this.options.mode && this.options.focusTrap) { + if (t) + return void this._focusTrap.trap(); + this._focusTrap.disable() + } + this._focusTrap.disable() + } + _updateOffsets(t) { + var e = 1 < arguments.length && void 0 !== arguments[1] && arguments[1] + , [n,i] = this.options.right && !o.g || !this.options.right && o.g ? ["right", "left"] : ["left", "right"] + , n = { + property: this._getProperty("padding", n), + value: "over" === this.options.mode ? 0 : this.width + } + , i = { + property: this._getProperty("margin", i), + value: "push" === this.options.mode ? -1 * this.width : 0 + }; + l.b.trigger(this._element, "update.mdb.sidenav", { + margin: i, + padding: n + }), + this._content && this._setContentOffsets(t, { + padding: n, + margin: i + }, e) + } + _updateTogglerAria(t) { + this.toggler.setAttribute("aria-expanded", t) + } + static toggleSidenav() { + return function(t) { + t = f.a.closest(t.target, _), + t = p.a.getDataAttributes(t).target; + f.a.find(t).forEach(t=>{ + (k.getInstance(t) || new k(t)).toggle() + } + ) + } + } + static jQueryInterface(n, i) { + return this.each(function() { + let t = d.a.getData(this, b); + var e = "object" == typeof n && n; + if ((t || !/dispose/.test(n)) && (t = t || new k(this,e), + "string" == typeof n)) { + if (void 0 === t[n]) + throw new TypeError('No method named "'.concat(n, '"')); + t[n](i) + } + }) + } + static getInstance(t) { + return d.a.getData(t, b) + } + static getOrCreateInstance(t) { + var e = 1 < arguments.length && void 0 !== arguments[1] ? arguments[1] : {}; + return this.getInstance(t) || new this(t,"object" == typeof e ? e : null) + } + } + l.b.on(document, "click", _, k.toggleSidenav()), + f.a.find(".sidenav").forEach(t=>{ + let e = k.getInstance(t); + return e = e || new k(t) + } + ), + Object(o.i)(()=>{ + const t = Object(o.f)(); + if (t) { + const e = t.fn[m]; + t.fn[m] = k.jQueryInterface, + t.fn[m].Constructor = k, + t.fn[m].noConflict = ()=>(t.fn[m] = e, + k.jQueryInterface) + } + } + ); + e.a = k + } + , function(D, t, e) { + "use strict"; + var n = e(3) + , i = e(2) + , o = e(1) + , r = e(7) + , s = e(0) + , a = (e(11), + e(12), + e(28), + e(4)) + , l = e(6) + , c = e(8) + , u = e(131) + , h = e(21) + , d = e(139) + , p = e(140) + , e = e(54); + const f = ".".concat("bs.modal"); + const g = "hide".concat(f) + , m = "hidePrevented".concat(f) + , b = "hidden".concat(f) + , v = "show".concat(f) + , _ = "shown".concat(f) + , y = "resize".concat(f) + , N = "click.dismiss".concat(f) + , H = "mousedown.dismiss".concat(f) + , B = "keydown.dismiss".concat(f); + var w = "click".concat(f).concat(".data-api"); + const O = "modal-open" + , x = "modal-static"; + const W = { + backdrop: !0, + focus: !0, + keyboard: !0 + } + , Y = { + backdrop: "(boolean|string)", + focus: "boolean", + keyboard: "boolean" + }; + class S extends h.a { + constructor(t, e) { + super(t, e), + this._dialog = c.a.findOne(".modal-dialog", this._element), + this._backdrop = this._initializeBackDrop(), + this._focustrap = this._initializeFocusTrap(), + this._isShown = !1, + this._isTransitioning = !1, + this._scrollBar = new u.a, + this._addEventListeners() + } + static get Default() { + return W + } + static get DefaultType() { + return Y + } + static get NAME() { + return "modal" + } + toggle(t) { + return this._isShown ? this.hide() : this.show(t) + } + show(t) { + this._isShown || this._isTransitioning || l.a.trigger(this._element, v, { + relatedTarget: t + }).defaultPrevented || (this._isShown = !0, + this._isTransitioning = !0, + this._scrollBar.hide(), + document.body.classList.add(O), + this._adjustDialog(), + this._backdrop.show(()=>this._showElement(t))) + } + hide() { + !this._isShown || this._isTransitioning || l.a.trigger(this._element, g).defaultPrevented || (this._isShown = !1, + this._isTransitioning = !0, + this._focustrap.deactivate(), + this._element.classList.remove("show"), + this._queueCallback(()=>this._hideModal(), this._element, this._isAnimated())) + } + dispose() { + for (const t of [window, this._dialog]) + l.a.off(t, f); + this._backdrop.dispose(), + this._focustrap.deactivate(), + super.dispose() + } + handleUpdate() { + this._adjustDialog() + } + _initializeBackDrop() { + return new d.a({ + isVisible: Boolean(this._config.backdrop) && Boolean(!this._config.modalNonInvasive), + isAnimated: this._isAnimated() + }) + } + _initializeFocusTrap() { + return new p.a({ + trapElement: this._element + }) + } + _showElement(t) { + document.body.contains(this._element) || document.body.append(this._element), + this._element.style.display = "block", + this._element.removeAttribute("aria-hidden"), + this._element.setAttribute("aria-modal", !0), + this._element.setAttribute("role", "dialog"), + this._element.scrollTop = 0; + var e = c.a.findOne(".modal-body", this._dialog); + e && (e.scrollTop = 0), + Object(a.p)(this._element), + this._element.classList.add("show"); + this._queueCallback(()=>{ + this._config.focus && this._focustrap.activate(), + this._isTransitioning = !1, + l.a.trigger(this._element, _, { + relatedTarget: t + }) + } + , this._dialog, this._isAnimated()) + } + _addEventListeners() { + l.a.on(this._element, B, t=>{ + "Escape" === t.key && (this._config.keyboard ? (t.preventDefault(), + this.hide()) : this._triggerBackdropTransition()) + } + ), + l.a.on(window, y, ()=>{ + this._isShown && !this._isTransitioning && this._adjustDialog() + } + ), + l.a.on(this._element, H, e=>{ + l.a.one(this._element, N, t=>{ + this._element === e.target && this._element === t.target && ("static" === this._config.backdrop ? this._triggerBackdropTransition() : this._config.backdrop && this.hide()) + } + ) + } + ) + } + _hideModal() { + this._element.style.display = "none", + this._element.setAttribute("aria-hidden", !0), + this._element.removeAttribute("aria-modal"), + this._element.removeAttribute("role"), + this._isTransitioning = !1, + this._backdrop.hide(()=>{ + document.body.classList.remove(O), + this._resetAdjustments(), + this._scrollBar.reset(), + l.a.trigger(this._element, b) + } + ) + } + _isAnimated() { + return this._element.classList.contains("fade") + } + _triggerBackdropTransition() { + var t = l.a.trigger(this._element, m); + if (!t.defaultPrevented) { + t = this._element.scrollHeight > document.documentElement.clientHeight; + const e = this._element.style.overflowY; + "hidden" === e || this._element.classList.contains(x) || (t || (this._element.style.overflowY = "hidden"), + this._element.classList.add(x), + this._queueCallback(()=>{ + this._element.classList.remove(x), + this._queueCallback(()=>{ + this._element.style.overflowY = e + } + , this._dialog) + } + , this._dialog), + this._element.focus()) + } + } + _adjustDialog() { + var t, e = this._element.scrollHeight > document.documentElement.clientHeight, n = this._scrollBar.getWidth(), i = 0 < n; + i && !e && (t = Object(a.m)() ? "paddingLeft" : "paddingRight", + this._element.style[t] = "".concat(n, "px")), + !i && e && (t = Object(a.m)() ? "paddingRight" : "paddingLeft", + this._element.style[t] = "".concat(n, "px")) + } + _resetAdjustments() { + this._element.style.paddingLeft = "", + this._element.style.paddingRight = "" + } + static jQueryInterface(e, n) { + return this.each(function() { + var t = S.getOrCreateInstance(this, e); + if ("string" == typeof e) { + if (void 0 === t[e]) + throw new TypeError('No method named "'.concat(e, '"')); + t[e](n) + } + }) + } + } + l.a.on(document, w, '[data-mdb-toggle="modal"]', function(t) { + const e = Object(a.f)(this); + ["A", "AREA"].includes(this.tagName) && t.preventDefault(), + l.a.one(e, v, t=>{ + t.defaultPrevented || l.a.one(e, b, ()=>{ + Object(a.n)(this) && this.focus() + } + ) + } + ), + c.a.find(".modal.show").forEach(t=>{ + t.classList.contains("modal-non-invasive-show") || S.getInstance(t).hide() + } + ), + S.getOrCreateInstance(e).toggle(this) + }), + Object(e.a)(S), + Object(a.a)(S); + h = S; + const F = ".fixed-top, .fixed-bottom, .is-fixed, .sticky-top" + , X = ".sticky-top"; + const C = (t,n)=>{ + i.a.find(t).forEach(t=>{ + var e = s.a.getDataAttribute(t, n); + void 0 === e ? t.style.removeProperty(n) : (s.a.removeDataAttribute(t, n), + t.style[n] = e) + } + ) + } + ; + const E = "modal" + , k = "bs.modal"; + w = ".".concat(k); + const A = "modal-non-invasive-open" + , j = "modal-non-invasive-show"; + const T = ".".concat("modal-content") + , z = ".".concat("modal-bottom") + , U = ".".concat("modal-bottom-right") + , q = ".".concat("modal-bottom-left") + , $ = ".".concat("modal-top-right") + , V = ".".concat("modal-top-left") + , K = ".".concat("modal-dialog-scrollable") + , G = ".".concat("modal-dialog"); + e = "mousedown".concat(w).concat(".data-api"); + const L = "show".concat(w) + , P = "shown".concat(w) + , R = "hidden".concat(w) + , Q = [{ + name: "show", + parametersToCopy: ["relatedTarget"] + }, { + name: "shown", + parametersToCopy: ["relatedTarget"] + }, { + name: "hide" + }, { + name: "hidePrevented" + }, { + name: "hidden" + }] + , M = { + backdrop: !0, + keyboard: !0, + focus: !0, + show: !0, + modalNonInvasive: !1 + } + , Z = { + backdrop: "(boolean|string)", + keyboard: "boolean", + focus: "boolean", + show: "boolean", + modalNonInvasive: "boolean" + }; + class I extends h { + constructor(t, e) { + super(t, e), + this._config = this._getConfig(e), + this._modalContentRect = "", + this._modalContentComputedStyles = "", + this._isNonInvasive = this._config.modalNonInvasive, + this._isScrollable = "", + this._isBottomRight = "", + this._isBottomLeft = "", + this._isTopRight = "", + this._isTopLeft = "", + this._isSideTopModal = "", + this._isSideBottomModal = "", + this._isSideModal = "", + this._isModalBottom = "", + this._isNonInvasive && (this._config.backdrop = !1, + this._config.focus = !1, + this._isBodyOverflowing = !0, + this._onModalShow(), + this._onModalShown(), + this._onModalHidden(), + this._listenToWindowResize()), + r.a.setData(t, k, this), + this._bindMdbEvents() + } + static get NAME() { + return E + } + dispose() { + o.b.off(this._element, L), + o.b.off(this._element, P), + o.b.off(this._element, "hide.bs.modal"), + o.b.off(this._element, R), + o.b.off(this._element, "hidePrevented.bs.modal"), + this._modalContentRect = null, + this._modalContentComputedStyles = null, + this._isNonInvasive = null, + this._isScrollable = null, + this._isBottomRight = null, + this._isBottomLeft = null, + this._isTopRight = null, + this._isTopLeft = null, + this._isSideTopModal = null, + this._isSideBottomModal = null, + this._isSideModal = null, + this._isModalBottom = null, + super.dispose() + } + _onModalShow() { + o.b.on(this._element, L, ()=>{ + this._addNonInvasiveClass() + } + ) + } + _onModalShown() { + o.b.on(this._element, P, ()=>{ + var t = i.a.findOne(T, this._element); + this._isScrollable = i.a.findOne(K, this._element), + this._isBottomRight = i.a.findOne(U, this._element), + this._isBottomLeft = i.a.findOne(q, this._element), + this._isTopRight = i.a.findOne($, this._element), + this._isTopLeft = i.a.findOne(V, this._element), + this._isSideTopModal = this._isTopLeft || this._isTopRight, + this._isSideBottomModal = this._isBottomLeft || this._isBottomRight, + this._isSideModal = this._isSideTopModal || this._isSideBottomModal, + this._isModalBottom = i.a.findOne(z, this._element), + this._modalContentRect = t.getBoundingClientRect(), + this._modalContentComputedStyles = window.getComputedStyle(t), + this._modalDialogComputedStyles = window.getComputedStyle(i.a.findOne(G, this._element)), + this._topOffset = parseInt(this._modalDialogComputedStyles.top, 0), + this._leftOffset = parseInt(this._modalDialogComputedStyles.left, 0), + this._rightOffset = parseInt(this._modalDialogComputedStyles.right, 0), + this._bottomOffset = parseInt(this._modalDialogComputedStyles.bottom, 0), + this._addOpenClass(), + this._setStyles() + } + ) + } + _listenToWindowResize() { + o.b.on(window, "resize", this._handleWindowResize.bind(this)) + } + _handleWindowResize() { + var t = i.a.findOne(T, this._element); + if (this._resetStyles(), + this._modalContentRect = t.getBoundingClientRect(), + this._modalContentComputedStyles = window.getComputedStyle(t), + this._isSideTopModal || this._isSideBottomModal) { + let t = 0 + , e = 0; + (this._isBottomRight || this._isBottomLeft) && (e = -this._bottomOffset), + (this._isBottomRight || this._isTopRight) && (t = -this._rightOffset), + (this._isBottomLeft || this._isTopLeft) && (t = this._leftOffset), + void this._setStyles(t, e) + } else + this._setStyles() + } + _showBackdrop(t) { + this._isNonInvasive ? "function" == typeof t && t() : super._showBackdrop(t) + } + _adjustDialog() { + super._adjustDialog(); + var t = document.body.classList.contains(A); + (this._isNonInvasive || t) && (this._isBodyOverflowing = !1), + this._isNonInvasive && (this._resetAdjustments(), + C("body", "overflow"), + C("body", "paddingRight"), + C(F, "paddingRight"), + C(X, "marginRight")) + } + _onModalHidden() { + o.b.on(this._element, R, t=>{ + t.stopImmediatePropagation(), + this._removeOpenClass(), + this._resetStyles(), + this._removeNonInvasiveClass() + } + ) + } + _addOpenClass() { + this._element.classList.add(j) + } + _removeOpenClass() { + this._element.classList.remove(j) + } + _addNonInvasiveClass() { + document.body.classList.add(A) + } + _removeNonInvasiveClass() { + i.a.findOne(".".concat("modal", ".").concat("show", ".").concat(j), document.body) ? document.body.classList.add("modal-open") : document.body.classList.remove(A) + } + _setStyles() { + var t = 0 < arguments.length && void 0 !== arguments[0] ? arguments[0] : 0 + , e = 1 < arguments.length && void 0 !== arguments[1] ? arguments[1] : 0 + , n = 992 <= window.innerWidth; + this._element.style.left = "".concat(this._modalContentRect.left + t, "px"), + this._element.style.width = this._modalContentComputedStyles.width, + this._isScrollable || (this._element.style.height = this._modalContentComputedStyles.height, + this._element.style.display = ""), + n && ((this._isSideBottomModal || this._isModalBottom) && (this._element.style.top = "".concat(this._modalContentRect.top + e, "px")), + this._isSideModal) && (this._element.style.overflowX = "auto"), + n || (this._element.style.height = "") + } + _resetStyles() { + this._element.style.left = "", + this._element.style.top = "", + this._element.style.height = "", + this._element.style.width = "", + this._isScrollable || (this._element.style.display = ""), + this._isSideModal && (this._element.style.overflowX = "") + } + _getConfig(t) { + let e; + this._element && (e = Object(n.c)(this._element)); + t = { + ...M, + ...s.a.getDataAttributes(this._element), + ...s.a.getDataAttributes(e), + ...t + }; + return Object(n.j)(E, t, Z), + t + } + _bindMdbEvents() { + o.b.extend(this._element, Q, E) + } + static jQueryInterface(n, i) { + return this.each(function() { + let t = r.a.getData(this, k); + var e = { + ...M, + ...s.a.getDataAttributes(this), + ..."object" == typeof n && n ? n : {} + }; + if (t = t || new I(this,e), + "string" == typeof n) { + if (void 0 === t[n]) + throw new TypeError('No method named "'.concat(n, '"')); + t[n](i) + } else + e.show && t.show(i) + }) + } + } + o.b.on(document, e, '[data-mdb-toggle="modal"]', function(t) { + var t = Object(n.c)(t.target) + , e = r.a.getData(t, k); + e || (e = { + ...s.a.getDataAttributes(t), + ...s.a.getDataAttributes(this._element) + }, + new I(t,e)) + }), + Object(n.i)(()=>{ + const t = Object(n.f)(); + if (t) { + const e = t.fn[E]; + t.fn[E] = I.jQueryInterface, + t.fn[E].Constructor = I, + t.fn[E].noConflict = ()=>(t.fn[E] = e, + I.jQueryInterface) + } + } + ); + t.a = I + } + , function(t, e, n) { + "use strict"; + n(17); + var i = n(3) + , o = n(7) + , r = n(1) + , s = n(0) + , a = n(2) + , l = n(4) + , c = n(6) + , n = n(21); + var u = ".".concat("bs.button"); + const h = '[data-mdb-toggle="button"]'; + u = "click".concat(u).concat(".data-api"); + class d extends n.a { + static get NAME() { + return "button" + } + toggle() { + this._element.setAttribute("aria-pressed", this._element.classList.toggle("active")) + } + static jQueryInterface(e) { + return this.each(function() { + var t = d.getOrCreateInstance(this); + "toggle" === e && t[e]() + }) + } + } + c.a.on(document, u, h, t=>{ + t.preventDefault(); + t = t.target.closest(h); + d.getOrCreateInstance(t).toggle() + } + ), + Object(l.a)(d); + n = d; + const p = "button" + , f = "mdb.".concat(p); + c = ".".concat(f); + const g = "click".concat(c) + , m = "transitionend" + , b = "mouseenter" + , v = "mouseleave" + , _ = "hide".concat(c) + , y = "hidden".concat(c) + , w = "show".concat(c) + , O = "shown".concat(c) + , x = "fixed-action-btn"; + class S extends n { + constructor(t) { + super(t), + this._fn = {}, + this._element && (o.a.setData(this._element, f, this), + this._init()) + } + static get NAME() { + return p + } + static jQueryInterface(n, i) { + return this.each(function() { + let t = o.a.getData(this, f); + var e = "object" == typeof n && n; + if ((t || !/dispose/.test(n)) && (t = t || new S(this,e), + "string" == typeof n)) { + if (void 0 === t[n]) + throw new TypeError('No method named "'.concat(n, '"')); + t[n](i) + } + }) + } + get _actionButton() { + return a.a.findOne(".fixed-action-btn:not(.smooth-scroll) > .btn-floating", this._element) + } + get _buttonListElements() { + return a.a.find("ul .btn", this._element) + } + get _buttonList() { + return a.a.findOne("ul", this._element) + } + get _isTouchDevice() { + return "ontouchstart"in document.documentElement + } + show() { + s.a.hasClass(this._element, x) && (r.b.off(this._buttonList, m), + r.b.trigger(this._element, w), + this._bindListOpenTransitionEnd(), + s.a.addStyle(this._element, { + height: "".concat(this._fullContainerHeight, "px") + }), + this._toggleVisibility(!0)) + } + hide() { + s.a.hasClass(this._element, x) && (r.b.off(this._buttonList, m), + r.b.trigger(this._element, _), + this._bindListHideTransitionEnd(), + this._toggleVisibility(!1)) + } + dispose() { + s.a.hasClass(this._element, x) && (r.b.off(this._actionButton, g), + this._actionButton.removeEventListener(b, this._fn.mouseenter), + this._element.removeEventListener(v, this._fn.mouseleave)), + super.dispose() + } + _init() { + s.a.hasClass(this._element, x) && (this._saveInitialHeights(), + this._setInitialStyles(), + this._bindInitialEvents()) + } + _bindMouseEnter() { + this._actionButton.addEventListener(b, this._fn.mouseenter = ()=>{ + this._isTouchDevice || this.show() + } + ) + } + _bindMouseLeave() { + this._element.addEventListener(v, this._fn.mouseleave = ()=>{ + this.hide() + } + ) + } + _bindClick() { + r.b.on(this._actionButton, g, ()=>{ + s.a.hasClass(this._element, "active") ? this.hide() : this.show() + } + ) + } + _bindListHideTransitionEnd() { + r.b.on(this._buttonList, m, t=>{ + "transform" === t.propertyName && (r.b.off(this._buttonList, m), + this._element.style.height = "".concat(this._initialContainerHeight, "px"), + r.b.trigger(this._element, y)) + } + ) + } + _bindListOpenTransitionEnd() { + r.b.on(this._buttonList, m, t=>{ + "transform" === t.propertyName && (r.b.off(this._buttonList, m), + r.b.trigger(this._element, O)) + } + ) + } + _toggleVisibility(t) { + const e = t ? "addClass" : "removeClass"; + t = t ? "translate(0)" : "translateY(".concat(this._fullContainerHeight, "px)"); + s.a.addStyle(this._buttonList, { + transform: t + }), + this._buttonListElements && this._buttonListElements.forEach(t=>s.a[e](t, "shown")), + s.a[e](this._element, "active") + } + _getHeight(t) { + t = window.getComputedStyle(t); + return parseFloat(t.getPropertyValue("height")) + } + _saveInitialHeights() { + this._initialContainerHeight = this._getHeight(this._element), + this._initialListHeight = this._getHeight(this._buttonList), + this._fullContainerHeight = this._initialContainerHeight + this._initialListHeight + } + _bindInitialEvents() { + this._bindClick(), + this._bindMouseEnter(), + this._bindMouseLeave() + } + _setInitialStyles() { + this._buttonList.style.marginBottom = "".concat(this._initialContainerHeight, "px"), + this._buttonList.style.transform = "translateY(".concat(this._fullContainerHeight, "px)"), + this._element.style.height = "".concat(this._initialContainerHeight, "px") + } + } + a.a.find(".fixed-action-btn").forEach(t=>{ + let e = S.getInstance(t); + return e = e || new S(t) + } + ), + a.a.find('[data-mdb-toggle="button"]').forEach(t=>{ + let e = S.getInstance(t); + return e = e || new S(t) + } + ), + Object(i.i)(()=>{ + const t = Object(i.f)(); + if (t) { + const e = t.fn[p]; + t.fn[p] = S.jQueryInterface, + t.fn[p].Constructor = S, + t.fn[p].noConflict = ()=>(t.fn[p] = e, + S.jQueryInterface) + } + } + ); + e.a = S + } + , function(t, e, n) { + "use strict"; + var i = n(3) + , o = n(1) + , r = n(2) + , s = n(4) + , n = n(69); + const a = { + ...n.a.Default, + content: "", + offset: [0, 8], + placement: "right", + template: '', + trigger: "click" + } + , l = { + ...n.a.DefaultType, + content: "(null|string|element|function)" + }; + class c extends n.a { + static get Default() { + return a + } + static get DefaultType() { + return l + } + static get NAME() { + return "popover" + } + _isWithContent() { + return this._getTitle() || this._getContent() + } + _getContentForTemplate() { + return { + ".popover-header": this._getTitle(), + ".popover-body": this._getContent() + } + } + _getContent() { + return this._resolvePossibleFunction(this._config.content) + } + static jQueryInterface(e) { + return this.each(function() { + var t = c.getOrCreateInstance(this, e); + if ("string" == typeof e) { + if (void 0 === t[e]) + throw new TypeError('No method named "'.concat(e, '"')); + t[e]() + } + }) + } + } + Object(s.a)(c); + n = c; + const u = "popover" + , h = [{ + name: "show" + }, { + name: "shown" + }, { + name: "hide" + }, { + name: "hidden" + }, { + name: "inserted" + }]; + class d extends n { + constructor(t, e) { + super(t, e), + this._init() + } + dispose() { + o.b.off(this.element, "show.bs.popover"), + o.b.off(this.element, "shown.bs.popover"), + o.b.off(this.element, "hide.bs.popover"), + o.b.off(this.element, "hidden.bs.popover"), + o.b.off(this.element, "inserted.bs.popover"), + super.dispose() + } + static get NAME() { + return u + } + _init() { + this._bindMdbEvents() + } + _bindMdbEvents() { + o.b.extend(this._element, h, u) + } + } + r.a.find('[data-mdb-toggle="popover"]').forEach(t=>{ + var e = d.getInstance(t); + e || new d(t) + } + ), + Object(i.i)(()=>{ + const t = Object(i.f)(); + if (t) { + const e = t.fn[u]; + t.fn[u] = d.jQueryInterface, + t.fn[u].Constructor = d, + t.fn[u].noConflict = ()=>(t.fn[u] = e, + d.jQueryInterface) + } + } + ); + e.a = d + } + , function(t, e, n) { + "use strict"; + var i = n(3) + , o = n(1) + , r = n(2) + , s = n(0) + , a = (n(11), + n(12), + n(4)) + , l = n(6) + , c = n(8) + , n = n(21); + var u = ".".concat("bs.scrollspy"); + const h = "activate".concat(u) + , d = "click".concat(u); + "load".concat(u).concat(".data-api"); + const p = "active"; + const f = "[href]"; + const g = "".concat(".nav-link", ", ").concat(".nav-item", " > ").concat(".nav-link", ", ").concat(".list-group-item") + , m = { + offset: null, + rootMargin: "0px 0px -25%", + smoothScroll: !1, + target: null, + threshold: [.1, .5, 1] + } + , b = { + offset: "(number|null)", + rootMargin: "string", + smoothScroll: "boolean", + target: "element", + threshold: "array" + }; + class v extends n.a { + constructor(t, e) { + super(t, e), + this._config.target && (this._targetLinks = new Map, + this._observableSections = new Map, + this._rootElement = "visible" === getComputedStyle(this._element).overflowY ? null : this._element, + this._activeTarget = null, + this._observer = null, + this._previousScrollData = { + visibleEntryTop: 0, + parentScrollTop: 0 + }, + this.refresh()) + } + static get Default() { + return m + } + static get DefaultType() { + return b + } + static get NAME() { + return "scrollspy" + } + refresh() { + this._initializeTargetsAndObservables(), + this._maybeEnableSmoothScroll(), + this._observer ? this._observer.disconnect() : this._observer = this._getNewObserver(); + for (const t of this._observableSections.values()) + this._observer.observe(t) + } + dispose() { + this._observer && this._observer.disconnect(), + super.dispose() + } + _configAfterMerge(t) { + return t.target = Object(a.e)(t.target) || document.body, + t.rootMargin = t.offset ? "".concat(t.offset, "px 0px -30%") : t.rootMargin, + "string" == typeof t.threshold && (t.threshold = t.threshold.split(",").map(t=>Number.parseFloat(t))), + t + } + _maybeEnableSmoothScroll() { + this._config.smoothScroll && (l.a.off(this._config.target, d), + l.a.on(this._config.target, d, f, t=>{ + var e = this._observableSections.get(t.target.hash); + e && (t.preventDefault(), + t = this._rootElement || window, + e = e.offsetTop - this._element.offsetTop, + t.scrollTo ? t.scrollTo({ + top: e, + behavior: "smooth" + }) : t.scrollTop = e) + } + )) + } + _getNewObserver() { + var t = { + root: this._rootElement, + threshold: this._config.threshold, + rootMargin: this._config.rootMargin + }; + return new IntersectionObserver(t=>this._observerCallback(t),t) + } + _observerCallback(t) { + const e = t=>this._targetLinks.get("#".concat(t.target.id)); + var n = t=>{ + this._previousScrollData.visibleEntryTop = t.target.offsetTop, + this._process(e(t)) + } + , i = (this._rootElement || document.documentElement).scrollTop + , o = i >= this._previousScrollData.parentScrollTop; + this._previousScrollData.parentScrollTop = i; + for (const s of t) + if (s.isIntersecting) { + var r = s.target.offsetTop >= this._previousScrollData.visibleEntryTop; + if (o && r) { + if (n(s), + i) + continue; + return + } + o || r || n(s) + } else + this._activeTarget = null, + this._clearActiveClass(e(s)) + } + _initializeTargetsAndObservables() { + var t; + this._targetLinks = new Map, + this._observableSections = new Map; + for (const e of c.a.find(f, this._config.target)) + e.hash && !Object(a.k)(e) && (t = c.a.findOne(e.hash, this._element), + Object(a.n)(t)) && (this._targetLinks.set(e.hash, e), + this._observableSections.set(e.hash, t)) + } + _process(t) { + this._activeTarget !== t && (this._clearActiveClass(this._config.target), + (this._activeTarget = t).classList.add(p), + this._activateParents(t), + l.a.trigger(this._element, h, { + relatedTarget: t + })) + } + _activateParents(t) { + if (t.classList.contains("dropdown-item")) + c.a.findOne(".dropdown-toggle", t.closest(".dropdown")).classList.add(p); + else + for (const e of c.a.parents(t, ".nav, .list-group")) + for (const n of c.a.prev(e, g)) + n.classList.add(p) + } + _clearActiveClass(t) { + t.classList.remove(p); + for (const e of c.a.find("".concat(f, ".").concat(p), t)) + e.classList.remove(p) + } + static jQueryInterface(e) { + return this.each(function() { + var t = v.getOrCreateInstance(this, e); + if ("string" == typeof e) { + if (void 0 === t[e] || e.startsWith("_") || "constructor" === e) + throw new TypeError('No method named "'.concat(e, '"')); + t[e]() + } + }) + } + } + Object(a.a)(v); + u = v; + const _ = "scrollspy"; + n = "mdb.".concat(_), + n = ".".concat(n); + const y = "activate.bs.scrollspy" + , w = "activate".concat(n); + n = "load".concat(n).concat(".data-api"); + const O = "collapsible-scrollspy"; + const x = ".".concat("active") + , S = ".".concat(O); + class C extends u { + constructor(t, e) { + super(t, e), + this._collapsibles = [], + this._init() + } + dispose() { + o.b.off(this._scrollElement, y), + super.dispose() + } + static get NAME() { + return _ + } + _init() { + this._bindActivateEvent(), + this._getCollapsibles(), + 0 !== this._collapsibles.length && (this._showSubsection(), + this._hideSubsection()) + } + _getHeight(t) { + return t.offsetHeight + } + _hide(t) { + t = r.a.findOne("ul", t.parentNode); + t.style.overflow = "hidden", + t.style.height = "".concat(0, "px") + } + _show(t, e) { + t.style.height = e + } + _getCollapsibles() { + var t = r.a.find(S); + t && t.forEach(t=>{ + var e = t.parentNode + , e = r.a.findOne("ul", e) + , n = e.offsetHeight; + this._collapsibles.push({ + element: e, + relatedTarget: t.getAttribute("href"), + height: "".concat(n, "px") + }) + } + ) + } + _showSubsection() { + r.a.find(x).filter(t=>s.a.hasClass(t, O)).forEach(e=>{ + var t = r.a.findOne("ul", e.parentNode) + , n = this._collapsibles.find(t=>t.relatedTarget = e.getAttribute("href")).height; + this._show(t, n) + } + ) + } + _hideSubsection() { + r.a.find(S).filter(t=>!1 === s.a.hasClass(t, "active")).forEach(t=>{ + this._hide(t) + } + ) + } + _bindActivateEvent() { + o.b.on(this._element, y, t=>{ + this._showSubsection(), + this._hideSubsection(), + o.b.trigger(this._element, w, { + relatedTarget: t.relatedTarget + }) + } + ) + } + } + o.b.on(window, n, ()=>{ + r.a.find('[data-mdb-spy="scroll"]').forEach(t=>{ + var e = C.getInstance(t); + e || new C(t,s.a.getDataAttributes(t)) + } + ) + } + ), + Object(i.i)(()=>{ + const t = Object(i.f)(); + if (t) { + const e = t.fn[_]; + t.fn[_] = C.jQueryInterface, + t.fn[_].Constructor = C, + t.fn[_].noConflict = ()=>(t.fn[_] = e, + C.jQueryInterface) + } + } + ); + e.a = C + } + , function(t, e, n) { + "use strict"; + var i = n(3) + , s = n(1) + , o = n(2) + , r = (n(28), + n(11), + n(12), + n(4)) + , a = n(6) + , l = n(8) + , n = n(21); + var c = ".".concat("bs.tab"); + const u = "hide".concat(c) + , h = "hidden".concat(c) + , d = "show".concat(c) + , p = "shown".concat(c); + var f = "click".concat(c); + const g = "keydown".concat(c); + c = "load".concat(c); + const m = "ArrowRight" + , b = "active"; + var v = ":not(.dropdown-toggle)"; + var v = ".nav-link".concat(v, ", .list-group-item").concat(v, ', [role="tab"]').concat(v) + , _ = '[data-mdb-toggle="tab"], [data-mdb-toggle="pill"], [data-mdb-toggle="list"]'; + const y = "".concat(v, ", ").concat(_) + , w = ".".concat(b, '[data-mdb-toggle="tab"], .').concat(b, '[data-mdb-toggle="pill"], .').concat(b, '[data-mdb-toggle="list"]'); + class O extends n.a { + constructor(t) { + super(t), + this._parent = this._element.closest('.list-group, .nav, [role="tablist"]'), + this._parent && (this._setInitialAttributes(this._parent, this._getChildren()), + a.a.on(this._element, g, t=>this._keydown(t))) + } + static get NAME() { + return "tab" + } + show() { + var t, e, n = this._element; + this._elemIsActive(n) || (e = (t = this._getActiveElem()) ? a.a.trigger(t, u, { + relatedTarget: n + }) : null, + a.a.trigger(n, d, { + relatedTarget: t + }).defaultPrevented) || e && e.defaultPrevented || (this._deactivate(t, n), + this._activate(n, t)) + } + _activate(t, e) { + t && (t.classList.add(b), + this._activate(Object(r.f)(t)), + this._queueCallback(()=>{ + "tab" !== t.getAttribute("role") ? t.classList.add("show") : (t.removeAttribute("tabindex"), + t.setAttribute("aria-selected", !0), + this._toggleDropDown(t, !0), + a.a.trigger(t, p, { + relatedTarget: e + })) + } + , t, t.classList.contains("fade"))) + } + _deactivate(t, e) { + t && (t.classList.remove(b), + t.blur(), + this._deactivate(Object(r.f)(t)), + this._queueCallback(()=>{ + "tab" !== t.getAttribute("role") ? t.classList.remove("show") : (t.setAttribute("aria-selected", !1), + t.setAttribute("tabindex", "-1"), + this._toggleDropDown(t, !1), + a.a.trigger(t, h, { + relatedTarget: e + })) + } + , t, t.classList.contains("fade"))) + } + _keydown(t) { + var e; + ["ArrowLeft", m, "ArrowUp", "ArrowDown"].includes(t.key) && (t.stopPropagation(), + t.preventDefault(), + e = [m, "ArrowDown"].includes(t.key), + t = Object(r.g)(this._getChildren().filter(t=>!Object(r.k)(t)), t.target, e, !0)) && (t.focus({ + preventScroll: !0 + }), + O.getOrCreateInstance(t).show()) + } + _getChildren() { + return l.a.find(y, this._parent) + } + _getActiveElem() { + return this._getChildren().find(t=>this._elemIsActive(t)) || null + } + _setInitialAttributes(t, e) { + this._setAttributeIfNotExists(t, "role", "tablist"); + for (const n of e) + this._setInitialAttributesOnChild(n) + } + _setInitialAttributesOnChild(t) { + t = this._getInnerElement(t); + var e = this._elemIsActive(t) + , n = this._getOuterElement(t); + t.setAttribute("aria-selected", e), + n !== t && this._setAttributeIfNotExists(n, "role", "presentation"), + e || t.setAttribute("tabindex", "-1"), + this._setAttributeIfNotExists(t, "role", "tab"), + this._setInitialAttributesOnTargetPanel(t) + } + _setInitialAttributesOnTargetPanel(t) { + var e = Object(r.f)(t); + e && (this._setAttributeIfNotExists(e, "role", "tabpanel"), + t.id) && this._setAttributeIfNotExists(e, "aria-labelledby", "#".concat(t.id)) + } + _toggleDropDown(t, n) { + const i = this._getOuterElement(t); + i.classList.contains("dropdown") && ((t = (t,e)=>{ + t = l.a.findOne(t, i); + t && t.classList.toggle(e, n) + } + )(".dropdown-toggle", b), + t(".dropdown-menu", "show"), + i.setAttribute("aria-expanded", n)) + } + _setAttributeIfNotExists(t, e, n) { + t.hasAttribute(e) || t.setAttribute(e, n) + } + _elemIsActive(t) { + return t.classList.contains(b) + } + _getInnerElement(t) { + return t.matches(y) ? t : l.a.findOne(y, t) + } + _getOuterElement(t) { + return t.closest(".nav-item, .list-group-item") || t + } + static jQueryInterface(e) { + return this.each(function() { + var t = O.getOrCreateInstance(this); + if ("string" == typeof e) { + if (void 0 === t[e] || e.startsWith("_") || "constructor" === e) + throw new TypeError('No method named "'.concat(e, '"')); + t[e]() + } + }) + } + } + a.a.on(document, f, _, function(t) { + ["A", "AREA"].includes(this.tagName) && t.preventDefault(), + Object(r.k)(this) || O.getOrCreateInstance(this).show() + }), + a.a.on(window, c, ()=>{ + for (const t of l.a.find(w)) + O.getOrCreateInstance(t) + } + ), + Object(r.a)(O); + v = O; + const x = "tab"; + n = "mdb.".concat(x), + f = ".".concat(n); + const S = "show.bs.tab" + , C = "shown.bs.tab" + , E = "show".concat(f) + , k = "shown".concat(f) + , A = "hide".concat(f) + , j = "hidden".concat(f); + class T extends v { + dispose() { + s.b.off(this._element, S), + s.b.off(this._element, C), + super.dispose() + } + static get NAME() { + return x + } + show() { + var n = this._element; + if (!this._elemIsActive(n)) { + var i = this._getActiveElem(); + let t = null + , e = null; + i && (t = s.b.trigger(i, "hide.bs.tab", { + relatedTarget: n + }), + e = s.b.trigger(i, A, { + relatedTarget: n + })); + var o = s.b.trigger(n, S, { + relatedTarget: i + }) + , r = s.b.trigger(n, E, { + relatedTarget: i + }); + o.defaultPrevented || r.defaultPrevented || t && t.defaultPrevented || e && e.defaultPrevented || (this._deactivate(i, n), + this._activate(n, i)) + } + } + _activate(t, e) { + t && (t.classList.add("active"), + this._activate(Object(i.c)(t)), + this._queueCallback(()=>{ + "tab" !== t.getAttribute("role") ? t.classList.add("show") : (t.focus(), + t.removeAttribute("tabindex"), + t.setAttribute("aria-selected", !0), + this._toggleDropDown(t, !0), + s.b.trigger(t, C, { + relatedTarget: e + }), + s.b.trigger(t, k, { + relatedTarget: e + })) + } + , t, t.classList.contains("fade"))) + } + _deactivate(t, e) { + t && (t.classList.remove("active"), + t.blur(), + this._deactivate(Object(i.c)(t)), + this._queueCallback(()=>{ + "tab" !== t.getAttribute("role") ? t.classList.remove("show") : (t.setAttribute("aria-selected", !1), + t.setAttribute("tabindex", "-1"), + this._toggleDropDown(t, !1), + s.b.trigger(t, "hidden.bs.tab", { + relatedTarget: e + }), + s.b.trigger(t, j, { + relatedTarget: e + })) + } + , t, t.classList.contains("fade"))) + } + } + o.a.find('[data-mdb-toggle="tab"], [data-mdb-toggle="pill"], [data-mdb-toggle="list"]').forEach(t=>{ + var e = T.getInstance(t); + e || new T(t) + } + ), + Object(i.i)(()=>{ + const t = Object(i.f)(); + if (t) { + const e = t.fn.tab; + t.fn.tab = T.jQueryInterface, + t.fn.tab.Constructor = T, + t.fn.tab.noConflict = ()=>(t.fn.tab = e, + T.jQueryInterface) + } + } + ); + e.a = T + } + , function(D, t, e) { + "use strict"; + var n = e(3) + , i = e(1) + , o = e(2) + , r = e(0) + , s = (e(11), + e(12), + e(75), + e(28), + e(17), + e(71)) + , a = e(141) + , l = e(4) + , c = e(6) + , u = e(34) + , h = e(8) + , e = e(21); + var d = ".".concat("bs.dropdown") + , p = ".data-api"; + const f = "hide".concat(d) + , g = "hidden".concat(d) + , m = "show".concat(d) + , b = "shown".concat(d); + var v = "click".concat(d).concat(p) + , _ = "keydown".concat(d).concat(p) + , d = "keyup".concat(d).concat(p); + const y = "show" + , w = '[data-mdb-toggle="dropdown"]:not(.disabled):not(:disabled)' + , O = "".concat(w, ".").concat(y) + , x = ".dropdown-menu" + , S = Object(l.m)() ? "top-end" : "top-start" + , C = Object(l.m)() ? "top-start" : "top-end" + , N = Object(l.m)() ? "bottom-end" : "bottom-start" + , H = Object(l.m)() ? "bottom-start" : "bottom-end" + , B = Object(l.m)() ? "left-start" : "right-start" + , W = Object(l.m)() ? "right-start" : "left-start" + , Y = { + autoClose: !0, + boundary: "clippingParents", + display: "dynamic", + offset: [0, 2], + popperConfig: null, + reference: "toggle" + } + , F = { + autoClose: "(boolean|string)", + boundary: "(string|element)", + display: "string", + offset: "(array|string|function)", + popperConfig: "(null|object|function)", + reference: "(string|element|object)" + }; + class E extends e.a { + constructor(t, e) { + super(t, e), + this._popper = null, + this._parent = this._element.parentNode, + this._menu = h.a.next(this._element, x)[0] || h.a.prev(this._element, x)[0] || h.a.findOne(x, this._parent), + this._inNavbar = this._detectNavbar() + } + static get Default() { + return Y + } + static get DefaultType() { + return F + } + static get NAME() { + return "dropdown" + } + toggle() { + return this._isShown() ? this.hide() : this.show() + } + show() { + if (!Object(l.k)(this._element) && !this._isShown()) { + var t = { + relatedTarget: this._element + } + , e = c.a.trigger(this._element, m, t); + if (!e.defaultPrevented) { + if (this._createPopper(), + "ontouchstart"in document.documentElement && !this._parent.closest(".navbar-nav")) + for (const n of [].concat(...document.body.children)) + c.a.on(n, "mouseover", l.o); + this._element.focus(), + this._element.setAttribute("aria-expanded", !0), + this._menu.classList.add(y), + this._element.classList.add(y), + c.a.trigger(this._element, b, t) + } + } + } + hide() { + var t; + !Object(l.k)(this._element) && this._isShown() && (t = { + relatedTarget: this._element + }, + this._completeHide(t)) + } + dispose() { + this._popper && this._popper.destroy(), + super.dispose() + } + update() { + this._inNavbar = this._detectNavbar(), + this._popper && this._popper.update() + } + _completeHide(t) { + var e = c.a.trigger(this._element, f, t); + if (!e.defaultPrevented) { + if ("ontouchstart"in document.documentElement) + for (const n of [].concat(...document.body.children)) + c.a.off(n, "mouseover", l.o); + this._popper && this._popper.destroy(), + this._menu.classList.remove(y), + this._element.classList.remove(y), + this._element.setAttribute("aria-expanded", "false"), + u.a.removeDataAttribute(this._menu, "popper"), + c.a.trigger(this._element, g, t) + } + } + _getConfig(t) { + if ("object" != typeof (t = super._getConfig(t)).reference || Object(l.l)(t.reference) || "function" == typeof t.reference.getBoundingClientRect) + return t; + throw new TypeError("".concat("dropdown".toUpperCase(), ': Option "reference" provided type "object" without a required "getBoundingClientRect" method.')) + } + _createPopper() { + if (void 0 === s) + throw new TypeError("Bootstrap's dropdowns require Popper (https://popper.js.org)"); + let t = this._element; + "parent" === this._config.reference ? t = this._parent : Object(l.l)(this._config.reference) ? t = Object(l.e)(this._config.reference) : "object" == typeof this._config.reference && (t = this._config.reference); + var e = this._getPopperConfig(); + this._popper = a.a(t, this._menu, e) + } + _isShown() { + return this._menu.classList.contains(y) + } + _getPlacement() { + var t, e = this._parent; + return e.classList.contains("dropend") ? B : e.classList.contains("dropstart") ? W : e.classList.contains("dropup-center") ? "top" : e.classList.contains("dropdown-center") ? "bottom" : (t = "end" === getComputedStyle(this._menu).getPropertyValue("--mdb-position").trim(), + e.classList.contains("dropup") ? t ? C : S : t ? H : N) + } + _detectNavbar() { + return null !== this._element.closest(".navbar") + } + _getOffset() { + const e = this._config["offset"]; + return "string" == typeof e ? e.split(",").map(t=>Number.parseInt(t, 10)) : "function" == typeof e ? t=>e(t, this._element) : e + } + _getPopperConfig() { + var t = { + placement: this._getPlacement(), + modifiers: [{ + name: "preventOverflow", + options: { + boundary: this._config.boundary + } + }, { + name: "offset", + options: { + offset: this._getOffset() + } + }] + }; + return !this._inNavbar && "static" !== this._config.display || (u.a.setDataAttribute(this._menu, "popper", "static"), + t.modifiers = [{ + name: "applyStyles", + enabled: !1 + }]), + { + ...t, + ..."function" == typeof this._config.popperConfig ? this._config.popperConfig(t) : this._config.popperConfig + } + } + _selectMenuItem(t) { + var {key: t, target: e} = t + , n = h.a.find(".dropdown-menu .dropdown-item:not(.disabled):not(:disabled)", this._menu).filter(t=>Object(l.n)(t)); + n.length && Object(l.g)(n, e, "ArrowDown" === t, !n.includes(e)).focus() + } + static jQueryInterface(e) { + return this.each(function() { + var t = E.getOrCreateInstance(this, e); + if ("string" == typeof e) { + if (void 0 === t[e]) + throw new TypeError('No method named "'.concat(e, '"')); + t[e]() + } + }) + } + static clearMenus(t) { + if (2 !== t.button && ("keyup" !== t.type || "Tab" === t.key)) + for (const o of h.a.find(O)) { + var e, n, i = E.getInstance(o); + i && !1 !== i._config.autoClose && (e = (n = t.composedPath()).includes(i._menu), + n.includes(i._element) || "inside" === i._config.autoClose && !e || "outside" === i._config.autoClose && e || i._menu.contains(t.target) && ("keyup" === t.type && "Tab" === t.key || /input|select|option|textarea|form/i.test(t.target.tagName)) || (n = { + relatedTarget: i._element + }, + "click" === t.type && (n.clickEvent = t), + i._completeHide(n))) + } + } + static dataApiKeydownHandler(t) { + var e = /input|textarea/i.test(t.target.tagName) + , n = "Escape" === t.key + , i = ["ArrowUp", "ArrowDown"].includes(t.key); + !i && !n || e && !n || (t.preventDefault(), + e = this.matches(w) ? this : h.a.prev(this, w)[0] || h.a.next(this, w)[0] || h.a.findOne(w, t.delegateTarget.parentNode), + n = E.getOrCreateInstance(e), + i ? (t.stopPropagation(), + n.show(), + n._selectMenuItem(t)) : n._isShown() && (t.stopPropagation(), + n.hide(), + e.focus())) + } + } + c.a.on(document, _, w, E.dataApiKeydownHandler), + c.a.on(document, _, x, E.dataApiKeydownHandler), + c.a.on(document, v, E.clearMenus), + c.a.on(document, d, E.clearMenus), + c.a.on(document, v, w, function(t) { + t.preventDefault(), + E.getOrCreateInstance(this).toggle() + }), + Object(l.a)(E); + p = E; + const k = "dropdown"; + e = "mdb.".concat(k), + _ = ".".concat(e); + const X = { + offset: [0, 2], + flip: !0, + boundary: "clippingParents", + reference: "toggle", + display: "dynamic", + popperConfig: null, + dropdownAnimation: "on" + } + , z = { + offset: "(array|string|function)", + flip: "boolean", + boundary: "(string|element)", + reference: "(string|element|object)", + display: "string", + popperConfig: "(null|object|function)", + dropdownAnimation: "string" + } + , A = "hide.bs.dropdown" + , j = "hidden.bs.dropdown" + , T = "show.bs.dropdown" + , L = "shown.bs.dropdown" + , U = "hide".concat(_) + , q = "hidden".concat(_) + , $ = "show".concat(_) + , V = "shown".concat(_) + , P = "animation" + , R = "fade-in" + , M = "fade-out"; + class I extends p { + constructor(t, e) { + super(t, e), + this._config = this._getConfig(e), + this._menuStyle = "", + this._popperPlacement = "", + this._mdbPopperConfig = ""; + t = window.matchMedia("(prefers-reduced-motion: reduce)").matches; + "on" !== this._config.dropdownAnimation || t || this._init() + } + dispose() { + i.b.off(this._element, T), + i.b.off(this._parent, L), + i.b.off(this._parent, A), + i.b.off(this._parent, j), + super.dispose() + } + static get NAME() { + return k + } + _init() { + this._bindShowEvent(), + this._bindShownEvent(), + this._bindHideEvent(), + this._bindHiddenEvent() + } + _getConfig(t) { + t = { + ...X, + ...r.a.getDataAttributes(this._element), + ...t + }; + return Object(n.j)(k, t, z), + t + } + _getOffset() { + const e = this._config["offset"]; + return "string" == typeof e ? e.split(",").map(t=>Number.parseInt(t, 10)) : "function" == typeof e ? t=>e(t, this._element) : e + } + _getPopperConfig() { + var t = { + placement: this._getPlacement(), + modifiers: [{ + name: "preventOverflow", + options: { + altBoundary: this._config.flip, + boundary: this._config.boundary + } + }, { + name: "offset", + options: { + offset: this._getOffset() + } + }] + }; + return "static" === this._config.display && (r.a.setDataAttribute(this._menu, "popper", "static"), + t.modifiers = [{ + name: "applyStyles", + enabled: !1 + }]), + { + ...t, + ..."function" == typeof this._config.popperConfig ? this._config.popperConfig(t) : this._config.popperConfig + } + } + _bindShowEvent() { + i.b.on(this._element, T, t=>{ + i.b.trigger(this._element, $, { + relatedTarget: t.relatedTarget + }).defaultPrevented ? t.preventDefault() : this._dropdownAnimationStart("show") + } + ) + } + _bindShownEvent() { + i.b.on(this._parent, L, t=>{ + i.b.trigger(this._parent, V, { + relatedTarget: t.relatedTarget + }).defaultPrevented && t.preventDefault() + } + ) + } + _bindHideEvent() { + i.b.on(this._parent, A, t=>{ + i.b.trigger(this._parent, U, { + relatedTarget: t.relatedTarget + }).defaultPrevented ? t.preventDefault() : (this._menuStyle = this._menu.style.cssText, + this._popperPlacement = this._menu.getAttribute("data-popper-placement"), + this._mdbPopperConfig = this._menu.getAttribute("data-mdb-popper")) + } + ) + } + _bindHiddenEvent() { + i.b.on(this._parent, j, t=>{ + i.b.trigger(this._parent, q, { + relatedTarget: t.relatedTarget + }).defaultPrevented ? t.preventDefault() : ("static" !== this._config.display && "" !== this._menuStyle && (this._menu.style.cssText = this._menuStyle), + this._menu.setAttribute("data-popper-placement", this._popperPlacement), + this._menu.setAttribute("data-mdb-popper", this._mdbPopperConfig), + this._dropdownAnimationStart("hide")) + } + ) + } + _dropdownAnimationStart(t) { + "show" === t ? (this._menu.classList.add(P, R), + this._menu.classList.remove(M)) : (this._menu.classList.add(P, M), + this._menu.classList.remove(R)), + this._bindAnimationEnd() + } + _bindAnimationEnd() { + i.b.one(this._menu, "animationend", ()=>{ + this._menu.classList.remove(P, M, R) + } + ) + } + } + o.a.find('[data-mdb-toggle="dropdown"]').forEach(t=>{ + var e = I.getInstance(t); + e || new I(t) + } + ), + Object(n.i)(()=>{ + const t = Object(n.f)(); + if (t) { + const e = t.fn[k]; + t.fn[k] = I.jQueryInterface, + t.fn[k].Constructor = I, + t.fn[k].noConflict = ()=>(t.fn[k] = e, + I.jQueryInterface) + } + } + ); + t.a = I + } + , function(t, e, n) { + "use strict"; + n(11), + n(12), + n(28); + var i = n(3) + , o = n(1) + , r = n(0) + , s = n(2) + , a = n(4) + , l = n(6) + , c = n(21) + , u = n(54); + var h = ".".concat("bs.alert"); + const d = "close".concat(h) + , p = "closed".concat(h); + class f extends c.a { + static get NAME() { + return "alert" + } + close() { + var t; + l.a.trigger(this._element, d).defaultPrevented || (this._element.classList.remove("show"), + t = this._element.classList.contains("fade"), + this._queueCallback(()=>this._destroyElement(), this._element, t)) + } + _destroyElement() { + this._element.remove(), + l.a.trigger(this._element, p), + this.dispose() + } + static jQueryInterface(e) { + return this.each(function() { + var t = f.getOrCreateInstance(this); + if ("string" == typeof e) { + if (void 0 === t[e] || e.startsWith("_") || "constructor" === e) + throw new TypeError('No method named "'.concat(e, '"')); + t[e](this) + } + }) + } + } + Object(u.a)(f, "close"), + Object(a.a)(f); + var h = f + , g = n(109); + const m = "alert" + , b = { + position: "(string || null)", + delay: "number", + autohide: "boolean", + width: "(string || null)", + offset: "number", + stacking: "boolean", + hidden: "boolean", + appendToBody: "boolean", + color: "(string || null)", + container: "(string|null)" + } + , v = { + position: null, + delay: 1e3, + autohide: !1, + width: null, + offset: 10, + stacking: !1, + hidden: !1, + appendToBody: !1, + color: null, + container: null + } + , _ = [{ + name: "close" + }, { + name: "closed" + }]; + class y extends h { + constructor(t) { + var e = 1 < arguments.length && void 0 !== arguments[1] ? arguments[1] : {}; + super(t, e), + this._options = this._getConfig(e), + this._init() + } + dispose() { + o.b.off(this._element, "close.bs.alert"), + o.b.off(this._element, "closed.bs.alert"), + super.dispose() + } + get verticalOffset() { + return this._options.stacking ? this.stackUtil.calculateOffset() : 0 + } + get parent() { + var [t] = s.a.parents(this._element, this._options.container); + return t + } + get position() { + var [t,e] = this._options.position.split("-"); + return { + y: t, + x: e + } + } + update() { + var t = 0 < arguments.length && void 0 !== arguments[0] ? arguments[0] : {}; + null !== this._timeout && (clearTimeout(this._timeout), + this._timeout = null), + this._options = this._getConfig(t), + this._setup() + } + hide() { + if (this._element && this._element.classList.contains("show")) { + r.a.toggleClass(this._element, "show"); + const e = t=>{ + r.a.style(t.target, { + display: "none" + }), + null !== this._timeout && (clearTimeout(this._timeout), + this._timeout = null), + this._options.stacking && this._updateAlertStack(), + o.b.off(t.target, "transitionend", e) + } + ; + o.b.on(this._element, "transitionend", e) + } + } + show() { + if (this._options.autohide && this._setupAutohide(), + !this._element.classList.contains("show") && (r.a.style(this._element, { + display: "block" + }), + Object(i.h)(this._element))) { + const e = t=>{ + r.a.style(t.target, { + display: "block" + }), + o.b.off(t.target, "transitionend", e) + } + ; + r.a.toggleClass(this._element, "show"), + this._options.position && this._setupAlignment(), + o.b.on(this._element, "transitionend", e) + } + } + _init() { + this._options.hidden && r.a.style(this._element, { + display: "none" + }), + this._bindMdbEvents(), + this._setup() + } + _setup() { + this._options.color && this._setColor(), + this._options.stacking && this._setupStacking(), + this._options.autohide && this._setupAutohide(), + this._options.width && this._setupWidth(), + this._options.appendToBody && this._appendToBody(), + this._options.position && (this._setupAlignment(), + this._setupPosition()) + } + _setupStacking() { + this.stackUtil = new g.a(this._element,".alert",{ + position: this.position.y, + offset: this._options.offset, + container: this._options.container, + filter: t=>{ + t = y.getInstance(t); + return !!t && t._options.container === this._options.container && t._options.position === this._options.position + } + }), + o.b.on(this._element, "closed.bs.alert", ()=>{ + this._updateAlertStack() + } + ) + } + _setColor() { + var t = ["primary", "secondary", "success", "info", "warning", "danger", "light", "dark"] + , e = t.includes(this._options.color) ? this._options.color : "primary"; + t.forEach(t=>{ + this._element.classList.remove("alert-".concat(t)) + } + ), + r.a.addClass(this._element, "alert-".concat(e)) + } + _setupWidth() { + r.a.style(this._element, { + width: this._options.width + }) + } + _setupAutohide() { + this._timeout = setTimeout(()=>{ + this.hide() + } + , this._options.delay) + } + _setupAlignment() { + var t = "top" === this.position.y ? "bottom" : "top" + , e = "left" === this.position.x ? "right" : "left"; + "center" === this.position.x ? r.a.style(this._element, { + [this.position.y]: "".concat(this.verticalOffset + this._options.offset, "px"), + [t]: "unset", + left: "50%", + transform: "translate(-50%)" + }) : r.a.style(this._element, { + [this.position.y]: "".concat(this.verticalOffset + this._options.offset, "px"), + [this.position.x]: "".concat(this._options.offset, "px"), + [t]: "unset", + [e]: "unset", + transform: "unset" + }) + } + _setupPosition() { + this._options.container ? (r.a.addClass(this.parent, "parent-alert-relative"), + r.a.addClass(this._element, "alert-absolute")) : r.a.addClass(this._element, "alert-fixed") + } + _appendToBody() { + this._element.parentNode.removeChild(this._element), + document.body.appendChild(this._element) + } + _getConfig(t) { + t = { + ...v, + ...r.a.getDataAttributes(this._element), + ...t + }; + return Object(i.j)(m, t, b), + t + } + _bindMdbEvents() { + o.b.extend(this._element, _, m) + } + _updatePosition() { + r.a.style(this._element, { + [this.position.y]: "".concat(this.verticalOffset + this._options.offset, "px") + }) + } + _updateAlertStack() { + this.stackUtil.nextElements.forEach(t=>{ + t = y.getInstance(t); + t && t._updatePosition() + } + ) + } + } + s.a.find(".alert").forEach(t=>{ + let e = y.getInstance(t); + return e = e || new y(t) + } + ), + Object(i.i)(()=>{ + const t = Object(i.f)(); + if (t) { + const e = t.fn[m]; + t.fn[m] = y.jQueryInterface, + t.fn[m].Constructor = y, + t.fn[m].noConflict = ()=>(t.fn[m] = e, + y.jQueryInterface) + } + } + ); + e.a = y + } + , function(t, e, n) { + "use strict"; + n(11), + n(12), + n(28); + var i = n(3) + , o = n(1) + , r = n(0) + , s = n(2) + , a = n(4) + , l = n(6) + , c = n(21) + , u = n(54); + var h = ".".concat("bs.toast"); + const d = "mouseover".concat(h) + , p = "mouseout".concat(h) + , f = "focusin".concat(h) + , g = "focusout".concat(h) + , m = "hide".concat(h) + , b = "hidden".concat(h) + , v = "show".concat(h) + , _ = "shown".concat(h) + , y = "show" + , w = "showing" + , O = { + animation: "boolean", + autohide: "boolean", + delay: "number" + } + , x = { + animation: !0, + autohide: !0, + delay: 5e3 + }; + class S extends c.a { + constructor(t, e) { + super(t, e), + this._timeout = null, + this._hasMouseInteraction = !1, + this._hasKeyboardInteraction = !1, + this._setListeners() + } + static get Default() { + return x + } + static get DefaultType() { + return O + } + static get NAME() { + return "toast" + } + show() { + l.a.trigger(this._element, v).defaultPrevented || (this._clearTimeout(), + this._config.animation && this._element.classList.add("fade"), + this._element.classList.remove("hide"), + Object(a.p)(this._element), + this._element.classList.add(y, w), + this._queueCallback(()=>{ + this._element.classList.remove(w), + l.a.trigger(this._element, _), + this._maybeScheduleHide() + } + , this._element, this._config.animation)) + } + hide() { + this.isShown() && !l.a.trigger(this._element, m).defaultPrevented && (this._element.classList.add(w), + this._queueCallback(()=>{ + this._element.classList.add("hide"), + this._element.classList.remove(w, y), + l.a.trigger(this._element, b) + } + , this._element, this._config.animation)) + } + dispose() { + this._clearTimeout(), + this.isShown() && this._element.classList.remove(y), + super.dispose() + } + isShown() { + return this._element.classList.contains(y) + } + _maybeScheduleHide() { + !this._config.autohide || this._hasMouseInteraction || this._hasKeyboardInteraction || (this._timeout = setTimeout(()=>{ + this.hide() + } + , this._config.delay)) + } + _onInteraction(t, e) { + switch (t.type) { + case "mouseover": + case "mouseout": + this._hasMouseInteraction = e; + break; + case "focusin": + case "focusout": + this._hasKeyboardInteraction = e + } + e ? this._clearTimeout() : (t = t.relatedTarget, + this._element === t || this._element.contains(t) || this._maybeScheduleHide()) + } + _setListeners() { + l.a.on(this._element, d, t=>this._onInteraction(t, !0)), + l.a.on(this._element, p, t=>this._onInteraction(t, !1)), + l.a.on(this._element, f, t=>this._onInteraction(t, !0)), + l.a.on(this._element, g, t=>this._onInteraction(t, !1)) + } + _clearTimeout() { + clearTimeout(this._timeout), + this._timeout = null + } + static jQueryInterface(e) { + return this.each(function() { + var t = S.getOrCreateInstance(this, e); + if ("string" == typeof e) { + if (void 0 === t[e]) + throw new TypeError('No method named "'.concat(e, '"')); + t[e](this) + } + }) + } + } + Object(u.a)(S), + Object(a.a)(S); + var h = S + , C = n(109); + const E = "toast" + , k = "show.bs.toast" + , A = "hidden.bs.toast" + , j = [{ + name: "shown" + }, { + name: "hide" + }] + , T = { + position: "(string|null)", + animation: "boolean", + autohide: "boolean", + width: "(string || null)", + color: "(string|null)", + delay: "(boolean|number)", + offset: "number", + appendToBody: "boolean", + stacking: "boolean" + } + , L = { + position: null, + animation: !0, + autohide: !0, + width: null, + color: null, + delay: 500, + offset: 10, + appendToBody: !1, + stacking: !0 + }; + class P extends h { + constructor(t) { + var e = 1 < arguments.length && void 0 !== arguments[1] ? arguments[1] : {}; + super(t, e), + this._config = this._getConfig(e), + this._setup() + } + get parent() { + var [t] = s.a.parents(this._element, this._config.container); + return t + } + get position() { + var t, e; + return this._config.position ? ([t,e] = this._config.position.split("-"), + { + y: t, + x: e + }) : null + } + get verticalOffset() { + return this._config.stacking && this.position ? this.stackUtil.calculateOffset() : 0 + } + update() { + this._config = this._getConfig(0 < arguments.length && void 0 !== arguments[0] ? arguments[0] : {}), + this._setupColor(), + this._config.position && (this._config.stacking && (this._setupStacking(), + o.b.on(this._element, "hidden.bs.toast", ()=>{ + setTimeout(()=>this._updateToastStack(), 150) + } + )), + this._setupPosition(), + this._setupAlignment()) + } + dispose() { + o.b.off(this._element, k), + o.b.off(this._element, "shown.bs.toast"), + o.b.off(this._element, "hide.bs.toast"), + o.b.off(this._element, A), + super.dispose() + } + _setup() { + this._setupColor(), + this._config.width && this._setupWidth(), + this._config.position && (this._config.stacking && (this._setupStacking(), + o.b.on(this._element, "hidden.bs.toast", ()=>{ + setTimeout(()=>this._updateToastStack(), 150) + } + )), + this._setupPosition(), + this._setupDisplay(), + !this._config.container && this._config.appendToBody && this._appendToBody(), + this._bindMdbEvents()) + } + _setupStacking() { + this.stackUtil = new C.a(this._element,".toast",{ + position: this.position.y, + offset: this._config.offset, + container: this._config.container, + filter: t=>{ + t = P.getInstance(t); + return !!t && t._config.container === this._config.container && t._config.position === this._config.position + } + }), + o.b.on(this._element, "closed.bs.alert", ()=>{ + this._updateAlertStack() + } + ) + } + _setupColor() { + if (this._config.color) { + const n = s.a.findOne(".toast-header", this._element); + var t = ["primary", "secondary", "success", "info", "warning", "danger", "light", "dark"] + , e = t.includes(this._config.color) ? this._config.color : "primary"; + t.forEach(t=>{ + this._element.classList.remove("toast-".concat(t)), + n && n.classList.remove("toast-".concat(t)) + } + ), + r.a.addClass(this._element, "toast-".concat(e)), + n && r.a.addClass(n, "toast-".concat(e)) + } + } + _setupWidth() { + r.a.style(this._element, { + width: this._config.width + }) + } + _setupPosition() { + this._config.container ? (r.a.addClass(this.parent, "parent-toast-relative"), + r.a.addClass(this._element, "toast-absolute")) : r.a.addClass(this._element, "toast-fixed") + } + _setupAlignment() { + var t = "top" === this.position.y ? "bottom" : "top" + , e = "left" === this.position.x ? "right" : "left"; + "center" === this.position.x ? r.a.style(this._element, { + [this.position.y]: "".concat(this.verticalOffset + this._config.offset, "px"), + [t]: "unset", + left: "50%", + transform: "translate(-50%)" + }) : r.a.style(this._element, { + [this.position.y]: "".concat(this.verticalOffset + this._config.offset, "px"), + [this.position.x]: "".concat(this._config.offset, "px"), + [t]: "unset", + [e]: "unset", + transform: "unset" + }) + } + _setupDisplay() { + this._element.classList.contains("show") || r.a.style(this._element, { + display: "none" + }), + o.b.on(this._element, A, ()=>{ + o.b.trigger(this._element, "hidden.mdb.toast"), + r.a.style(this._element, { + display: "none" + }) + } + ), + o.b.on(this._element, k, ()=>{ + o.b.trigger(this._element, "show.mdb.toast").defaultPrevented || (this._setupAlignment(), + r.a.style(this._element, { + display: "block" + })) + } + ) + } + _bindMdbEvents() { + o.b.extend(this._element, j, E) + } + _getConfig(t) { + t = { + ...L, + ...r.a.getDataAttributes(this._element), + ...t + }; + return Object(i.j)(E, t, T), + t + } + _appendToBody() { + this._element.parentNode.removeChild(this._element), + document.body.appendChild(this._element) + } + _updatePosition() { + r.a.style(this._element, { + [this.position.y]: "".concat(this.verticalOffset + this._config.offset, "px") + }) + } + _updateToastStack() { + this.stackUtil.nextElements.forEach(t=>{ + t = P.getInstance(t); + t && t._updatePosition() + } + ) + } + static jQueryInterface(e) { + let n = 1 < arguments.length && void 0 !== arguments[1] ? arguments[1] : {}; + return this.each(function() { + let t; + if (t = "object" == typeof e ? new P(this,e) : P.getOrCreateInstance(this, e), + "string" == typeof e) { + if (void 0 === t[e]) + throw new TypeError('No method named "'.concat(e, '"')); + t[e](n) + } + }) + } + } + s.a.find(".toast").forEach(t=>{ + let e = P.getInstance(t); + return e = e || new P(t) + } + ), + Object(i.i)(()=>{ + const t = Object(i.f)(); + if (t) { + const e = t.fn[E]; + t.fn[E] = P.jQueryInterface, + t.fn[E].Constructor = P, + t.fn[E].noConflict = ()=>(t.fn[E] = e, + P.jQueryInterface) + } + } + ); + e.a = P + } + , function(D, t, e) { + "use strict"; + e(17); + /*! + * perfect-scrollbar v1.5.3 + * Copyright 2021 Hyunje Jun, MDBootstrap and Contributors + * Licensed under MIT + */ + function p(t) { + return getComputedStyle(t) + } + function l(t, e) { + for (var n in e) { + var i = e[n]; + "number" == typeof i && (i += "px"), + t.style[n] = i + } + } + function c(t) { + var e = document.createElement("div"); + return e.className = t, + e + } + var n = "undefined" != typeof Element && (Element.prototype.matches || Element.prototype.webkitMatchesSelector || Element.prototype.mozMatchesSelector || Element.prototype.msMatchesSelector); + function a(t, e) { + if (n) + return n.call(t, e); + throw new Error("No element matching method supported") + } + function s(t) { + t.remove ? t.remove() : t.parentNode && t.parentNode.removeChild(t) + } + function u(t, e) { + return Array.prototype.filter.call(t.children, function(t) { + return a(t, e) + }) + } + var v = { + main: "ps", + rtl: "ps__rtl", + element: { + thumb: function(t) { + return "ps__thumb-" + t + }, + rail: function(t) { + return "ps__rail-" + t + }, + consuming: "ps__child--consume" + }, + state: { + focus: "ps--focus", + clicking: "ps--clicking", + active: function(t) { + return "ps--active-" + t + }, + scrolling: function(t) { + return "ps--scrolling-" + t + } + } + } + , i = { + x: null, + y: null + }; + function _(t, e) { + var t = t.element.classList + , n = v.state.scrolling(e); + t.contains(n) ? clearTimeout(i[e]) : t.add(n) + } + function y(t, e) { + i[e] = setTimeout(function() { + return t.isAlive && t.element.classList.remove(v.state.scrolling(e)) + }, t.settings.scrollingThreshold) + } + function o(t) { + this.element = t, + this.handlers = {} + } + function h() { + this.eventElements = [] + } + var r = { + isEmpty: { + configurable: !0 + } + }; + o.prototype.bind = function(t, e) { + void 0 === this.handlers[t] && (this.handlers[t] = []), + this.handlers[t].push(e), + this.element.addEventListener(t, e, !1) + } + , + o.prototype.unbind = function(e, n) { + var i = this; + this.handlers[e] = this.handlers[e].filter(function(t) { + return !(!n || t === n) || (i.element.removeEventListener(e, t, !1), + !1) + }) + } + , + o.prototype.unbindAll = function() { + for (var t in this.handlers) + this.unbind(t) + } + , + r.isEmpty.get = function() { + var e = this; + return Object.keys(this.handlers).every(function(t) { + return 0 === e.handlers[t].length + }) + } + , + Object.defineProperties(o.prototype, r); + function d(t) { + var e; + return "function" == typeof window.CustomEvent ? new CustomEvent(t) : ((e = document.createEvent("CustomEvent")).initCustomEvent(t, !1, !1, void 0), + e) + } + function f(t, e, n, i, o) { + var r; + if (void 0 === i && (i = !0), + void 0 === o && (o = !1), + "top" === e) + r = ["contentHeight", "containerHeight", "scrollTop", "y", "up", "down"]; + else { + if ("left" !== e) + throw new Error("A proper axis should be provided"); + r = ["contentWidth", "containerWidth", "scrollLeft", "x", "left", "right"] + } + var e = t + , t = n + , n = i + , i = o + , s = (o = r)[0] + , a = o[1] + , l = o[2] + , c = o[3] + , u = o[4] + , o = o[5] + , h = (void 0 === n && (n = !0), + void 0 === i && (i = !1), + e.element); + e.reach[c] = null, + h[l] < 1 && (e.reach[c] = "start"), + h[l] > e[s] - e[a] - 1 && (e.reach[c] = "end"), + t && (h.dispatchEvent(d("ps-scroll-" + c)), + t < 0 ? h.dispatchEvent(d("ps-scroll-" + u)) : 0 < t && h.dispatchEvent(d("ps-scroll-" + o)), + n) && (_(l = e, s = c), + y(l, s)); + e.reach[c] && (t || i) && h.dispatchEvent(d("ps-" + c + "-reach-" + e.reach[c])) + } + function g(t) { + return parseInt(t, 10) || 0 + } + h.prototype.eventElement = function(e) { + var t = this.eventElements.filter(function(t) { + return t.element === e + })[0]; + return t || (t = new o(e), + this.eventElements.push(t)), + t + } + , + h.prototype.bind = function(t, e, n) { + this.eventElement(t).bind(e, n) + } + , + h.prototype.unbind = function(t, e, n) { + t = this.eventElement(t); + t.unbind(e, n), + t.isEmpty && this.eventElements.splice(this.eventElements.indexOf(t), 1) + } + , + h.prototype.unbindAll = function() { + this.eventElements.forEach(function(t) { + return t.unbindAll() + }), + this.eventElements = [] + } + , + h.prototype.once = function(t, e, n) { + var i = this.eventElement(t) + , o = function(t) { + i.unbind(e, o), + n(t) + }; + i.bind(e, o) + } + ; + var m = { + isWebKit: "undefined" != typeof document && "WebkitAppearance"in document.documentElement.style, + supportsTouch: "undefined" != typeof window && ("ontouchstart"in window || "maxTouchPoints"in window.navigator && 0 < window.navigator.maxTouchPoints || window.DocumentTouch && document instanceof window.DocumentTouch), + supportsIePointer: "undefined" != typeof navigator && navigator.msMaxTouchPoints, + isChrome: "undefined" != typeof navigator && /Chrome/i.test(navigator && navigator.userAgent) + }; + function w(t) { + var e = t.element + , n = Math.floor(e.scrollTop) + , i = e.getBoundingClientRect() + , i = (t.containerWidth = Math.round(i.width), + t.containerHeight = Math.round(i.height), + t.contentWidth = e.scrollWidth, + t.contentHeight = e.scrollHeight, + e.contains(t.scrollbarXRail) || (u(e, v.element.rail("x")).forEach(s), + e.appendChild(t.scrollbarXRail)), + e.contains(t.scrollbarYRail) || (u(e, v.element.rail("y")).forEach(s), + e.appendChild(t.scrollbarYRail)), + !t.settings.suppressScrollX && t.containerWidth + t.settings.scrollXMarginOffset < t.contentWidth ? (t.scrollbarXActive = !0, + t.railXWidth = t.containerWidth - t.railXMarginWidth, + t.railXRatio = t.containerWidth / t.railXWidth, + t.scrollbarXWidth = b(t, g(t.railXWidth * t.containerWidth / t.contentWidth)), + t.scrollbarXLeft = g((t.negativeScrollAdjustment + e.scrollLeft) * (t.railXWidth - t.scrollbarXWidth) / (t.contentWidth - t.containerWidth))) : t.scrollbarXActive = !1, + !t.settings.suppressScrollY && t.containerHeight + t.settings.scrollYMarginOffset < t.contentHeight ? (t.scrollbarYActive = !0, + t.railYHeight = t.containerHeight - t.railYMarginHeight, + t.railYRatio = t.containerHeight / t.railYHeight, + t.scrollbarYHeight = b(t, g(t.railYHeight * t.containerHeight / t.contentHeight)), + t.scrollbarYTop = g(n * (t.railYHeight - t.scrollbarYHeight) / (t.contentHeight - t.containerHeight))) : t.scrollbarYActive = !1, + t.scrollbarXLeft >= t.railXWidth - t.scrollbarXWidth && (t.scrollbarXLeft = t.railXWidth - t.scrollbarXWidth), + t.scrollbarYTop >= t.railYHeight - t.scrollbarYHeight && (t.scrollbarYTop = t.railYHeight - t.scrollbarYHeight), + e) + , n = t + , o = { + width: n.railXWidth + } + , r = Math.floor(i.scrollTop); + n.isRtl ? o.left = n.negativeScrollAdjustment + i.scrollLeft + n.containerWidth - n.contentWidth : o.left = i.scrollLeft, + n.isScrollbarXUsingBottom ? o.bottom = n.scrollbarXBottom - r : o.top = n.scrollbarXTop + r, + l(n.scrollbarXRail, o), + o = { + top: r, + height: n.railYHeight + }, + n.isScrollbarYUsingRight ? n.isRtl ? o.right = n.contentWidth - (n.negativeScrollAdjustment + i.scrollLeft) - n.scrollbarYRight - n.scrollbarYOuterWidth - 9 : o.right = n.scrollbarYRight - i.scrollLeft : n.isRtl ? o.left = n.negativeScrollAdjustment + i.scrollLeft + 2 * n.containerWidth - n.contentWidth - n.scrollbarYLeft - n.scrollbarYOuterWidth : o.left = n.scrollbarYLeft + i.scrollLeft, + l(n.scrollbarYRail, o), + l(n.scrollbarX, { + left: n.scrollbarXLeft, + width: n.scrollbarXWidth - n.railBorderXWidth + }), + l(n.scrollbarY, { + top: n.scrollbarYTop, + height: n.scrollbarYHeight - n.railBorderYWidth + }), + t.scrollbarXActive ? e.classList.add(v.state.active("x")) : (e.classList.remove(v.state.active("x")), + t.scrollbarXWidth = 0, + t.scrollbarXLeft = 0, + e.scrollLeft = !0 === t.isRtl ? t.contentWidth : 0), + t.scrollbarYActive ? e.classList.add(v.state.active("y")) : (e.classList.remove(v.state.active("y")), + t.scrollbarYHeight = 0, + t.scrollbarYTop = 0, + e.scrollTop = 0) + } + function b(t, e) { + return t.settings.minScrollbarLength && (e = Math.max(e, t.settings.minScrollbarLength)), + e = t.settings.maxScrollbarLength ? Math.min(e, t.settings.maxScrollbarLength) : e + } + function O(n, t) { + var i = t[0] + , o = t[1] + , r = t[2] + , s = t[3] + , e = t[4] + , a = t[5] + , l = t[6] + , c = t[7] + , u = t[8] + , h = n.element + , d = null + , p = null + , f = null; + function g(t) { + t.touches && t.touches[0] && (t[r] = t.touches[0].pageY), + h[l] = d + f * (t[r] - p), + _(n, c), + w(n), + t.stopPropagation(), + t.type.startsWith("touch") && 1 < t.changedTouches.length && t.preventDefault() + } + function m() { + y(n, c), + n[u].classList.remove(v.state.clicking), + n.event.unbind(n.ownerDocument, "mousemove", g) + } + function b(t, e) { + d = h[l], + e && t.touches && (t[r] = t.touches[0].pageY), + p = t[r], + f = (n[o] - n[i]) / (n[s] - n[a]), + e ? n.event.bind(n.ownerDocument, "touchmove", g) : (n.event.bind(n.ownerDocument, "mousemove", g), + n.event.once(n.ownerDocument, "mouseup", m), + t.preventDefault()), + n[u].classList.add(v.state.clicking), + t.stopPropagation() + } + n.event.bind(n[e], "mousedown", function(t) { + b(t) + }), + n.event.bind(n[e], "touchstart", function(t) { + b(t, !0) + }) + } + function x(t, e) { + var n, i = this; + if (void 0 === e && (e = {}), + !(t = "string" == typeof t ? document.querySelector(t) : t) || !t.nodeName) + throw new Error("no element is specified to initialize PerfectScrollbar"); + for (n in (this.element = t).classList.add(v.main), + this.settings = { + handlers: ["click-rail", "drag-thumb", "keyboard", "wheel", "touch"], + maxScrollbarLength: null, + minScrollbarLength: null, + scrollingThreshold: 1e3, + scrollXMarginOffset: 0, + scrollYMarginOffset: 0, + suppressScrollX: !1, + suppressScrollY: !1, + swipeEasing: !0, + useBothWheelAxes: !1, + wheelPropagation: !0, + wheelSpeed: 1 + }, + e) + this.settings[n] = e[n]; + function o() { + return t.classList.add(v.state.focus) + } + function r() { + return t.classList.remove(v.state.focus) + } + this.containerWidth = null, + this.containerHeight = null, + this.contentWidth = null, + this.contentHeight = null, + this.isRtl = "rtl" === p(t).direction, + !0 === this.isRtl && t.classList.add(v.rtl), + this.isNegativeScroll = (s = t.scrollLeft, + t.scrollLeft = -1, + a = t.scrollLeft < 0, + t.scrollLeft = s, + a), + this.negativeScrollAdjustment = this.isNegativeScroll ? t.scrollWidth - t.clientWidth : 0, + this.event = new h, + this.ownerDocument = t.ownerDocument || document, + this.scrollbarXRail = c(v.element.rail("x")), + t.appendChild(this.scrollbarXRail), + this.scrollbarX = c(v.element.thumb("x")), + this.scrollbarXRail.appendChild(this.scrollbarX), + this.scrollbarX.setAttribute("tabindex", 0), + this.event.bind(this.scrollbarX, "focus", o), + this.event.bind(this.scrollbarX, "blur", r), + this.scrollbarXActive = null, + this.scrollbarXWidth = null, + this.scrollbarXLeft = null; + var s = p(this.scrollbarXRail) + , a = (this.scrollbarXBottom = parseInt(s.bottom, 10), + isNaN(this.scrollbarXBottom) ? (this.isScrollbarXUsingBottom = !1, + this.scrollbarXTop = g(s.top)) : this.isScrollbarXUsingBottom = !0, + this.railBorderXWidth = g(s.borderLeftWidth) + g(s.borderRightWidth), + l(this.scrollbarXRail, { + display: "block" + }), + this.railXMarginWidth = g(s.marginLeft) + g(s.marginRight), + l(this.scrollbarXRail, { + display: "" + }), + this.railXWidth = null, + this.railXRatio = null, + this.scrollbarYRail = c(v.element.rail("y")), + t.appendChild(this.scrollbarYRail), + this.scrollbarY = c(v.element.thumb("y")), + this.scrollbarYRail.appendChild(this.scrollbarY), + this.scrollbarY.setAttribute("tabindex", 0), + this.event.bind(this.scrollbarY, "focus", o), + this.event.bind(this.scrollbarY, "blur", r), + this.scrollbarYActive = null, + this.scrollbarYHeight = null, + this.scrollbarYTop = null, + p(this.scrollbarYRail)); + this.scrollbarYRight = parseInt(a.right, 10), + isNaN(this.scrollbarYRight) ? (this.isScrollbarYUsingRight = !1, + this.scrollbarYLeft = g(a.left)) : this.isScrollbarYUsingRight = !0, + this.scrollbarYOuterWidth = this.isRtl ? g((s = p(s = this.scrollbarY)).width) + g(s.paddingLeft) + g(s.paddingRight) + g(s.borderLeftWidth) + g(s.borderRightWidth) : null, + this.railBorderYWidth = g(a.borderTopWidth) + g(a.borderBottomWidth), + l(this.scrollbarYRail, { + display: "block" + }), + this.railYMarginHeight = g(a.marginTop) + g(a.marginBottom), + l(this.scrollbarYRail, { + display: "" + }), + this.railYHeight = null, + this.railYRatio = null, + this.reach = { + x: t.scrollLeft <= 0 ? "start" : t.scrollLeft >= this.contentWidth - this.containerWidth ? "end" : null, + y: t.scrollTop <= 0 ? "start" : t.scrollTop >= this.contentHeight - this.containerHeight ? "end" : null + }, + this.isAlive = !0, + this.settings.handlers.forEach(function(t) { + return S[t](i) + }), + this.lastScrollTop = Math.floor(t.scrollTop), + this.lastScrollLeft = t.scrollLeft, + this.event.bind(this.element, "scroll", function(t) { + return i.onScroll(t) + }), + w(this) + } + var S = { + "click-rail": function(n) { + n.element, + n.event.bind(n.scrollbarY, "mousedown", function(t) { + return t.stopPropagation() + }), + n.event.bind(n.scrollbarYRail, "mousedown", function(t) { + var e = t.pageY - window.pageYOffset - n.scrollbarYRail.getBoundingClientRect().top > n.scrollbarYTop ? 1 : -1; + n.element.scrollTop += e * n.containerHeight, + w(n), + t.stopPropagation() + }), + n.event.bind(n.scrollbarX, "mousedown", function(t) { + return t.stopPropagation() + }), + n.event.bind(n.scrollbarXRail, "mousedown", function(t) { + var e = t.pageX - window.pageXOffset - n.scrollbarXRail.getBoundingClientRect().left > n.scrollbarXLeft ? 1 : -1; + n.element.scrollLeft += e * n.containerWidth, + w(n), + t.stopPropagation() + }) + }, + "drag-thumb": function(t) { + O(t, ["containerWidth", "contentWidth", "pageX", "railXWidth", "scrollbarX", "scrollbarXWidth", "scrollLeft", "x", "scrollbarXRail"]), + O(t, ["containerHeight", "contentHeight", "pageY", "railYHeight", "scrollbarY", "scrollbarYHeight", "scrollTop", "y", "scrollbarYRail"]) + }, + keyboard: function(r) { + var s = r.element; + r.event.bind(r.ownerDocument, "keydown", function(t) { + if (!(t.isDefaultPrevented && t.isDefaultPrevented() || t.defaultPrevented) && (a(s, ":hover") || a(r.scrollbarX, ":focus") || a(r.scrollbarY, ":focus"))) { + var e, n = document.activeElement || r.ownerDocument.activeElement; + if (n) { + if ("IFRAME" === n.tagName) + n = n.contentDocument.activeElement; + else + for (; n.shadowRoot; ) + n = n.shadowRoot.activeElement; + if (a(e = n, "input,[contenteditable]") || a(e, "select,[contenteditable]") || a(e, "textarea,[contenteditable]") || a(e, "button,[contenteditable]")) + return + } + var i = 0 + , o = 0; + switch (t.which) { + case 37: + i = t.metaKey ? -r.contentWidth : t.altKey ? -r.containerWidth : -30; + break; + case 38: + o = t.metaKey ? r.contentHeight : t.altKey ? r.containerHeight : 30; + break; + case 39: + i = t.metaKey ? r.contentWidth : t.altKey ? r.containerWidth : 30; + break; + case 40: + o = t.metaKey ? -r.contentHeight : t.altKey ? -r.containerHeight : -30; + break; + case 32: + o = t.shiftKey ? r.containerHeight : -r.containerHeight; + break; + case 33: + o = r.containerHeight; + break; + case 34: + o = -r.containerHeight; + break; + case 36: + o = r.contentHeight; + break; + case 35: + o = -r.contentHeight; + break; + default: + return + } + r.settings.suppressScrollX && 0 !== i || r.settings.suppressScrollY && 0 !== o || (s.scrollTop -= o, + s.scrollLeft += i, + w(r), + !function(t, e) { + var n = Math.floor(s.scrollTop); + if (0 === t) { + if (!r.scrollbarYActive) + return; + if (0 === n && 0 < e || n >= r.contentHeight - r.containerHeight && e < 0) + return !r.settings.wheelPropagation + } + if (n = s.scrollLeft, + 0 === e) { + if (!r.scrollbarXActive) + return; + if (0 === n && t < 0 || n >= r.contentWidth - r.containerWidth && 0 < t) + return !r.settings.wheelPropagation + } + return 1 + }(i, o)) || t.preventDefault() + } + }) + }, + wheel: function(l) { + var c = l.element; + function t(t) { + s = (r = t).deltaX, + a = -1 * r.deltaY, + void 0 !== s && void 0 !== a || (s = -1 * r.wheelDeltaX / 6, + a = r.wheelDeltaY / 6), + r.deltaMode && 1 === r.deltaMode && (s *= 10, + a *= 10), + s != s && a != a && (s = 0, + a = r.wheelDelta); + var e, n, i, o, r = r.shiftKey ? [-a, -s] : [s, a], s = r[0], a = r[1]; + !function(t, e, n) { + if (!m.isWebKit && c.querySelector("select:focus")) + return 1; + if (c.contains(t)) + for (var i = t; i && i !== c; ) { + if (i.classList.contains(v.element.consuming)) + return 1; + var o = p(i); + if (n && o.overflowY.match(/(scroll|auto)/)) { + var r = i.scrollHeight - i.clientHeight; + if (0 < r && (0 < i.scrollTop && n < 0 || i.scrollTop < r && 0 < n)) + return 1 + } + if (e && o.overflowX.match(/(scroll|auto)/)) { + r = i.scrollWidth - i.clientWidth; + if (0 < r && (0 < i.scrollLeft && e < 0 || i.scrollLeft < r && 0 < e)) + return 1 + } + i = i.parentNode + } + }(t.target, s, a) && (r = !1, + l.settings.useBothWheelAxes ? l.scrollbarYActive && !l.scrollbarXActive ? (a ? c.scrollTop -= a * l.settings.wheelSpeed : c.scrollTop += s * l.settings.wheelSpeed, + r = !0) : l.scrollbarXActive && !l.scrollbarYActive && (s ? c.scrollLeft += s * l.settings.wheelSpeed : c.scrollLeft -= a * l.settings.wheelSpeed, + r = !0) : (c.scrollTop -= a * l.settings.wheelSpeed, + c.scrollLeft += s * l.settings.wheelSpeed), + w(l), + r = r || (s = s, + a = a, + e = Math.floor(c.scrollTop), + n = 0 === c.scrollTop, + e = e + c.offsetHeight === c.scrollHeight, + i = 0 === c.scrollLeft, + o = c.scrollLeft + c.offsetWidth === c.scrollWidth, + !(a = Math.abs(a) > Math.abs(s) ? n || e : i || o)) || !l.settings.wheelPropagation) && !t.ctrlKey && (t.stopPropagation(), + t.preventDefault()) + } + void 0 !== window.onwheel ? l.event.bind(c, "wheel", t) : void 0 !== window.onmousewheel && l.event.bind(c, "mousewheel", t) + }, + touch: function(s) { + var a, r, l, c, e; + function u(t, e) { + a.scrollTop -= e, + a.scrollLeft -= t, + w(s) + } + function h(t) { + return t.targetTouches ? t.targetTouches[0] : t + } + function d(t) { + return (!t.pointerType || "pen" !== t.pointerType || 0 !== t.buttons) && (t.targetTouches && 1 === t.targetTouches.length || !(!t.pointerType || "mouse" === t.pointerType || t.pointerType === t.MSPOINTER_TYPE_MOUSE)) + } + function t(t) { + d(t) && (t = h(t), + r.pageX = t.pageX, + r.pageY = t.pageY, + l = (new Date).getTime(), + null !== e) && clearInterval(e) + } + function n(t) { + var e, n, i, o; + d(t) && (e = (i = { + pageX: (i = h(t)).pageX, + pageY: i.pageY + }).pageX - r.pageX, + n = i.pageY - r.pageY, + !function(t, e, n) { + if (a.contains(t)) + for (var i = t; i && i !== a; ) { + if (i.classList.contains(v.element.consuming)) + return 1; + var o = p(i); + if (n && o.overflowY.match(/(scroll|auto)/)) { + var r = i.scrollHeight - i.clientHeight; + if (0 < r && (0 < i.scrollTop && n < 0 || i.scrollTop < r && 0 < n)) + return 1 + } + if (e && o.overflowX.match(/(scroll|auto)/)) { + r = i.scrollWidth - i.clientWidth; + if (0 < r && (0 < i.scrollLeft && e < 0 || i.scrollLeft < r && 0 < e)) + return 1 + } + i = i.parentNode + } + }(t.target, e, n)) && (u(e, n), + r = i, + 0 < (o = (i = (new Date).getTime()) - l) && (c.x = e / o, + c.y = n / o, + l = i), + function(t, e) { + var n = Math.floor(a.scrollTop) + , i = a.scrollLeft + , o = Math.abs(t) + , r = Math.abs(e); + if (o < r) { + if (e < 0 && n === s.contentHeight - s.containerHeight || 0 < e && 0 === n) + return 0 === window.scrollY && 0 < e && m.isChrome + } else if (r < o && (t < 0 && i === s.contentWidth - s.containerWidth || 0 < t && 0 === i)) + ;return 1 + }(e, n)) && t.preventDefault() + } + function i() { + s.settings.swipeEasing && (clearInterval(e), + e = setInterval(function() { + !s.isInitialized && (c.x || c.y) && !(Math.abs(c.x) < .01 && Math.abs(c.y) < .01) && s.element ? (u(30 * c.x, 30 * c.y), + c.x *= .8, + c.y *= .8) : clearInterval(e) + }, 10)) + } + (m.supportsTouch || m.supportsIePointer) && (a = s.element, + r = {}, + l = 0, + c = {}, + e = null, + m.supportsTouch ? (s.event.bind(a, "touchstart", t), + s.event.bind(a, "touchmove", n), + s.event.bind(a, "touchend", i)) : m.supportsIePointer && (window.PointerEvent ? (s.event.bind(a, "pointerdown", t), + s.event.bind(a, "pointermove", n), + s.event.bind(a, "pointerup", i)) : window.MSPointerEvent && (s.event.bind(a, "MSPointerDown", t), + s.event.bind(a, "MSPointerMove", n), + s.event.bind(a, "MSPointerUp", i)))) + } + } + , C = (x.prototype.update = function() { + this.isAlive && (this.negativeScrollAdjustment = this.isNegativeScroll ? this.element.scrollWidth - this.element.clientWidth : 0, + l(this.scrollbarXRail, { + display: "block" + }), + l(this.scrollbarYRail, { + display: "block" + }), + this.railXMarginWidth = g(p(this.scrollbarXRail).marginLeft) + g(p(this.scrollbarXRail).marginRight), + this.railYMarginHeight = g(p(this.scrollbarYRail).marginTop) + g(p(this.scrollbarYRail).marginBottom), + l(this.scrollbarXRail, { + display: "none" + }), + l(this.scrollbarYRail, { + display: "none" + }), + w(this), + f(this, "top", 0, !1, !0), + f(this, "left", 0, !1, !0), + l(this.scrollbarXRail, { + display: "" + }), + l(this.scrollbarYRail, { + display: "" + })) + } + , + x.prototype.onScroll = function(t) { + this.isAlive && (w(this), + f(this, "top", this.element.scrollTop - this.lastScrollTop), + f(this, "left", this.element.scrollLeft - this.lastScrollLeft), + this.lastScrollTop = Math.floor(this.element.scrollTop), + this.lastScrollLeft = this.element.scrollLeft) + } + , + x.prototype.destroy = function() { + this.isAlive && (this.event.unbindAll(), + s(this.scrollbarX), + s(this.scrollbarY), + s(this.scrollbarXRail), + s(this.scrollbarYRail), + this.removePsClasses(), + this.element = null, + this.scrollbarX = null, + this.scrollbarY = null, + this.scrollbarXRail = null, + this.scrollbarYRail = null, + this.isAlive = !1) + } + , + x.prototype.removePsClasses = function() { + this.element.className = this.element.className.split(" ").filter(function(t) { + return !t.match(/^ps([-_].+|)$/) + }).join(" ") + } + , + x) + , E = e(3) + , k = e(7) + , A = e(0) + , j = e(1) + , r = e(2); + const T = "perfectScrollbar" + , L = "mdb.perfectScrollbar"; + var e = "mdb" + , P = "ps"; + const R = [{ + mdb: "scrollX.".concat(e, ".").concat(P), + ps: "ps-scroll-x" + }, { + mdb: "scrollY.".concat(e, ".").concat(P), + ps: "ps-scroll-y" + }, { + mdb: "scrollUp.".concat(e, ".").concat(P), + ps: "ps-scroll-up" + }, { + mdb: "scrollDown.".concat(e, ".").concat(P), + ps: "ps-scroll-down" + }, { + mdb: "scrollLeft.".concat(e, ".").concat(P), + ps: "ps-scroll-left" + }, { + mdb: "scrollRight.".concat(e, ".").concat(P), + ps: "ps-scroll-right" + }, { + mdb: "scrollXEnd.".concat(e, ".").concat(P), + ps: "ps-x-reach-end" + }, { + mdb: "scrollYEnd.".concat(e, ".").concat(P), + ps: "ps-y-reach-end" + }, { + mdb: "scrollXStart.".concat(e, ".").concat(P), + ps: "ps-x-reach-start" + }, { + mdb: "scrollYStart.".concat(e, ".").concat(P), + ps: "ps-y-reach-start" + }] + , M = { + handlers: ["click-rail", "drag-thumb", "keyboard", "wheel", "touch"], + wheelSpeed: 1, + wheelPropagation: !0, + swipeEasing: !0, + minScrollbarLength: null, + maxScrollbarLength: null, + scrollingThreshold: 1e3, + useBothWheelAxes: !1, + suppressScrollX: !1, + suppressScrollY: !1, + scrollXMarginOffset: 0, + scrollYMarginOffset: 0 + } + , N = { + handlers: "(string|array)", + wheelSpeed: "number", + wheelPropagation: "boolean", + swipeEasing: "boolean", + minScrollbarLength: "(number|null)", + maxScrollbarLength: "(number|null)", + scrollingThreshold: "number", + useBothWheelAxes: "boolean", + suppressScrollX: "boolean", + suppressScrollY: "boolean", + scrollXMarginOffset: "number", + scrollYMarginOffset: "number" + }; + class I { + constructor(t) { + var e = 1 < arguments.length && void 0 !== arguments[1] ? arguments[1] : {}; + this._element = t, + this._options = this._getConfig(e), + this.perfectScrollbar = null, + this._element && (k.a.setData(t, L, this), + A.a.addClass(this._element, "perfect-scrollbar")), + this.init() + } + static get NAME() { + return T + } + _getConfig(t) { + var e = A.a.getDataAttributes(this._element); + return void 0 !== e.handlers && (e.handlers = e.handlers.split(" ")), + t = { + ...M, + ...e, + ...t + }, + Object(E.j)(T, t, N), + t + } + dispose() { + k.a.removeData(this._element, L), + this._element = null, + this._dataAttrOptions = null, + this._options = null, + this.perfectScrollbar.destroy(), + this.removeEvent(R), + this.perfectScrollbar = null + } + init() { + this.perfectScrollbar = new C(this._element,this._options), + this._initEvents(R) + } + update() { + return this.perfectScrollbar.update() + } + _initEvents() { + (0 < arguments.length && void 0 !== arguments[0] ? arguments[0] : []).forEach(t=>{ + let {ps: e, mdb: n} = t; + return j.b.on(this._element, e, t=>j.b.trigger(this._element, n, { + e: t + })) + } + ) + } + removeEvent(e) { + let t = []; + (t = "string" == typeof e ? R.filter(t=>{ + t = t.mdb; + return t === e + } + ) : t).forEach(t=>{ + var {ps: t, mdb: e} = t; + j.b.off(this._element, t), + j.b.off(this._element, e) + } + ) + } + static jQueryInterface(n) { + return this.each(function() { + let t = k.a.getData(this, L); + var e = "object" == typeof n && n; + if ((t || !/dispose|hide/.test(n)) && (t = t || new I(this,e), + "string" == typeof n)) { + if (void 0 === t[n]) + throw new TypeError('No method named "'.concat(n, '"')); + t[n]() + } + }) + } + static getInstance(t) { + return k.a.getData(t, L) + } + static getOrCreateInstance(t) { + var e = 1 < arguments.length && void 0 !== arguments[1] ? arguments[1] : {}; + return this.getInstance(t) || new this(t,"object" == typeof e ? e : null) + } + } + r.a.find('[data-mdb-perfect-scrollbar="true"]').forEach(t=>{ + let e = I.getInstance(t); + return e = e || new I(t) + } + ), + Object(E.i)(()=>{ + const t = Object(E.f)(); + if (t) { + const e = t.fn[T]; + t.fn[T] = I.jQueryInterface, + t.fn[T].Constructor = I, + t.fn[T].noConflict = ()=>(t.fn[T] = e, + I.jQueryInterface) + } + } + ); + t.a = I + } + , function(t, e, n) { + "use strict"; + n.r(e), + n.d(e, "compiled", function() { + return m + }); + n(204), + n(220), + n(235); + var e = n(190) + , i = n(52) + , o = n(191) + , r = n(192) + , s = n(193) + , a = n(136) + , l = n(102) + , c = n(194) + , u = n(138) + , h = n(189) + , d = n(188) + , p = n(195) + , f = n(196) + , g = n(134) + , n = n(197); + const m = { + Button: e.a, + Collapse: i.a, + Popover: o.a, + ScrollSpy: r.a, + Tab: s.a, + Tooltip: a.a, + Input: l.a, + Dropdown: c.a, + Animate: u.a, + Modal: h.a, + Sidenav: d.a, + Alert: p.a, + Toast: f.a, + Select: g.a, + PerfectScrollbar: n.a + } + } + , function(t, e, n) { + "use strict"; + var i = n(26) + , o = n(262).left + , r = n(176) + , s = n(90); + i({ + target: "Array", + proto: !0, + forced: !n(83) && 79 < s && s < 83 || !r("reduce") + }, { + reduce: function(t) { + var e = arguments.length; + return o(this, t, e, 1 < e ? arguments[1] : void 0) + } + }) + } + , function(t, e, n) { + "use strict"; + var i = n(14) + , o = n(50) + , d = Math.floor + , p = i("".charAt) + , f = i("".replace) + , g = i("".slice) + , m = /\$([$&'`]|\d{1,2}|<[^>]*>)/g + , b = /\$([$&'`]|\d{1,2})/g; + t.exports = function(r, s, a, l, c, t) { + var u = a + r.length + , h = l.length + , e = b; + return void 0 !== c && (c = o(c), + e = m), + f(t, e, function(t, e) { + var n; + switch (p(e, 0)) { + case "$": + return "$"; + case "&": + return r; + case "`": + return g(s, 0, a); + case "'": + return g(s, u); + case "<": + n = c[g(e, 1, -1)]; + break; + default: + var i, o = +e; + if (0 == o) + return t; + if (h < o) + return 0 !== (i = d(o / 10)) && i <= h ? void 0 === l[i - 1] ? p(e, 1) : l[i - 1] + p(e, 1) : t; + n = l[o - 1] + } + return void 0 === n ? "" : n + }) + } + } + , function(t, e, n) { + "use strict"; + var i = n(35) + , o = n(55) + , r = n(20)("match"); + t.exports = function(t) { + var e; + return i(t) && (void 0 !== (e = t[r]) ? !!e : "RegExp" === o(t)) + } + } + , function(t, e, n) { + "use strict"; + var i = n(22) + , o = n(29) + , r = n(56) + , s = n(125) + , a = RegExp.prototype; + t.exports = function(t) { + var e = t.flags; + return void 0 !== e || "flags"in a || o(t, "flags") || !r(a, t) ? e : i(s, t) + } + } + , function(t, e, n) { + "use strict"; + n(237), + n(246), + n(248), + n(249), + n(250), + n(251) + } + , function(t, e, n) { + "use strict"; + !function(t) { + var e; + n(137), + n(11), + n(12); + e = function() { + return n = [function(t, e, n) { + var i; + n = [t, n(7)], + void 0 !== (e = "function" == typeof (i = function(t, e) { + "use strict"; + function n(t, e) { + if (!(t instanceof e)) + throw new TypeError("Cannot call a class as a function") + } + var i = function(t) { + return t && t.__esModule ? t : { + default: t + } + }(e) + , o = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(t) { + return typeof t + } + : function(t) { + return t && "function" == typeof Symbol && t.constructor === Symbol && t !== Symbol.prototype ? "symbol" : typeof t + } + , r = function() { + function i(t, e) { + for (var n = 0; n < e.length; n++) { + var i = e[n]; + i.enumerable = i.enumerable || !1, + i.configurable = !0, + "value"in i && (i.writable = !0), + Object.defineProperty(t, i.key, i) + } + } + return function(t, e, n) { + return e && i(t.prototype, e), + n && i(t, n), + t + } + }() + , s = function() { + function e(t) { + n(this, e), + this.resolveOptions(t), + this.initSelection() + } + return r(e, [{ + key: "resolveOptions", + value: function() { + var t = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : {}; + this.action = t.action, + this.container = t.container, + this.emitter = t.emitter, + this.target = t.target, + this.text = t.text, + this.trigger = t.trigger, + this.selectedText = "" + } + }, { + key: "initSelection", + value: function() { + this.text ? this.selectFake() : this.target && this.selectTarget() + } + }, { + key: "selectFake", + value: function() { + var t = this + , e = "rtl" == document.documentElement.getAttribute("dir"); + this.removeFake(), + this.fakeHandlerCallback = function() { + return t.removeFake() + } + , + this.fakeHandler = this.container.addEventListener("click", this.fakeHandlerCallback) || !0, + this.fakeElem = document.createElement("textarea"), + this.fakeElem.style.fontSize = "12pt", + this.fakeElem.style.border = "0", + this.fakeElem.style.padding = "0", + this.fakeElem.style.margin = "0", + this.fakeElem.style.position = "absolute", + this.fakeElem.style[e ? "right" : "left"] = "-9999px"; + var n = window.pageYOffset || document.documentElement.scrollTop; + this.fakeElem.style.top = n + "px", + this.fakeElem.setAttribute("readonly", ""), + this.fakeElem.value = this.text, + this.container.appendChild(this.fakeElem), + this.selectedText = (0, + i.default)(this.fakeElem), + this.copyText() + } + }, { + key: "removeFake", + value: function() { + this.fakeHandler && (this.container.removeEventListener("click", this.fakeHandlerCallback), + this.fakeHandler = null, + this.fakeHandlerCallback = null), + this.fakeElem && (this.container.removeChild(this.fakeElem), + this.fakeElem = null) + } + }, { + key: "selectTarget", + value: function() { + this.selectedText = (0, + i.default)(this.target), + this.copyText() + } + }, { + key: "copyText", + value: function() { + var e = void 0; + try { + e = document.execCommand(this.action) + } catch (t) { + e = !1 + } + this.handleResult(e) + } + }, { + key: "handleResult", + value: function(t) { + this.emitter.emit(t ? "success" : "error", { + action: this.action, + text: this.selectedText, + trigger: this.trigger, + clearSelection: this.clearSelection.bind(this) + }) + } + }, { + key: "clearSelection", + value: function() { + this.trigger && this.trigger.focus(), + window.getSelection().removeAllRanges() + } + }, { + key: "destroy", + value: function() { + this.removeFake() + } + }, { + key: "action", + set: function() { + var t = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : "copy"; + if (this._action = t, + "copy" !== this._action && "cut" !== this._action) + throw new Error('Invalid "action" value, use either "copy" or "cut"') + }, + get: function() { + return this._action + } + }, { + key: "target", + set: function(t) { + if (void 0 !== t) { + if (!t || "object" !== (void 0 === t ? "undefined" : o(t)) || 1 !== t.nodeType) + throw new Error('Invalid "target" value, use a valid Element'); + if ("copy" === this.action && t.hasAttribute("disabled")) + throw new Error('Invalid "target" attribute. Please use "readonly" instead of "disabled" attribute'); + if ("cut" === this.action && (t.hasAttribute("readonly") || t.hasAttribute("disabled"))) + throw new Error('Invalid "target" attribute. You can\'t cut text from elements with "readonly" or "disabled" attributes'); + this._target = t + } + }, + get: function() { + return this._target + } + }]), + e + }(); + t.exports = s + } + ) ? i.apply(e, n) : i) && (t.exports = e) + } + , function(t, e, n) { + var c = n(6) + , u = n(5); + t.exports = function(t, e, n) { + if (!t && !e && !n) + throw new Error("Missing required arguments"); + if (!c.string(e)) + throw new TypeError("Second argument must be a String"); + if (!c.fn(n)) + throw new TypeError("Third argument must be a Function"); + if (c.node(t)) + return o = e, + r = n, + (i = t).addEventListener(o, r), + { + destroy: function() { + i.removeEventListener(o, r) + } + }; + var i, o, r, s, a, l; + if (c.nodeList(t)) + return s = t, + a = e, + l = n, + Array.prototype.forEach.call(s, function(t) { + t.addEventListener(a, l) + }), + { + destroy: function() { + Array.prototype.forEach.call(s, function(t) { + t.removeEventListener(a, l) + }) + } + }; + if (c.string(t)) + return u(document.body, t, e, n); + throw new TypeError("First argument must be a String, HTMLElement, HTMLCollection, or NodeList") + } + } + , function(t, e) { + function n() {} + n.prototype = { + on: function(t, e, n) { + var i = this.e || (this.e = {}); + return (i[t] || (i[t] = [])).push({ + fn: e, + ctx: n + }), + this + }, + once: function(t, e, n) { + function i() { + o.off(t, i), + e.apply(n, arguments) + } + var o = this; + return i._ = e, + this.on(t, i, n) + }, + emit: function(t) { + for (var e = [].slice.call(arguments, 1), n = ((this.e || (this.e = {}))[t] || []).slice(), i = 0, o = n.length; i < o; i++) + n[i].fn.apply(n[i].ctx, e); + return this + }, + off: function(t, e) { + var n = this.e || (this.e = {}) + , i = n[t] + , o = []; + if (i && e) + for (var r = 0, s = i.length; r < s; r++) + i[r].fn !== e && i[r].fn._ !== e && o.push(i[r]); + return o.length ? n[t] = o : delete n[t], + this + } + }, + t.exports = n + } + , function(t, e, n) { + var i; + n = [t, n(0), n(2), n(1)], + void 0 !== (e = "function" == typeof (i = function(t, e, n, i) { + "use strict"; + function o(t) { + return t && t.__esModule ? t : { + default: t + } + } + function r(t, e) { + if (!(t instanceof e)) + throw new TypeError("Cannot call a class as a function") + } + function s(t, e) { + if (!t) + throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); + return !e || "object" != typeof e && "function" != typeof e ? t : e + } + function a(t, e) { + if ("function" != typeof e && null !== e) + throw new TypeError("Super expression must either be null or a function, not " + typeof e); + t.prototype = Object.create(e && e.prototype, { + constructor: { + value: t, + enumerable: !1, + writable: !0, + configurable: !0 + } + }), + e && (Object.setPrototypeOf ? Object.setPrototypeOf(t, e) : t.__proto__ = e) + } + function l(t, e) { + var n = "data-clipboard-" + t; + if (e.hasAttribute(n)) + return e.getAttribute(n) + } + var c = o(e) + , u = o(n) + , h = o(i) + , d = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(t) { + return typeof t + } + : function(t) { + return t && "function" == typeof Symbol && t.constructor === Symbol && t !== Symbol.prototype ? "symbol" : typeof t + } + , p = function() { + function i(t, e) { + for (var n = 0; n < e.length; n++) { + var i = e[n]; + i.enumerable = i.enumerable || !1, + i.configurable = !0, + "value"in i && (i.writable = !0), + Object.defineProperty(t, i.key, i) + } + } + return function(t, e, n) { + return e && i(t.prototype, e), + n && i(t, n), + t + } + }() + , f = function(t) { + function i(t, e) { + r(this, i); + var n = s(this, (i.__proto__ || Object.getPrototypeOf(i)).call(this)); + return n.resolveOptions(e), + n.listenClick(t), + n + } + return a(i, t), + p(i, [{ + key: "resolveOptions", + value: function() { + var t = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : {}; + this.action = "function" == typeof t.action ? t.action : this.defaultAction, + this.target = "function" == typeof t.target ? t.target : this.defaultTarget, + this.text = "function" == typeof t.text ? t.text : this.defaultText, + this.container = "object" === d(t.container) ? t.container : document.body + } + }, { + key: "listenClick", + value: function(t) { + var e = this; + this.listener = (0, + h.default)(t, "click", function(t) { + return e.onClick(t) + }) + } + }, { + key: "onClick", + value: function(t) { + var e = t.delegateTarget || t.currentTarget; + this.clipboardAction && (this.clipboardAction = null), + this.clipboardAction = new c.default({ + action: this.action(e), + target: this.target(e), + text: this.text(e), + container: this.container, + trigger: e, + emitter: this + }) + } + }, { + key: "defaultAction", + value: function(t) { + return l("action", t) + } + }, { + key: "defaultTarget", + value: function(t) { + var e = l("target", t); + if (e) + return document.querySelector(e) + } + }, { + key: "defaultText", + value: function(t) { + return l("text", t) + } + }, { + key: "destroy", + value: function() { + this.listener.destroy(), + this.clipboardAction && (this.clipboardAction.destroy(), + this.clipboardAction = null) + } + }], [{ + key: "isSupported", + value: function() { + var t = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : ["copy", "cut"] + , e = "string" == typeof t ? [t] : t + , n = !!document.queryCommandSupported; + return e.forEach(function(t) { + n = n && !!document.queryCommandSupported(t) + }), + n + } + }]), + i + }(u.default); + t.exports = f + } + ) ? i.apply(e, n) : i) && (t.exports = e) + } + , function(t, e) { + var n; + "undefined" == typeof Element || Element.prototype.matches || ((n = Element.prototype).matches = n.matchesSelector || n.mozMatchesSelector || n.msMatchesSelector || n.oMatchesSelector || n.webkitMatchesSelector), + t.exports = function(t, e) { + for (; t && 9 !== t.nodeType; ) { + if ("function" == typeof t.matches && t.matches(e)) + return t; + t = t.parentNode + } + } + } + , function(t, e, n) { + function r(t, e, n, i, o) { + var r = function(e, n, t, i) { + return function(t) { + t.delegateTarget = s(t.target, n), + t.delegateTarget && i.call(e, t) + } + } + .apply(this, arguments); + return t.addEventListener(n, r, o), + { + destroy: function() { + t.removeEventListener(n, r, o) + } + } + } + var s = n(4); + t.exports = function(t, e, n, i, o) { + return "function" == typeof t.addEventListener ? r.apply(null, arguments) : "function" == typeof n ? r.bind(null, document).apply(null, arguments) : ("string" == typeof t && (t = document.querySelectorAll(t)), + Array.prototype.map.call(t, function(t) { + return r(t, e, n, i, o) + })) + } + } + , function(t, n) { + n.node = function(t) { + return void 0 !== t && t instanceof HTMLElement && 1 === t.nodeType + } + , + n.nodeList = function(t) { + var e = Object.prototype.toString.call(t); + return void 0 !== t && ("[object NodeList]" === e || "[object HTMLCollection]" === e) && "length"in t && (0 === t.length || n.node(t[0])) + } + , + n.string = function(t) { + return "string" == typeof t || t instanceof String + } + , + n.fn = function(t) { + return "[object Function]" === Object.prototype.toString.call(t) + } + } + , function(t, e) { + t.exports = function(t) { + var e, n; + return t = "SELECT" === t.nodeName ? (t.focus(), + t.value) : "INPUT" === t.nodeName || "TEXTAREA" === t.nodeName ? ((e = t.hasAttribute("readonly")) || t.setAttribute("readonly", ""), + t.select(), + t.setSelectionRange(0, t.value.length), + e || t.removeAttribute("readonly"), + t.value) : (t.hasAttribute("contenteditable") && t.focus(), + e = window.getSelection(), + (n = document.createRange()).selectNodeContents(t), + e.removeAllRanges(), + e.addRange(n), + e.toString()) + } + } + ], + o = {}, + i.m = n, + i.c = o, + i.i = function(t) { + return t + } + , + i.d = function(t, e, n) { + i.o(t, e) || Object.defineProperty(t, e, { + configurable: !1, + enumerable: !0, + get: n + }) + } + , + i.n = function(t) { + var e = t && t.__esModule ? function() { + return t.default + } + : function() { + return t + } + ; + return i.d(e, "a", e), + e + } + , + i.o = function(t, e) { + return Object.prototype.hasOwnProperty.call(t, e) + } + , + i.p = "", + i(i.s = 3); + function i(t) { + var e; + return (o[t] || (e = o[t] = { + i: t, + l: !1, + exports: {} + }, + n[t].call(e.exports, e, e.exports, i), + e.l = !0, + e)).exports + } + var n, o + } + , + "object" == typeof exports && "object" == typeof t ? t.exports = e() : "function" == typeof define && n(219) ? define([], e) : "object" == typeof exports ? exports.ClipboardJS = e() : window.ClipboardJS = e() + } + .call(this, n(205)(t)) + } + , function(t, e) { + t.exports = function(t) { + var e; + return t.webpackPolyfill || ((e = Object.create(t)).children || (e.children = []), + Object.defineProperty(e, "loaded", { + enumerable: !0, + get: function() { + return e.l + } + }), + Object.defineProperty(e, "id", { + enumerable: !0, + get: function() { + return e.i + } + }), + Object.defineProperty(e, "exports", { + enumerable: !0 + }), + e.webpackPolyfill = 1), + e + } + } + , function(t, e) { + var n = function() { + return this + }(); + try { + n = n || new Function("return this")() + } catch (t) { + "object" == typeof window && (n = window) + } + t.exports = n + } + , function(t, e, n) { + "use strict"; + var i = n(22) + , o = n(35) + , r = n(144) + , s = n(88) + , a = n(208) + , n = n(20) + , l = TypeError + , c = n("toPrimitive"); + t.exports = function(t, e) { + if (!o(t) || r(t)) + return t; + var n = s(t, c); + if (n) { + if (n = i(n, t, e = void 0 === e ? "default" : e), + !o(n) || r(n)) + return n; + throw l("Can't convert object to primitive value") + } + return a(t, e = void 0 === e ? "number" : e) + } + } + , function(t, e, n) { + "use strict"; + var o = n(22) + , r = n(15) + , s = n(35) + , a = TypeError; + t.exports = function(t, e) { + var n, i; + if ("string" === e && r(n = t.toString) && !s(i = o(n, t))) + return i; + if (r(n = t.valueOf) && !s(i = o(n, t))) + return i; + if ("string" !== e && r(n = t.toString) && !s(i = o(n, t))) + return i; + throw a("Can't convert object to primitive value") + } + } + , function(t, e, n) { + "use strict"; + var i = n(13) + , n = n(15) + , i = i.WeakMap; + t.exports = n(i) && /native code/.test(String(i)) + } + , function(t, e, n) { + "use strict"; + var i = n(48) + , o = n(14) + , r = n(152) + , s = n(157) + , a = n(30) + , l = o([].concat); + t.exports = i("Reflect", "ownKeys") || function(t) { + var e = r.f(a(t)) + , n = s.f; + return n ? l(e, n(t)) : e + } + } + , function(t, e, n) { + "use strict"; + var i = Math.ceil + , o = Math.floor; + t.exports = Math.trunc || function(t) { + t = +t; + return (0 < t ? o : i)(t) + } + } + , function(t, e, n) { + "use strict"; + var i = {}; + i[n(20)("toStringTag")] = "z", + t.exports = "[object z]" === String(i) + } + , function(t, e, n) { + "use strict"; + var i = n(23) + , o = n(149) + , a = n(40) + , l = n(30) + , c = n(77) + , u = n(159); + e.f = i && !o ? Object.defineProperties : function(t, e) { + l(t); + for (var n, i = c(e), o = u(e), r = o.length, s = 0; s < r; ) + a.f(t, n = o[s++], i[n]); + return t + } + } + , function(t, e, n) { + "use strict"; + n = n(16); + t.exports = !n(function() { + function t() {} + return t.prototype.constructor = null, + Object.getPrototypeOf(new t) !== t.prototype + }) + } + , function(t, e, n) { + "use strict"; + var i = n(14) + , o = n(39); + t.exports = function(t, e, n) { + try { + return i(o(Object.getOwnPropertyDescriptor(t, e)[n])) + } catch (t) {} + } + } + , function(t, e, n) { + "use strict"; + var i = n(15) + , o = String + , r = TypeError; + t.exports = function(t) { + if ("object" == typeof t || i(t)) + return t; + throw r("Can't set " + o(t) + " as a prototype") + } + } + , function(t, e, n) { + "use strict"; + t.exports = { + CSSRuleList: 0, + CSSStyleDeclaration: 0, + CSSValueList: 0, + ClientRectList: 0, + DOMRectList: 0, + DOMStringList: 0, + DOMTokenList: 1, + DataTransferItemList: 0, + FileList: 0, + HTMLAllCollection: 0, + HTMLCollection: 0, + HTMLFormElement: 0, + HTMLSelectElement: 0, + MediaList: 0, + MimeTypeArray: 0, + NamedNodeMap: 0, + NodeList: 1, + PaintRequestList: 0, + Plugin: 0, + PluginArray: 0, + SVGLengthList: 0, + SVGNumberList: 0, + SVGPathSegList: 0, + SVGPointList: 0, + SVGStringList: 0, + SVGTransformList: 0, + SourceBufferList: 0, + StyleSheetList: 0, + TextTrackCueList: 0, + TextTrackList: 0, + TouchList: 0 + } + } + , function(t, e, n) { + "use strict"; + n = n(91)("span").classList, + n = n && n.constructor && n.constructor.prototype; + t.exports = n === Object.prototype ? void 0 : n + } + , function(e, t) { + !function(t) { + e.exports = t + } + .call(this, {}) + } + , function(t, e, n) { + "use strict"; + var i, o; + n(137), + n(221), + n(17), + n(53), + n(72), + n(11), + n(12), + n(228), + n(75), + n(133), + n(28); + function r(t) { + var e; + return (o[t] || (e = o[t] = { + i: t, + l: !1, + exports: {} + }, + i[t].call(e.exports, e, e.exports, r), + e.l = !0, + e)).exports + } + i = [function(t, e) { + t.exports = function(t) { + try { + return !!t() + } catch (t) { + return !0 + } + } + } + , function(t, e, n) { + var n = n(21) + , i = (o = Function.prototype).call + , o = n && o.bind.bind(i, i); + t.exports = n ? o : function(t) { + return function() { + return i.apply(t, arguments) + } + } + } + , function(t, e, n) { + var i = (n = n(39)).all; + t.exports = n.IS_HTMLDDA ? function(t) { + return "function" == typeof t || t === i + } + : function(t) { + return "function" == typeof t + } + } + , function(n, t, e) { + !function(t) { + function e(t) { + return t && t.Math == Math && t + } + n.exports = e("object" == typeof globalThis && globalThis) || e("object" == typeof window && window) || e("object" == typeof self && self) || e("object" == typeof t && t) || function() { + return this + }() || Function("return this")() + } + .call(this, e(36)) + } + , function(t, e, n) { + n = n(0), + t.exports = !n(function() { + return 7 != Object.defineProperty({}, 1, { + get: function() { + return 7 + } + })[1] + }) + } + , function(t, e, n) { + var i = n(1) + , o = n(29) + , r = i({}.hasOwnProperty); + t.exports = Object.hasOwn || function(t, e) { + return r(o(t), e) + } + } + , function(t, e, n) { + var i = n(3) + , o = n(26) + , r = n(5) + , s = n(47) + , a = n(42) + , l = n(41) + , c = o("wks") + , u = i.Symbol + , h = u && u.for + , d = l ? u : u && u.withoutSetter || s; + t.exports = function(t) { + var e; + return r(c, t) && (a || "string" == typeof c[t]) || (e = "Symbol." + t, + a && r(u, t) ? c[t] = u[t] : c[t] = (l && h ? h : d)(e)), + c[t] + } + } + , function(t, e, n) { + var i = n(9) + , o = String + , r = TypeError; + t.exports = function(t) { + if (i(t)) + return t; + throw r(o(t) + " is not an object") + } + } + , function(t, e, n) { + var n = n(21) + , i = Function.prototype.call; + t.exports = n ? i.bind(i) : function() { + return i.apply(i, arguments) + } + } + , function(t, e, n) { + var i = n(2) + , o = (n = n(39)).all; + t.exports = n.IS_HTMLDDA ? function(t) { + return "object" == typeof t ? null !== t : i(t) || t === o + } + : function(t) { + return "object" == typeof t ? null !== t : i(t) + } + } + , function(t, e, n) { + var i = n(4) + , o = n(48) + , r = n(50) + , s = n(7) + , a = n(24) + , l = TypeError + , c = Object.defineProperty + , u = Object.getOwnPropertyDescriptor + , h = "enumerable" + , d = "configurable" + , p = "writable"; + e.f = i ? r ? function(t, e, n) { + var i; + return s(t), + e = a(e), + s(n), + "function" == typeof t && "prototype" === e && "value"in n && p in n && !n[p] && (i = u(t, e)) && i[p] && (t[e] = n.value, + n = { + configurable: (d in n ? n : i)[d], + enumerable: (h in n ? n : i)[h], + writable: !1 + }), + c(t, e, n) + } + : c : function(t, e, n) { + if (s(t), + e = a(e), + s(n), + o) + try { + return c(t, e, n) + } catch (t) {} + if ("get"in n || "set"in n) + throw l("Accessors not supported"); + return "value"in n && (t[e] = n.value), + t + } + } + , function(t, e, n) { + var i = n(83) + , o = String; + t.exports = function(t) { + if ("Symbol" === i(t)) + throw TypeError("Cannot convert a Symbol value to a string"); + return o(t) + } + } + , function(t, e, n) { + var i = (n = n(1))({}.toString) + , o = n("".slice); + t.exports = function(t) { + return o(i(t), 8, -1) + } + } + , function(t, e, n) { + var i = n(23) + , o = TypeError; + t.exports = function(t) { + if (i(t)) + throw o("Can't call method on " + t); + return t + } + } + , function(t, e, n) { + var i = n(3) + , o = n(2); + t.exports = function(t, e) { + return arguments.length < 2 ? (n = i[t], + o(n) ? n : void 0) : i[t] && i[t][e]; + var n + } + } + , function(t, e, n) { + var i = n(71) + , o = n(13); + t.exports = function(t) { + return i(o(t)) + } + } + , function(t, e, n) { + n = n(14), + t.exports = n("navigator", "userAgent") || "" + } + , function(t, e, n) { + var i = n(4) + , o = n(10) + , r = n(22); + t.exports = i ? function(t, e, n) { + return o.f(t, e, r(1, n)) + } + : function(t, e, n) { + return t[e] = n, + t + } + } + , function(t, e, n) { + var i = n(81); + t.exports = function(t) { + return (t = +t) != t || 0 == t ? 0 : i(t) + } + } + , , function(t, e, n) { + var c = n(3) + , u = n(38).f + , h = n(17) + , d = n(30) + , p = n(28) + , f = n(78) + , g = n(57); + t.exports = function(t, e) { + var n, i, o, r = t.target, s = t.global, a = t.stat, l = s ? c : a ? c[r] || p(r, {}) : (c[r] || {}).prototype; + if (l) + for (n in e) { + if (i = e[n], + o = t.dontCallGetSet ? (o = u(l, n)) && o.value : l[n], + !g(s ? n : r + (a ? "." : "#") + n, t.forced) && void 0 !== o) { + if (typeof i == typeof o) + continue; + f(i, o) + } + (t.sham || o && o.sham) && h(i, "sham", !0), + d(l, n, i, t) + } + } + } + , function(t, e, n) { + n = n(0), + t.exports = !n(function() { + var t = function() {} + .bind(); + return "function" != typeof t || t.hasOwnProperty("prototype") + }) + } + , function(t, e) { + t.exports = function(t, e) { + return { + enumerable: !(1 & t), + configurable: !(2 & t), + writable: !(4 & t), + value: e + } + } + } + , function(t, e) { + t.exports = function(t) { + return null == t + } + } + , function(t, e, n) { + var i = n(72) + , o = n(40); + t.exports = function(t) { + return t = i(t, "string"), + o(t) ? t : t + "" + } + } + , function(t, e, n) { + n = n(1), + t.exports = n({}.isPrototypeOf) + } + , function(t, e, n) { + var i = n(74) + , o = n(27); + (t.exports = function(t, e) { + return o[t] || (o[t] = void 0 !== e ? e : {}) + } + )("versions", []).push({ + version: "3.26.1", + mode: i ? "pure" : "global", + copyright: "© 2014-2022 Denis Pushkarev (zloirock.ru)", + license: "https://github.com/zloirock/core-js/blob/v3.26.1/LICENSE", + source: "https://github.com/zloirock/core-js" + }) + } + , function(t, e, n) { + var i = n(3) + , n = n(28) + , o = "__core-js_shared__" + , i = i[o] || n(o, {}); + t.exports = i + } + , function(t, e, n) { + var i = n(3) + , o = Object.defineProperty; + t.exports = function(e, n) { + try { + o(i, e, { + value: n, + configurable: !0, + writable: !0 + }) + } catch (t) { + i[e] = n + } + return n + } + } + , function(t, e, n) { + var i = n(13) + , o = Object; + t.exports = function(t) { + return o(i(t)) + } + } + , function(t, e, n) { + var s = n(2) + , a = n(10) + , l = n(75) + , c = n(28); + t.exports = function(t, e, n, i) { + var o = (i = i || {}).enumerable + , r = void 0 !== i.name ? i.name : e; + if (s(n) && l(n, r, i), + i.global) + o ? t[e] = n : c(e, n); + else { + try { + i.unsafe ? t[e] && (o = !0) : delete t[e] + } catch (t) {} + o ? t[e] = n : a.f(t, e, { + value: n, + enumerable: !1, + configurable: !i.nonConfigurable, + writable: !i.nonWritable + }) + } + return t + } + } + , function(t, e, n) { + var i, o, r, s, a = n(77), l = n(3), c = n(9), u = n(17), h = n(5), d = n(27), p = n(52), n = n(32), f = "Object already initialized", g = l.TypeError, l = l.WeakMap, m = a || d.state ? ((r = d.state || (d.state = new l)).get = r.get, + r.has = r.has, + r.set = r.set, + i = function(t, e) { + if (r.has(t)) + throw g(f); + return e.facade = t, + r.set(t, e), + e + } + , + o = function(t) { + return r.get(t) || {} + } + , + function(t) { + return r.has(t) + } + ) : (n[s = p("state")] = !0, + i = function(t, e) { + if (h(t, s)) + throw g(f); + return e.facade = t, + u(t, s, e), + e + } + , + o = function(t) { + return h(t, s) ? t[s] : {} + } + , + function(t) { + return h(t, s) + } + ); + t.exports = { + set: i, + get: o, + has: m, + enforce: function(t) { + return m(t) ? o(t) : i(t, {}) + }, + getterFor: function(e) { + return function(t) { + if (c(t) && (t = o(t)).type === e) + return t; + throw g("Incompatible receiver, " + e + " required") + } + } + } + } + , function(t, e) { + t.exports = {} + } + , function(t, e, n) { + var i = n(56); + t.exports = function(t) { + return i(t.length) + } + } + , function(t, e) { + t.exports = ["constructor", "hasOwnProperty", "isPrototypeOf", "propertyIsEnumerable", "toLocaleString", "toString", "valueOf"] + } + , function(t, e, n) { + var f = n(8) + , i = n(1) + , g = n(11) + , m = n(58) + , o = n(59) + , r = n(26) + , b = n(85) + , v = n(31).get + , s = n(60) + , n = n(61) + , _ = r("native-string-replace", String.prototype.replace) + , y = RegExp.prototype.exec + , w = y + , O = i("".charAt) + , x = i("".indexOf) + , S = i("".replace) + , C = i("".slice) + , E = (r = /b*/g, + f(y, i = /a/, "a"), + f(y, r, "a"), + 0 !== i.lastIndex || 0 !== r.lastIndex) + , k = o.BROKEN_CARET + , A = void 0 !== /()??/.exec("")[1]; + (E || A || k || s || n) && (w = function(t) { + var e, n, i, o, r, s, a = this, l = v(a), t = g(t); + if (u = l.raw) + return u.lastIndex = a.lastIndex, + h = f(w, u, t), + a.lastIndex = u.lastIndex, + h; + var c = l.groups + , u = k && a.sticky + , h = f(m, a) + , l = a.source + , d = 0 + , p = t; + if (u && (h = S(h, "y", ""), + -1 === x(h, "g") && (h += "g"), + p = C(t, a.lastIndex), + 0 < a.lastIndex && (!a.multiline || a.multiline && "\n" !== O(t, a.lastIndex - 1)) && (l = "(?: " + l + ")", + p = " " + p, + d++), + e = new RegExp("^(?:" + l + ")",h)), + A && (e = new RegExp("^" + l + "$(?!\\s)",h)), + E && (n = a.lastIndex), + i = f(y, u ? e : a, p), + u ? i ? (i.input = C(i.input, d), + i[0] = C(i[0], d), + i.index = a.lastIndex, + a.lastIndex += i[0].length) : a.lastIndex = 0 : E && i && (a.lastIndex = a.global ? i.index + i[0].length : n), + A && i && 1 < i.length && f(_, i[0], e, function() { + for (o = 1; o < arguments.length - 2; o++) + void 0 === arguments[o] && (i[o] = void 0) + }), + i && c) + for (i.groups = r = b(null), + o = 0; o < c.length; o++) + r[(s = c[o])[0]] = i[s[1]]; + return i + } + ), + t.exports = w + } + , function(t, e) { + var n = function() { + return this + }(); + try { + n = n || new Function("return this")() + } catch (t) { + "object" == typeof window && (n = window) + } + t.exports = n + } + , function(t, e, n) { + var i = n(20) + , n = n(35); + i({ + target: "RegExp", + proto: !0, + forced: /./.exec !== n + }, { + exec: n + }) + } + , function(t, e, n) { + var i = n(4) + , o = n(8) + , r = n(70) + , s = n(22) + , a = n(15) + , l = n(24) + , c = n(5) + , u = n(48) + , h = Object.getOwnPropertyDescriptor; + e.f = i ? h : function(t, e) { + if (t = a(t), + e = l(e), + u) + try { + return h(t, e) + } catch (t) {} + if (c(t, e)) + return s(!o(r.f, t, e), t[e]) + } + } + , function(t, e) { + var n = "object" == typeof document && document.all; + t.exports = { + all: n, + IS_HTMLDDA: void 0 === n && void 0 !== n + } + } + , function(t, e, n) { + var i = n(14) + , o = n(2) + , r = n(25) + , n = n(41) + , s = Object; + t.exports = n ? function(t) { + return "symbol" == typeof t + } + : function(t) { + var e = i("Symbol"); + return o(e) && r(e.prototype, s(t)) + } + } + , function(t, e, n) { + n = n(42), + t.exports = n && !Symbol.sham && "symbol" == typeof Symbol.iterator + } + , function(t, e, n) { + var i = n(43) + , n = n(0); + t.exports = !!Object.getOwnPropertySymbols && !n(function() { + var t = Symbol(); + return !String(t) || !(Object(t)instanceof Symbol) || !Symbol.sham && i && i < 41 + }) + } + , function(t, e, n) { + var i, o, r = n(3), n = n(16), s = r.process, r = r.Deno; + !(o = (r = (s = s && s.versions || r && r.version) && s.v8) ? 0 < (i = r.split("."))[0] && i[0] < 4 ? 1 : +(i[0] + i[1]) : o) && n && (!(i = n.match(/Edge\/(\d+)/)) || 74 <= i[1]) && (i = n.match(/Chrome\/(\d+)/)) && (o = +i[1]), + t.exports = o + } + , function(t, e, n) { + var i = n(45) + , o = n(23); + t.exports = function(t, e) { + return t = t[e], + o(t) ? void 0 : i(t) + } + } + , function(t, e, n) { + var i = n(2) + , o = n(46) + , r = TypeError; + t.exports = function(t) { + if (i(t)) + return t; + throw r(o(t) + " is not a function") + } + } + , function(t, e) { + var n = String; + t.exports = function(t) { + try { + return n(t) + } catch (t) { + return "Object" + } + } + } + , function(t, e, n) { + var n = n(1) + , i = 0 + , o = Math.random() + , r = n(1..toString); + t.exports = function(t) { + return "Symbol(" + (void 0 === t ? "" : t) + ")_" + r(++i + o, 36) + } + } + , function(t, e, n) { + var i = n(4) + , o = n(0) + , r = n(49); + t.exports = !i && !o(function() { + return 7 != Object.defineProperty(r("div"), "a", { + get: function() { + return 7 + } + }).a + }) + } + , function(t, e, n) { + var i = n(3) + , n = n(9) + , o = i.document + , r = n(o) && n(o.createElement); + t.exports = function(t) { + return r ? o.createElement(t) : {} + } + } + , function(t, e, n) { + var i = n(4) + , n = n(0); + t.exports = i && n(function() { + return 42 != Object.defineProperty(function() {}, "prototype", { + value: 42, + writable: !1 + }).prototype + }) + } + , function(t, e, n) { + var i = n(4) + , n = n(5) + , o = Function.prototype + , r = i && Object.getOwnPropertyDescriptor + , s = (n = n(o, "name")) && "something" === function() {} + .name + , i = n && (!i || r(o, "name").configurable); + t.exports = { + EXISTS: n, + PROPER: s, + CONFIGURABLE: i + } + } + , function(t, e, n) { + var i = n(26) + , o = n(47) + , r = i("keys"); + t.exports = function(t) { + return r[t] || (r[t] = o(t)) + } + } + , function(t, e, n) { + var i = n(54) + , o = n(34).concat("length", "prototype"); + e.f = Object.getOwnPropertyNames || function(t) { + return i(t, o) + } + } + , function(t, e, n) { + var i = n(1) + , s = n(5) + , a = n(15) + , l = n(80).indexOf + , c = n(32) + , u = i([].push); + t.exports = function(t, e) { + var n, i = a(t), o = 0, r = []; + for (n in i) + !s(c, n) && s(i, n) && u(r, n); + for (; e.length > o; ) + s(i, n = e[o++]) && !~l(r, n) && u(r, n); + return r + } + } + , function(t, e, n) { + var i = n(18) + , o = Math.max + , r = Math.min; + t.exports = function(t, e) { + return (t = i(t)) < 0 ? o(t + e, 0) : r(t, e) + } + } + , function(t, e, n) { + var i = n(18) + , o = Math.min; + t.exports = function(t) { + return 0 < t ? o(i(t), 9007199254740991) : 0 + } + } + , function(t, e, n) { + function i(t, e) { + return (t = l[a(t)]) == u || t != c && (r(e) ? o(e) : !!e) + } + var o = n(0) + , r = n(2) + , s = /#|\.prototype\./ + , a = i.normalize = function(t) { + return String(t).replace(s, ".").toLowerCase() + } + , l = i.data = {} + , c = i.NATIVE = "N" + , u = i.POLYFILL = "P"; + t.exports = i + } + , function(t, e, n) { + var i = n(7); + t.exports = function() { + var t = i(this) + , e = ""; + return t.hasIndices && (e += "d"), + t.global && (e += "g"), + t.ignoreCase && (e += "i"), + t.multiline && (e += "m"), + t.dotAll && (e += "s"), + t.unicode && (e += "u"), + t.unicodeSets && (e += "v"), + t.sticky && (e += "y"), + e + } + } + , function(t, e, n) { + var i = n(0) + , o = n(3).RegExp + , r = (n = i(function() { + var t = o("a", "y"); + return t.lastIndex = 2, + null != t.exec("abcd") + })) || i(function() { + return !o("a", "y").sticky + }) + , i = n || i(function() { + var t = o("^r", "gy"); + return t.lastIndex = 2, + null != t.exec("str") + }); + t.exports = { + BROKEN_CARET: i, + MISSED_STICKY: r, + UNSUPPORTED_Y: n + } + } + , function(t, e, n) { + var i = n(0) + , o = n(3).RegExp; + t.exports = i(function() { + var t = o(".", "s"); + return !(t.dotAll && t.exec("\n") && "s" === t.flags) + }) + } + , function(t, e, n) { + var i = n(0) + , o = n(3).RegExp; + t.exports = i(function() { + var t = o("(?b)", "g"); + return "b" !== t.exec("b").groups.a || "bc" !== "b".replace(t, "$c") + }) + } + , function(t, e) { + t.exports = "\t\n\v\f\r                 \u2028\u2029\ufeff" + } + , , , , , , function(t, e, Z) { + Z.r(e), + function(t, e) { + Z(37), + Z(89), + Z(97), + Z(105), + Z(108); + var a, D, T, o, s, N, H, n, l, i, r, c, u, B, h, d, p, f, g, m, b, W, Y, F, v, X, z, _, y, w, O, x, S, C = "undefined" != typeof window ? window : "undefined" != typeof WorkerGlobalScope && self instanceof WorkerGlobalScope ? self : {}, E = (a = /\blang(?:uage)?-([\w-]+)\b/i, + D = 0, + T = C.Prism = { + manual: C.Prism && C.Prism.manual, + disableWorkerMessageHandler: C.Prism && C.Prism.disableWorkerMessageHandler, + util: { + encode: function(t) { + return t instanceof o ? new o(t.type,T.util.encode(t.content),t.alias) : "Array" === T.util.type(t) ? t.map(T.util.encode) : t.replace(/&/g, "&").replace(/ t.length) + return; + if (!(y instanceof l)) { + if (f && v != e.length - 1) { + if (b.lastIndex = _, + !(E = b.exec(t))) + break; + for (var w = E.index + (p ? E[1].length : 0), O = E.index + E[0].length, x = v, S = _, C = e.length; x < C && (S < O || !e[x].type && !e[x - 1].greedy); ++x) + (S += e[x].length) <= w && (++v, + _ = S); + if (e[v]instanceof l) + continue; + k = x - v, + y = t.slice(_, S), + E.index -= _ + } else { + b.lastIndex = 0; + var E = b.exec(y) + , k = 1 + } + if (E) { + p && (g = E[1] ? E[1].length : 0); + var O = (w = E.index + g) + (E = E[0].slice(g)).length + , A = y.slice(0, w) + , y = y.slice(O) + , j = [v, k] + , A = (A && (++v, + _ += A.length, + j.push(A)), + new l(a,d ? T.tokenize(E, d) : E,m,E,f)); + if (j.push(A), + y && j.push(y), + Array.prototype.splice.apply(e, j), + 1 != k && T.matchGrammar(t, e, n, v, _, !0, a), + r) + break + } else if (r) + break + } + } + } + } + }, + tokenize: function(t, e, n) { + var i = [t] + , o = e.rest; + if (o) { + for (var r in o) + e[r] = o[r]; + delete e.rest + } + return T.matchGrammar(t, i, e, 0, 0, !1), + i + }, + hooks: { + all: {}, + add: function(t, e) { + var n = T.hooks.all; + n[t] = n[t] || [], + n[t].push(e) + }, + run: function(t, e) { + var n = T.hooks.all[t]; + if (n && n.length) + for (var i, o = 0; i = n[o++]; ) + i(e) + } + } + }, + (o = T.Token = function(t, e, n, i, o) { + this.type = t, + this.content = e, + this.alias = n, + this.length = 0 | (i || "").length, + this.greedy = !!o + } + ).stringify = function(e, n, t) { + var i; + return "string" == typeof e ? e : "Array" === T.util.type(e) ? e.map(function(t) { + return o.stringify(t, n, e) + }).join("") : (i = { + type: e.type, + content: o.stringify(e.content, n, t), + tag: "span", + classes: ["token", e.type], + attributes: {}, + language: n, + parent: t + }, + e.alias && (t = "Array" === T.util.type(e.alias) ? e.alias : [e.alias], + Array.prototype.push.apply(i.classes, t)), + T.hooks.run("wrap", i), + t = Object.keys(i.attributes).map(function(t) { + return t + '="' + (i.attributes[t] || "").replace(/"/g, """) + '"' + }).join(" "), + "<" + i.tag + ' class="' + i.classes.join(" ") + '"' + (t ? " " + t : "") + ">" + i.content + "") + } + , + C.document ? (_ = document.currentScript || [].slice.call(document.getElementsByTagName("script")).pop()) && (T.filename = _.src, + T.manual || _.hasAttribute("data-manual") || ("loading" !== document.readyState ? window.requestAnimationFrame ? window.requestAnimationFrame(T.highlightAll) : window.setTimeout(T.highlightAll, 16) : document.addEventListener("DOMContentLoaded", T.highlightAll))) : C.addEventListener && !T.disableWorkerMessageHandler && C.addEventListener("message", function(t) { + var e = (t = JSON.parse(t.data)).language + , n = t.code + , t = t.immediateClose; + C.postMessage(T.highlight(n, T.languages[e], e)), + t && C.close() + }, !1), + C.Prism); + function k(t, e) { + return t = t.replace(//g, function() { + return N + }).replace(//g, function() { + return H + }).replace(//g, function() { + return n + }), + RegExp(t, e) + } + function A(t, n) { + return t.replace(/<<(\d+)>>/g, function(t, e) { + return "(?:" + n[+e] + ")" + }) + } + function j(t, e, n) { + return RegExp(A(t, e), n || "") + } + function L(t, e) { + for (var n = 0; n < e; n++) + t = t.replace(/<>/g, function() { + return "(?:" + t + ")" + }); + return t.replace(/<>/g, "[^\\s\\S]") + } + function P(t) { + return "\\b(?:" + t.trim().replace(/ /g, "|") + ")\\b" + } + function U(t, e) { + return { + interpolation: { + pattern: j(/((?:^|[^{])(?:\{\{)*)<<0>>/.source, [t]), + lookbehind: !0, + inside: { + "format-string": { + pattern: j(/(^\{(?:(?![}:])<<0>>)*)<<1>>(?=\}$)/.source, [e, h]), + lookbehind: !0, + inside: { + punctuation: /^:/ + } + }, + punctuation: /^\{|\}$/, + expression: { + pattern: /[\s\S]+/, + alias: "language-csharp", + inside: i.languages.csharp + } + } + }, + string: /[\s\S]+/ + } + } + if (t.exports && (t.exports = E), + void 0 !== e && (e.Prism = E), + E.languages.markup = { + comment: //, + prolog: /<\?[\s\S]+?\?>/, + doctype: //i, + cdata: //i, + tag: { + pattern: /<\/?(?!\d)[^\s>\/=$<%]+(?:\s+[^\s>\/=]+(?:=(?:("|')(?:\\[\s\S]|(?!\1)[^\\])*\1|[^\s'">=]+))?)*\s*\/?>/i, + greedy: !0, + inside: { + tag: { + pattern: /^<\/?[^\s>\/]+/i, + inside: { + punctuation: /^<\/?/, + namespace: /^[^\s>\/:]+:/ + } + }, + "special-attr": [], + "attr-value": { + pattern: /=(?:("|')(?:\\[\s\S]|(?!\1)[^\\])*\1|[^\s'">=]+)/i, + inside: { + punctuation: [/^=/, { + pattern: /(^|[^\\])["']/, + lookbehind: !0 + }] + } + }, + punctuation: /\/?>/, + "attr-name": { + pattern: /[^\s>\/]+/, + inside: { + namespace: /^[^\s>\/:]+:/ + } + } + } + }, + entity: /&#?[\da-z]{1,8};/i + }, + E.languages.markup.tag.inside["attr-value"].inside.entity = E.languages.markup.entity, + E.hooks.add("wrap", function(t) { + "entity" === t.type && (t.attributes.title = t.content.replace(/&/, "&")) + }), + E.languages.xml = E.languages.markup, + E.languages.html = E.languages.markup, + E.languages.mathml = E.languages.markup, + E.languages.svg = E.languages.markup, + E.languages.css = { + comment: /\/\*[\s\S]*?\*\//, + atrule: { + pattern: /@[\w-]+?.*?(?:;|(?=\s*\{))/i, + inside: { + rule: /@[\w-]+/ + } + }, + url: /url\((?:(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1|.*?)\)/i, + selector: /[^{}\s][^{};]*?(?=\s*\{)/, + string: { + pattern: /("|')(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/, + greedy: !0 + }, + property: /[-_a-z\xA0-\uFFFF][-\w\xA0-\uFFFF]*(?=\s*:)/i, + important: /\B!important\b/i, + function: /[-a-z0-9]+(?=\()/i, + punctuation: /[(){};:]/ + }, + E.languages.css.atrule.inside.rest = E.languages.css, + E.languages.markup && (E.languages.insertBefore("markup", "tag", { + style: { + pattern: /()[\s\S]*?(?=<\/style>)/i, + lookbehind: !0, + inside: E.languages.css, + alias: "language-css", + greedy: !0 + } + }), + E.languages.insertBefore("inside", "attr-value", { + "style-attr": { + pattern: /\s*style=("|')(?:\\[\s\S]|(?!\1)[^\\])*\1/i, + inside: { + "attr-name": { + pattern: /^\s*style/i, + inside: E.languages.markup.tag.inside + }, + punctuation: /^\s*=\s*['"]|['"]\s*$/, + "attr-value": { + pattern: /.+/i, + inside: E.languages.css + } + }, + alias: "language-css" + } + }, E.languages.markup.tag)), + E.languages.clike = { + comment: [{ + pattern: /(^|[^\\])\/\*[\s\S]*?(?:\*\/|$)/, + lookbehind: !0 + }, { + pattern: /(^|[^\\:])\/\/.*/, + lookbehind: !0, + greedy: !0 + }], + string: { + pattern: /(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/, + greedy: !0 + }, + "class-name": { + pattern: /((?:\b(?:class|interface|extends|implements|trait|instanceof|new)\s+)|(?:catch\s+\())[\w.\\]+/i, + lookbehind: !0, + inside: { + punctuation: /[.\\]/ + } + }, + keyword: /\b(?:if|else|while|do|for|return|in|instanceof|function|new|try|throw|catch|finally|null|break|continue)\b/, + boolean: /\b(?:true|false)\b/, + function: /[a-z0-9_]+(?=\()/i, + number: /\b0x[\da-f]+\b|(?:\b\d+\.?\d*|\B\.\d+)(?:e[+-]?\d+)?/i, + operator: /--?|\+\+?|!=?=?|<=?|>=?|==?=?|&&?|\|\|?|\?|\*|\/|~|\^|%/, + punctuation: /[{}[\];(),.:]/ + }, + E.languages.javascript = E.languages.extend("clike", { + "class-name": [E.languages.clike["class-name"], { + pattern: /(^|[^$\w\xA0-\uFFFF])(?!\s)[_$A-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\.(?:constructor|prototype))/, + lookbehind: !0 + }], + keyword: /\b(?:as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|var|void|while|with|yield)\b/, + number: /\b(?:0[xX][\dA-Fa-f]+|0[bB][01]+|0[oO][0-7]+|NaN|Infinity)\b|(?:\b\d+\.?\d*|\B\.\d+)(?:[Ee][+-]?\d+)?/, + function: /[_$a-z\xA0-\uFFFF][$\w\xA0-\uFFFF]*(?=\s*\()/i, + operator: /-[-=]?|\+[+=]?|!=?=?|<>?>?=?|=(?:==?|>)?|&[&=]?|\|[|=]?|\*\*?=?|\/=?|~|\^=?|%=?|\?|\.{3}/ + }), + E.languages.javascript["class-name"][0].pattern = /(\b(?:class|extends|implements|instanceof|interface|new)\s+)[\w.\\]+/, + E.languages.insertBefore("javascript", "keyword", { + regex: { + pattern: /((?:^|[^$\w\xA0-\uFFFF."'\])\s])\s*)\/(\[[^\]\r\n]+]|\\.|[^/\\\[\r\n])+\/[gimyu]{0,5}(?=\s*($|[\r\n,.;})\]]))/, + lookbehind: !0, + greedy: !0, + inside: { + "regex-source": { + pattern: /^(\/)[\s\S]+(?=\/[a-z]*$)/, + lookbehind: !0, + alias: "language-regex", + inside: E.languages.regex + }, + "regex-delimiter": /^\/|\/$/, + "regex-flags": /^[a-z]+$/ + } + }, + "function-variable": { + pattern: /[_$a-z\xA0-\uFFFF][$\w\xA0-\uFFFF]*(?=\s*=\s*(?:function\b|(?:\([^()]*\)|[_$a-z\xA0-\uFFFF][$\w\xA0-\uFFFF]*)\s*=>))/i, + alias: "function" + }, + constant: /\b[A-Z][A-Z\d_]*\b/ + }), + E.languages.insertBefore("javascript", "string", { + hashbang: { + pattern: /^#!.*/, + greedy: !0, + alias: "comment" + }, + "string-property": { + pattern: /((?:^|[,{])[ \t]*)(["'])(?:\\(?:\r\n|[\s\S])|(?!\2)[^\\\r\n])*\2(?=\s*:)/m, + lookbehind: !0, + greedy: !0, + alias: "property" + }, + "template-string": { + pattern: /`(?:\\[\s\S]|\${[^}]+}|[^\\`])*`/, + greedy: !0, + inside: { + interpolation: { + pattern: /\${[^}]+}/, + inside: { + "interpolation-punctuation": { + pattern: /^\${|}$/, + alias: "punctuation" + }, + rest: null + } + }, + string: /[\s\S]+/ + } + } + }), + E.languages.insertBefore("javascript", "operator", { + "literal-property": { + pattern: /((?:^|[,{])[ \t]*)(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*:)/m, + lookbehind: !0, + alias: "property" + } + }), + E.languages.javascript["template-string"].inside.interpolation.inside.rest = E.languages.javascript, + Object.defineProperty(E.languages.markup.tag, "addInlined", { + value: function(t, e) { + var n = {}; + n["language-" + e] = { + pattern: /(^$)/i, + lookbehind: !0, + inside: E.languages[e] + }, + n.cdata = /^$/i, + (n = { + "included-cdata": { + pattern: //i, + inside: n + } + })["language-" + e] = { + pattern: /[\s\S]+/, + inside: E.languages[e] + }, + (e = {})[t] = { + pattern: RegExp(/(<__[^>]*>)(?:))*\]\]>|(?!)/.source.replace(/__/g, function() { + return t + }), "i"), + lookbehind: !0, + greedy: !0, + inside: n + }, + E.languages.insertBefore("markup", "cdata", e) + } + }), + Object.defineProperty(E.languages.markup.tag, "addAttribute", { + value: function(t, e) { + E.languages.markup.tag.inside["special-attr"].push({ + pattern: RegExp(/(^|["'\s])/.source + "(?:" + t + ")" + /\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))/.source, "i"), + lookbehind: !0, + inside: { + "attr-name": /^[^\s=]+/, + "attr-value": { + pattern: /=[\s\S]+/, + inside: { + value: { + pattern: /(^=\s*(["']|(?!["'])))\S[\s\S]*(?=\2$)/, + lookbehind: !0, + alias: [e, "language-" + e], + inside: E.languages[e] + }, + punctuation: [{ + pattern: /^=/, + alias: "attr-equals" + }, /"|'/] + } + } + } + }) + } + }), + E.languages.markup && (E.languages.insertBefore("markup", "tag", { + script: { + pattern: /()[\s\S]*?(?=<\/script>)/i, + lookbehind: !0, + inside: E.languages.javascript, + alias: "language-javascript", + greedy: !0 + } + }), + E.languages.markup.tag.addInlined("script", "javascript"), + E.languages.markup.tag.addAttribute(/on(?:abort|blur|change|click|composition(?:end|start|update)|dblclick|error|focus(?:in|out)?|key(?:down|up)|load|mouse(?:down|enter|leave|move|out|over|up)|reset|resize|scroll|select|slotchange|submit|unload|wheel)/.source, "javascript")), + E.languages.js = E.languages.javascript, + E.languages["markup-templating"] = {}, + Object.defineProperties(E.languages["markup-templating"], { + buildPlaceholders: { + value: function(n, i, t, o) { + n.language === i && (n.tokenStack = [], + n.code = n.code.replace(t, function(t) { + if ("function" == typeof o && !o(t)) + return t; + for (var e = n.tokenStack.length; -1 !== n.code.indexOf("___" + i.toUpperCase() + e + "___"); ) + ++e; + return n.tokenStack[e] = t, + "___" + i.toUpperCase() + e + "___" + }), + n.grammar = E.languages.markup) + } + }, + tokenizePlaceholders: { + value: function(c, u) { + var h, d, p; + c.language === u && c.tokenStack && (c.grammar = E.languages[u], + h = 0, + d = Object.keys(c.tokenStack), + (p = function(t) { + if (!(h >= d.length)) + for (var e = 0; e < t.length; e++) { + var n = t[e]; + if ("string" == typeof n || n.content && "string" == typeof n.content) { + var i = d[h] + , o = c.tokenStack[i] + , r = (l = "string" == typeof n ? n : n.content).indexOf("___" + u.toUpperCase() + i + "___"); + if (-1 < r) { + ++h; + var s, a = l.substring(0, r), o = new E.Token(u,E.tokenize(o, c.grammar, u),"language-" + u,o), l = l.substring(r + ("___" + u.toUpperCase() + i + "___").length); + if (a || l ? (s = [a, o, l].filter(function(t) { + return !!t + }), + p(s)) : s = o, + "string" == typeof n ? Array.prototype.splice.apply(t, [e, 1].concat(s)) : n.content = s, + h >= d.length) + break + } + } else + n.content && "string" != typeof n.content && p(n.content) + } + } + )(c.tokens)) + } + } + }), + E.languages.json = { + property: /"(?:\\.|[^\\"\r\n])*"(?=\s*:)/i, + string: { + pattern: /"(?:\\.|[^\\"\r\n])*"(?!\s*:)/, + greedy: !0 + }, + number: /\b0x[\dA-Fa-f]+\b|(?:\b\d+\.?\d*|\B\.\d+)(?:[Ee][+-]?\d+)?/, + punctuation: /[{}[\]);,]/, + operator: /:/g, + boolean: /\b(?:true|false)\b/i, + null: /\bnull\b/i + }, + E.languages.jsonp = E.languages.json, + _ = (s = E).util.clone(s.languages.javascript), + N = /(?:\s|\/\/.*(?!.)|\/\*(?:[^*]|\*(?!\/))\*\/)/.source, + H = /(?:\{(?:\{(?:\{[^{}]*\}|[^{}])*\}|[^{}])*\})/.source, + n = k(n = /(?:\{*\.{3}(?:[^{}]|)*\})/.source).source, + s.languages.jsx = s.languages.extend("markup", _), + s.languages.jsx.tag.pattern = k(/<\/?(?:[\w.:-]+(?:+(?:[\w.:$-]+(?:=(?:"(?:\\[\s\S]|[^\\"])*"|'(?:\\[\s\S]|[^\\'])*'|[^\s{'"/>=]+|))?|))**\/?)?>/.source), + s.languages.jsx.tag.inside.tag.pattern = /^<\/?[^\s>\/]*/, + s.languages.jsx.tag.inside["attr-value"].pattern = /=(?!\{)(?:"(?:\\[\s\S]|[^\\"])*"|'(?:\\[\s\S]|[^\\'])*'|[^\s'">]+)/, + s.languages.jsx.tag.inside.tag.inside["class-name"] = /^[A-Z]\w*(?:\.[A-Z]\w*)*$/, + s.languages.jsx.tag.inside.comment = _.comment, + s.languages.insertBefore("inside", "attr-name", { + spread: { + pattern: k(//.source), + inside: s.languages.jsx + } + }, s.languages.jsx.tag), + s.languages.insertBefore("inside", "special-attr", { + script: { + pattern: k(/=/.source), + alias: "language-javascript", + inside: { + "script-punctuation": { + pattern: /^=(?=\{)/, + alias: "punctuation" + }, + rest: s.languages.jsx + } + } + }, s.languages.jsx.tag), + l = function(t) { + return t ? "string" == typeof t ? t : "string" == typeof t.content ? t.content : t.content.map(l).join("") : "" + } + , + s.hooks.add("after-tokenize", function(t) { + "jsx" !== t.language && "tsx" !== t.language || function t(e) { + for (var n = [], i = 0; i < e.length; i++) { + var o = e[i] + , r = !1; + "string" != typeof o && ("tag" === o.type && o.content[0] && "tag" === o.content[0].type ? "" !== o.content[o.content.length - 1].content && n.push({ + tagName: l(o.content[0].content[1]), + openedBraces: 0 + }) : 0 < n.length && "punctuation" === o.type && "{" === o.content ? n[n.length - 1].openedBraces++ : 0 < n.length && 0 < n[n.length - 1].openedBraces && "punctuation" === o.type && "}" === o.content ? n[n.length - 1].openedBraces-- : r = !0), + (r || "string" == typeof o) && 0 < n.length && 0 === n[n.length - 1].openedBraces && (r = l(o), + i < e.length - 1 && ("string" == typeof e[i + 1] || "plain-text" === e[i + 1].type) && (r += l(e[i + 1]), + e.splice(i + 1, 1)), + 0 < i && ("string" == typeof e[i - 1] || "plain-text" === e[i - 1].type) && (r = l(e[i - 1]) + r, + e.splice(i - 1, 1), + i--), + e[i] = new s.Token("plain-text",r,null,r)), + o.content && "string" != typeof o.content && t(o.content) + } + }(t.tokens) + }), + i = E, + e = "bool byte char decimal double dynamic float int long object sbyte short string uint ulong ushort var void", + _ = "add alias and ascending async await by descending from(?=\\s*(?:\\w|$)) get global group into init(?=\\s*;) join let nameof not notnull on or orderby partial remove select set unmanaged value when where with(?=\\s*{)", + S = "abstract as base break case catch checked const continue default delegate do else event explicit extern finally fixed for foreach goto if implicit in internal is lock namespace new null operator out override params private protected public readonly ref return sealed sizeof stackalloc static switch this throw try typeof unchecked unsafe using virtual volatile while yield", + g = P(b = "class enum interface record struct"), + r = RegExp(P(e + " " + b + " " + _ + " " + S)), + _ = P(b + " " + _ + " " + S), + e = P(e + " " + b + " " + S), + b = L(/<(?:[^<>;=+\-*/%&|^]|<>)*>/.source, 2), + S = L(/\((?:[^()]|<>)*\)/.source, 2), + c = A(/<<0>>(?:\s*<<1>>)?/.source, [f = /@?\b[A-Za-z_]\w*\b/.source, b]), + _ = A(/(?!<<0>>)<<1>>(?:\s*\.\s*<<1>>)*/.source, [_, c]), + x = A(/<<0>>(?:\s*(?:\?\s*)?<<1>>)*(?:\s*\?)?/.source, [_, d = /\[\s*(?:,\s*)*\]/.source]), + u = A(/[^,()<>[\];=+\-*/%&|^]|<<0>>|<<1>>|<<2>>/.source, [b, S, d]), + u = A(/\(<<0>>+(?:,<<0>>+)+\)/.source, [u]), + u = A(/(?:<<0>>|<<1>>)(?:\s*(?:\?\s*)?<<2>>)*(?:\s*\?)?/.source, [u, _, d]), + d = { + keyword: r, + punctuation: /[<>()?,.:[\]]/ + }, + B = /'(?:[^\r\n'\\]|\\.|\\[Uux][\da-fA-F]{1,8})'/.source, + p = /"(?:\\.|[^\\"\r\n])*"/.source, + i.languages.csharp = i.languages.extend("clike", { + string: [{ + pattern: j(/(^|[^$\\])<<0>>/.source, [/@"(?:""|\\[\s\S]|[^\\"])*"(?!")/.source]), + lookbehind: !0, + greedy: !0 + }, { + pattern: j(/(^|[^@$\\])<<0>>/.source, [p]), + lookbehind: !0, + greedy: !0 + }], + "class-name": [{ + pattern: j(/(\busing\s+static\s+)<<0>>(?=\s*;)/.source, [_]), + lookbehind: !0, + inside: d + }, { + pattern: j(/(\busing\s+<<0>>\s*=\s*)<<1>>(?=\s*;)/.source, [f, u]), + lookbehind: !0, + inside: d + }, { + pattern: j(/(\busing\s+)<<0>>(?=\s*=)/.source, [f]), + lookbehind: !0 + }, { + pattern: j(/(\b<<0>>\s+)<<1>>/.source, [g, c]), + lookbehind: !0, + inside: d + }, { + pattern: j(/(\bcatch\s*\(\s*)<<0>>/.source, [_]), + lookbehind: !0, + inside: d + }, { + pattern: j(/(\bwhere\s+)<<0>>/.source, [f]), + lookbehind: !0 + }, { + pattern: j(/(\b(?:is(?:\s+not)?|as)\s+)<<0>>/.source, [x]), + lookbehind: !0, + inside: d + }, { + pattern: j(/\b<<0>>(?=\s+(?!<<1>>|with\s*\{)<<2>>(?:\s*[=,;:{)\]]|\s+(?:in|when)\b))/.source, [u, e, f]), + inside: d + }], + keyword: r, + number: /(?:\b0(?:x[\da-f_]*[\da-f]|b[01_]*[01])|(?:\B\.\d+(?:_+\d+)*|\b\d+(?:_+\d+)*(?:\.\d+(?:_+\d+)*)?)(?:e[-+]?\d+(?:_+\d+)*)?)(?:[dflmu]|lu|ul)?\b/i, + operator: />>=?|<<=?|[-=]>|([-+&|])\1|~|\?\?=?|[-+*/%&|^!=<>]=?/, + punctuation: /\?\.?|::|[{}[\];(),.:]/ + }), + i.languages.insertBefore("csharp", "number", { + range: { + pattern: /\.\./, + alias: "operator" + } + }), + i.languages.insertBefore("csharp", "punctuation", { + "named-parameter": { + pattern: j(/([(,]\s*)<<0>>(?=\s*:)/.source, [f]), + lookbehind: !0, + alias: "punctuation" + } + }), + i.languages.insertBefore("csharp", "class-name", { + namespace: { + pattern: j(/(\b(?:namespace|using)\s+)<<0>>(?:\s*\.\s*<<0>>)*(?=\s*[;{])/.source, [f]), + lookbehind: !0, + inside: { + punctuation: /\./ + } + }, + "type-expression": { + pattern: j(/(\b(?:default|sizeof|typeof)\s*\(\s*(?!\s))(?:[^()\s]|\s(?!\s)|<<0>>)*(?=\s*\))/.source, [S]), + lookbehind: !0, + alias: "class-name", + inside: d + }, + "return-type": { + pattern: j(/<<0>>(?=\s+(?:<<1>>\s*(?:=>|[({]|\.\s*this\s*\[)|this\s*\[))/.source, [u, _]), + inside: d, + alias: "class-name" + }, + "constructor-invocation": { + pattern: j(/(\bnew\s+)<<0>>(?=\s*[[({])/.source, [u]), + lookbehind: !0, + inside: d, + alias: "class-name" + }, + "generic-method": { + pattern: j(/<<0>>\s*<<1>>(?=\s*\()/.source, [f, b]), + inside: { + function: j(/^<<0>>/.source, [f]), + generic: { + pattern: RegExp(b), + alias: "class-name", + inside: d + } + } + }, + "type-list": { + pattern: j(/\b((?:<<0>>\s+<<1>>|record\s+<<1>>\s*<<5>>|where\s+<<2>>)\s*:\s*)(?:<<3>>|<<4>>|<<1>>\s*<<5>>|<<6>>)(?:\s*,\s*(?:<<3>>|<<4>>|<<6>>))*(?=\s*(?:where|[{;]|=>|$))/.source, [g, c, f, u, r.source, S, /\bnew\s*\(\s*\)/.source]), + lookbehind: !0, + inside: { + "record-arguments": { + pattern: j(/(^(?!new\s*\()<<0>>\s*)<<1>>/.source, [c, S]), + lookbehind: !0, + greedy: !0, + inside: i.languages.csharp + }, + keyword: r, + "class-name": { + pattern: RegExp(u), + greedy: !0, + inside: d + }, + punctuation: /[,()]/ + } + }, + preprocessor: { + pattern: /(^[\t ]*)#.*/m, + lookbehind: !0, + alias: "property", + inside: { + directive: { + pattern: /(#)\b(?:define|elif|else|endif|endregion|error|if|line|nullable|pragma|region|undef|warning)\b/, + lookbehind: !0, + alias: "keyword" + } + } + } + }), + e = A(/\/(?![*/])|\/\/[^\r\n]*[\r\n]|\/\*(?:[^*]|\*(?!\/))*\*\/|<<0>>/.source, [x = p + "|" + B]), + b = L(A(/[^"'/()]|<<0>>|\(<>*\)/.source, [e]), 2), + g = /\b(?:assembly|event|field|method|module|param|property|return|type)\b/.source, + f = A(/<<0>>(?:\s*\(<<1>>*\))?/.source, [_, b]), + i.languages.insertBefore("csharp", "class-name", { + attribute: { + pattern: j(/((?:^|[^\s\w>)?])\s*\[\s*)(?:<<0>>\s*:\s*)?<<1>>(?:\s*,\s*<<1>>)*(?=\s*\])/.source, [g, f]), + lookbehind: !0, + greedy: !0, + inside: { + target: { + pattern: j(/^<<0>>(?=\s*:)/.source, [g]), + alias: "keyword" + }, + "attribute-arguments": { + pattern: j(/\(<<0>>*\)/.source, [b]), + inside: i.languages.csharp + }, + "class-name": { + pattern: RegExp(_), + inside: { + punctuation: /\./ + } + }, + punctuation: /[:,]/ + } + } + }), + h = /:[^}\r\n]+/.source, + c = L(A(/[^"'/()]|<<0>>|\(<>*\)/.source, [e]), 2), + S = A(/\{(?!\{)(?:(?![}:])<<0>>)*<<1>>?\}/.source, [c, h]), + r = L(A(/[^"'/()]|\/(?!\*)|\/\*(?:[^*]|\*(?!\/))*\*\/|<<0>>|\(<>*\)/.source, [x]), 2), + u = A(/\{(?!\{)(?:(?![}:])<<0>>)*<<1>>?\}/.source, [r, h]), + i.languages.insertBefore("csharp", "string", { + "interpolation-string": [{ + pattern: j(/(^|[^\\])(?:\$@|@\$)"(?:""|\\[\s\S]|\{\{|<<0>>|[^\\{"])*"/.source, [S]), + lookbehind: !0, + greedy: !0, + inside: U(S, c) + }, { + pattern: j(/(^|[^@\\])\$"(?:\\.|\{\{|<<0>>|[^\\"{])*"/.source, [u]), + lookbehind: !0, + greedy: !0, + inside: U(u, r) + }], + char: { + pattern: RegExp(B), + greedy: !0 + } + }), + i.languages.dotnet = i.languages.cs = i.languages.csharp, + E.languages.aspnet = E.languages.extend("markup", { + "page-directive": { + pattern: /<%\s*@.*%>/, + alias: "tag", + inside: { + "page-directive": { + pattern: /<%\s*@\s*(?:Assembly|Control|Implements|Import|Master(?:Type)?|OutputCache|Page|PreviousPageType|Reference|Register)?|%>/i, + alias: "tag" + }, + rest: E.languages.markup.tag.inside + } + }, + directive: { + pattern: /<%.*%>/, + alias: "tag", + inside: { + directive: { + pattern: /<%\s*?[$=%#:]{0,2}|%>/, + alias: "tag" + }, + rest: E.languages.csharp + } + } + }), + E.languages.aspnet.tag.pattern = /<(?!%)\/?[^\s>\/]+(?:\s+[^\s>\/=]+(?:=(?:("|')(?:\\[\s\S]|(?!\1)[^\\])*\1|[^\s'">=]+))?)*\s*\/?>/, + E.languages.insertBefore("inside", "punctuation", { + directive: E.languages.aspnet.directive + }, E.languages.aspnet.tag.inside["attr-value"]), + E.languages.insertBefore("aspnet", "comment", { + "asp-comment": { + pattern: /<%--[\s\S]*?--%>/, + alias: ["asp", "comment"] + } + }), + E.languages.insertBefore("aspnet", E.languages.javascript ? "script" : "tag", { + "asp-script": { + pattern: /(]*>)[\s\S]*?(?=<\/script>)/i, + lookbehind: !0, + alias: ["asp", "script"], + inside: E.languages.csharp || {} + } + }), + E.languages.python = { + comment: { + pattern: /(^|[^\\])#.*/, + lookbehind: !0, + greedy: !0 + }, + "string-interpolation": { + pattern: /(?:f|fr|rf)(?:("""|''')[\s\S]*?\1|("|')(?:\\.|(?!\2)[^\\\r\n])*\2)/i, + greedy: !0, + inside: { + interpolation: { + pattern: /((?:^|[^{])(?:\{\{)*)\{(?!\{)(?:[^{}]|\{(?!\{)(?:[^{}]|\{(?!\{)(?:[^{}])+\})+\})+\}/, + lookbehind: !0, + inside: { + "format-spec": { + pattern: /(:)[^:(){}]+(?=\}$)/, + lookbehind: !0 + }, + "conversion-option": { + pattern: /![sra](?=[:}]$)/, + alias: "punctuation" + }, + rest: null + } + }, + string: /[\s\S]+/ + } + }, + "triple-quoted-string": { + pattern: /(?:[rub]|br|rb)?("""|''')[\s\S]*?\1/i, + greedy: !0, + alias: "string" + }, + string: { + pattern: /(?:[rub]|br|rb)?("|')(?:\\.|(?!\1)[^\\\r\n])*\1/i, + greedy: !0 + }, + function: { + pattern: /((?:^|\s)def[ \t]+)[a-zA-Z_]\w*(?=\s*\()/g, + lookbehind: !0 + }, + "class-name": { + pattern: /(\bclass\s+)\w+/i, + lookbehind: !0 + }, + decorator: { + pattern: /(^[\t ]*)@\w+(?:\.\w+)*/m, + lookbehind: !0, + alias: ["annotation", "punctuation"], + inside: { + punctuation: /\./ + } + }, + keyword: /\b(?:_(?=\s*:)|and|as|assert|async|await|break|case|class|continue|def|del|elif|else|except|exec|finally|for|from|global|if|import|in|is|lambda|match|nonlocal|not|or|pass|print|raise|return|try|while|with|yield)\b/, + builtin: /\b(?:__import__|abs|all|any|apply|ascii|basestring|bin|bool|buffer|bytearray|bytes|callable|chr|classmethod|cmp|coerce|compile|complex|delattr|dict|dir|divmod|enumerate|eval|execfile|file|filter|float|format|frozenset|getattr|globals|hasattr|hash|help|hex|id|input|int|intern|isinstance|issubclass|iter|len|list|locals|long|map|max|memoryview|min|next|object|oct|open|ord|pow|property|range|raw_input|reduce|reload|repr|reversed|round|set|setattr|slice|sorted|staticmethod|str|sum|super|tuple|type|unichr|unicode|vars|xrange|zip)\b/, + boolean: /\b(?:False|None|True)\b/, + number: /\b0(?:b(?:_?[01])+|o(?:_?[0-7])+|x(?:_?[a-f0-9])+)\b|(?:\b\d+(?:_\d+)*(?:\.(?:\d+(?:_\d+)*)?)?|\B\.\d+(?:_\d+)*)(?:e[+-]?\d+(?:_\d+)*)?j?(?!\w)/i, + operator: /[-+%=]=?|!=|:=|\*\*?=?|\/\/?=?|<[<=>]?|>[=>]?|[&|^~]/, + punctuation: /[{}[\];(),.:]/ + }, + E.languages.python["string-interpolation"].inside.interpolation.inside.rest = E.languages.python, + E.languages.py = E.languages.python, + (d = E).languages.ruby = d.languages.extend("clike", { + comment: { + pattern: /#.*|^=begin\s[\s\S]*?^=end/m, + greedy: !0 + }, + "class-name": { + pattern: /(\b(?:class|module)\s+|\bcatch\s+\()[\w.\\]+|\b[A-Z_]\w*(?=\s*\.\s*new\b)/, + lookbehind: !0, + inside: { + punctuation: /[.\\]/ + } + }, + keyword: /\b(?:BEGIN|END|alias|and|begin|break|case|class|def|define_method|defined|do|each|else|elsif|end|ensure|extend|for|if|in|include|module|new|next|nil|not|or|prepend|private|protected|public|raise|redo|require|rescue|retry|return|self|super|then|throw|undef|unless|until|when|while|yield)\b/, + operator: /\.{2,3}|&\.|===||[!=]?~|(?:&&|\|\||<<|>>|\*\*|[+\-*/%<>!^&|=])=?|[?:]/, + punctuation: /[(){}[\].,;]/ + }), + d.languages.insertBefore("ruby", "operator", { + "double-colon": { + pattern: /::/, + alias: "punctuation" + } + }), + p = { + pattern: /((?:^|[^\\])(?:\\{2})*)#\{(?:[^{}]|\{[^{}]*\})*\}/, + lookbehind: !0, + inside: { + content: { + pattern: /^(#\{)[\s\S]+(?=\}$)/, + lookbehind: !0, + inside: d.languages.ruby + }, + delimiter: { + pattern: /^#\{|\}$/, + alias: "punctuation" + } + } + }, + delete d.languages.ruby.function, + f = "(?:" + [/([^a-zA-Z0-9\s{(\[<=])(?:(?!\1)[^\\]|\\[\s\S])*\1/.source, /\((?:[^()\\]|\\[\s\S]|\((?:[^()\\]|\\[\s\S])*\))*\)/.source, /\{(?:[^{}\\]|\\[\s\S]|\{(?:[^{}\\]|\\[\s\S])*\})*\}/.source, /\[(?:[^\[\]\\]|\\[\s\S]|\[(?:[^\[\]\\]|\\[\s\S])*\])*\]/.source, /<(?:[^<>\\]|\\[\s\S]|<(?:[^<>\\]|\\[\s\S])*>)*>/.source].join("|") + ")", + g = /(?:"(?:\\.|[^"\\\r\n])*"|(?:\b[a-zA-Z_]\w*|[^\s\0-\x7F]+)[?!]?|\$.)/.source, + d.languages.insertBefore("ruby", "keyword", { + "regex-literal": [{ + pattern: RegExp(/%r/.source + f + /[egimnosux]{0,6}/.source), + greedy: !0, + inside: { + interpolation: p, + regex: /[\s\S]+/ + } + }, { + pattern: /(^|[^/])\/(?!\/)(?:\[[^\r\n\]]+\]|\\.|[^[/\\\r\n])+\/[egimnosux]{0,6}(?=\s*(?:$|[\r\n,.;})#]))/, + lookbehind: !0, + greedy: !0, + inside: { + interpolation: p, + regex: /[\s\S]+/ + } + }], + variable: /[@$]+[a-zA-Z_]\w*(?:[?!]|\b)/, + symbol: [{ + pattern: RegExp(/(^|[^:]):/.source + g), + lookbehind: !0, + greedy: !0 + }, { + pattern: RegExp(/([\r\n{(,][ \t]*)/.source + g + /(?=:(?!:))/.source), + lookbehind: !0, + greedy: !0 + }], + "method-definition": { + pattern: /(\bdef\s+)\w+(?:\s*\.\s*\w+)?/, + lookbehind: !0, + inside: { + function: /\b\w+$/, + keyword: /^self\b/, + "class-name": /^\w+/, + punctuation: /\./ + } + } + }), + d.languages.insertBefore("ruby", "string", { + "string-literal": [{ + pattern: RegExp(/%[qQiIwWs]?/.source + f), + greedy: !0, + inside: { + interpolation: p, + string: /[\s\S]+/ + } + }, { + pattern: /("|')(?:#\{[^}]+\}|#(?!\{)|\\(?:\r\n|[\s\S])|(?!\1)[^\\#\r\n])*\1/, + greedy: !0, + inside: { + interpolation: p, + string: /[\s\S]+/ + } + }, { + pattern: /<<[-~]?([a-z_]\w*)[\r\n](?:.*[\r\n])*?[\t ]*\1/i, + alias: "heredoc-string", + greedy: !0, + inside: { + delimiter: { + pattern: /^<<[-~]?[a-z_]\w*|\b[a-z_]\w*$/i, + inside: { + symbol: /\b\w+/, + punctuation: /^<<[-~]?/ + } + }, + interpolation: p, + string: /[\s\S]+/ + } + }, { + pattern: /<<[-~]?'([a-z_]\w*)'[\r\n](?:.*[\r\n])*?[\t ]*\1/i, + alias: "heredoc-string", + greedy: !0, + inside: { + delimiter: { + pattern: /^<<[-~]?'[a-z_]\w*'|\b[a-z_]\w*$/i, + inside: { + symbol: /\b\w+/, + punctuation: /^<<[-~]?'|'$/ + } + }, + string: /[\s\S]+/ + } + }], + "command-literal": [{ + pattern: RegExp(/%x/.source + f), + greedy: !0, + inside: { + interpolation: p, + command: { + pattern: /[\s\S]+/, + alias: "string" + } + } + }, { + pattern: /`(?:#\{[^}]+\}|#(?!\{)|\\(?:\r\n|[\s\S])|[^\\`#\r\n])*`/, + greedy: !0, + inside: { + interpolation: p, + command: { + pattern: /[\s\S]+/, + alias: "string" + } + } + }] + }), + delete d.languages.ruby.string, + d.languages.insertBefore("ruby", "number", { + builtin: /\b(?:Array|Bignum|Binding|Class|Continuation|Dir|Exception|FalseClass|File|Fixnum|Float|Hash|IO|Integer|MatchData|Method|Module|NilClass|Numeric|Object|Proc|Range|Regexp|Stat|String|Struct|Symbol|TMS|Thread|ThreadGroup|Time|TrueClass)\b/, + constant: /\b[A-Z][A-Z0-9_]*(?:[?!]|\b)/ + }), + d.languages.rb = d.languages.ruby, + (m = E).languages.php = m.languages.extend("clike", { + keyword: /\b(?:and|or|xor|array|as|break|case|cfunction|class|const|continue|declare|default|die|do|else|elseif|enddeclare|endfor|endforeach|endif|endswitch|endwhile|extends|for|foreach|function|include|include_once|global|if|new|return|static|switch|use|require|require_once|var|while|abstract|interface|public|implements|private|protected|parent|throw|null|echo|print|trait|namespace|final|yield|goto|instanceof|finally|try|catch)\b/i, + constant: /\b[A-Z0-9_]{2,}\b/, + comment: { + pattern: /(^|[^\\])(?:\/\*[\s\S]*?\*\/|\/\/.*)/, + lookbehind: !0 + } + }), + m.languages.insertBefore("php", "string", { + "shell-comment": { + pattern: /(^|[^\\])#.*/, + lookbehind: !0, + alias: "comment" + } + }), + m.languages.insertBefore("php", "keyword", { + delimiter: { + pattern: /\?>|<\?(?:php|=)?/i, + alias: "important" + }, + variable: /\$+(?:\w+\b|(?={))/i, + package: { + pattern: /(\\|namespace\s+|use\s+)[\w\\]+/, + lookbehind: !0, + inside: { + punctuation: /\\/ + } + } + }), + m.languages.insertBefore("php", "operator", { + property: { + pattern: /(->)[\w]+/, + lookbehind: !0 + } + }), + m.languages.insertBefore("php", "string", { + "nowdoc-string": { + pattern: /<<<'([^']+)'(?:\r\n?|\n)(?:.*(?:\r\n?|\n))*?\1;/, + greedy: !0, + alias: "string", + inside: { + delimiter: { + pattern: /^<<<'[^']+'|[a-z_]\w*;$/i, + alias: "symbol", + inside: { + punctuation: /^<<<'?|[';]$/ + } + } + } + }, + "heredoc-string": { + pattern: /<<<(?:"([^"]+)"(?:\r\n?|\n)(?:.*(?:\r\n?|\n))*?\1;|([a-z_]\w*)(?:\r\n?|\n)(?:.*(?:\r\n?|\n))*?\2;)/i, + greedy: !0, + alias: "string", + inside: { + delimiter: { + pattern: /^<<<(?:"[^"]+"|[a-z_]\w*)|[a-z_]\w*;$/i, + alias: "symbol", + inside: { + punctuation: /^<<<"?|[";]$/ + } + }, + interpolation: null + } + }, + "single-quoted-string": { + pattern: /'(?:\\[\s\S]|[^\\'])*'/, + greedy: !0, + alias: "string" + }, + "double-quoted-string": { + pattern: /"(?:\\[\s\S]|[^\\"])*"/, + greedy: !0, + alias: "string", + inside: { + interpolation: null + } + } + }), + delete m.languages.php.string, + b = { + pattern: /{\$(?:{(?:{[^{}]+}|[^{}]+)}|[^{}])+}|(^|[^\\{])\$+(?:\w+(?:\[.+?]|->\w+)*)/, + lookbehind: !0, + inside: { + rest: m.languages.php + } + }, + m.languages.php["heredoc-string"].inside.interpolation = b, + m.languages.php["double-quoted-string"].inside.interpolation = b, + m.hooks.add("before-tokenize", function(t) { + /(?:<\?php|<\?)/gi.test(t.code) && m.languages["markup-templating"].buildPlaceholders(t, "php", /(?:<\?php|<\?)[\s\S]*?(?:\?>|$)/gi) + }), + m.hooks.add("after-tokenize", function(t) { + m.languages["markup-templating"].tokenizePlaceholders(t, "php") + }), + E.languages.typescript = E.languages.extend("javascript", { + keyword: /\b(?:as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|var|void|while|with|yield|module|declare|constructor|namespace|abstract|require|type)\b/, + builtin: /\b(?:string|Function|any|number|boolean|Array|symbol|console)\b/ + }), + E.languages.ts = E.languages.typescript, + E.languages.scss = E.languages.extend("css", { + comment: { + pattern: /(^|[^\\])(?:\/\*[\s\S]*?\*\/|\/\/.*)/, + lookbehind: !0 + }, + atrule: { + pattern: /@[\w-]+(?:\([^()]+\)|[^(])*?(?=\s+[{;])/, + inside: { + rule: /@[\w-]+/ + } + }, + url: /(?:[-a-z]+-)*url(?=\()/i, + selector: { + pattern: /(?=\S)[^@;{}()]?(?:[^@;{}()]|&|#\{\$[-\w]+\})+(?=\s*\{(?:\}|\s|[^}]+[:{][^}]+))/m, + inside: { + parent: { + pattern: /&/, + alias: "important" + }, + placeholder: /%[-\w]+/, + variable: /\$[-\w]+|#\{\$[-\w]+\}/ + } + } + }), + E.languages.insertBefore("scss", "atrule", { + keyword: [/@(?:if|else(?: if)?|for|each|while|import|extend|debug|warn|mixin|include|function|return|content)/i, { + pattern: /( +)(?:from|through)(?= )/, + lookbehind: !0 + }] + }), + E.languages.scss.property = { + pattern: /(?:[\w-]|\$[-\w]+|#\{\$[-\w]+\})+(?=\s*:)/i, + inside: { + variable: /\$[-\w]+|#\{\$[-\w]+\}/ + } + }, + E.languages.insertBefore("scss", "important", { + variable: /\$[-\w]+|#\{\$[-\w]+\}/ + }), + E.languages.insertBefore("scss", "function", { + placeholder: { + pattern: /%[-\w]+/, + alias: "selector" + }, + statement: { + pattern: /\B!(?:default|optional)\b/i, + alias: "keyword" + }, + boolean: /\b(?:true|false)\b/, + null: /\bnull\b/, + operator: { + pattern: /(\s)(?:[-+*\/%]|[=!]=|<=?|>=?|and|or|not)(?=\s)/, + lookbehind: !0 + } + }), + E.languages.scss.atrule.inside.rest = E.languages.scss, + "undefined" != typeof self && self.Prism && self.document && (W = "line-numbers", + Y = /\n(?!$)/g, + F = function(t) { + var n, i, e = ((e = t) ? window.getComputedStyle ? getComputedStyle(e) : e.currentStyle || null : null)["white-space"]; + "pre-wrap" !== e && "pre-line" !== e || (e = t.querySelector("code"), + n = t.querySelector(".line-numbers-rows"), + i = t.querySelector(".line-numbers-sizer"), + t = e.textContent.split(Y), + i || ((i = document.createElement("span")).className = "line-numbers-sizer", + e.appendChild(i)), + i.style.display = "block", + t.forEach(function(t, e) { + i.textContent = t || "\n", + t = i.getBoundingClientRect().height, + n.children[e].style.height = t + "px" + }), + i.textContent = "", + i.style.display = "none") + } + , + window.addEventListener("resize", function() { + Array.prototype.forEach.call(document.querySelectorAll("pre." + W), F) + }), + E.hooks.add("complete", function(t) { + var e, n, i; + t.code && (n = /\s*\bline-numbers\b\s*/, + e = t.element.parentNode) && /pre/i.test(e.nodeName) && (n.test(e.className) || n.test(t.element.className)) && (t.element.querySelector(".line-numbers-rows") || (n.test(t.element.className) && (t.element.className = t.element.className.replace(n, " ")), + n.test(e.className) || (e.className += " line-numbers"), + n = (n = t.code.match(Y)) ? n.length + 1 : 1, + n = (n = new Array(n + 1)).join(""), + (i = document.createElement("span")).setAttribute("aria-hidden", "true"), + i.className = "line-numbers-rows", + i.innerHTML = n, + e.hasAttribute("data-start") && (e.style.counterReset = "linenumber " + (parseInt(e.getAttribute("data-start"), 10) - 1)), + t.element.appendChild(i), + F(e), + E.hooks.run("line-numbers", t))) + }), + E.hooks.add("line-numbers", function(t) { + t.plugins = t.plugins || {}, + t.plugins.lineNumbers = !0 + }), + E.plugins.lineNumbers = { + getLine: function(t, e) { + var n, i; + if ("PRE" === t.tagName && t.classList.contains(W)) + return n = t.querySelector(".line-numbers-rows"), + i = (e = (i = (t = parseInt(t.getAttribute("data-start"), 10) || 1) + (n.children.length - 1)) < (e = e < t ? t : e) ? i : e) - t, + n.children[i] + } + }), + "undefined" != typeof self && self.Prism && self.document && (v = [], + X = {}, + z = function() {} + , + E.plugins.toolbar = {}, + _ = E.plugins.toolbar.registerButton = function(t, n) { + v.push(X[t] = "function" == typeof n ? n : function(t) { + var e; + return "function" == typeof n.onClick ? ((e = document.createElement("button")).type = "button", + e.addEventListener("click", function() { + n.onClick.call(this, t) + })) : "string" == typeof n.url ? (e = document.createElement("a")).href = n.url : e = document.createElement("span"), + e.textContent = n.text, + e + } + ) + } + , + e = E.plugins.toolbar.hook = function(n) { + var t, i, e = n.element.parentNode; + e && /pre/i.test(e.nodeName) && (e.parentNode.classList.contains("code-toolbar") || ((t = document.createElement("div")).classList.add("code-toolbar"), + e.parentNode.insertBefore(t, e), + t.appendChild(e), + (i = document.createElement("div")).classList.add("toolbar"), + (v = document.body.hasAttribute("data-toolbar-order") ? document.body.getAttribute("data-toolbar-order").split(",").map(function(t) { + return X[t] || z + }) : v).forEach(function(t) { + var e; + (t = t(n)) && ((e = document.createElement("div")).classList.add("toolbar-item"), + e.appendChild(t), + i.appendChild(e)) + }), + t.appendChild(i))) + } + , + _("label", function(t) { + if ((t = t.element.parentNode) && /pre/i.test(t.nodeName) && t.hasAttribute("data-label")) { + var e, n, i = t.getAttribute("data-label"); + try { + n = document.querySelector("template#" + i) + } catch (t) {} + return n ? e = n.content : (t.hasAttribute("data-url") ? (e = document.createElement("a")).href = t.getAttribute("data-url") : e = document.createElement("span"), + e.textContent = i), + e + } + }), + E.hooks.add("complete", e)), + ("undefined" == typeof self || self.Prism) && self.document && Function.prototype.bind) { + var R, q, M = { + gradient: { + create: (R = {}, + function() { + new E.plugins.Previewer("gradient",function(t) { + return this.firstChild.style.backgroundImage = "", + this.firstChild.style.backgroundImage = R[t = t] || (r = (e = t.match(/^(\b|\B-[a-z]{1,10}-)((?:repeating-)?(?:linear|radial)-gradient)/)) && e[1], + e = e && e[2], + n = t.replace(/^(?:\b|\B-[a-z]{1,10}-)(?:repeating-)?(?:linear|radial)-gradient\(|\)$/g, "").split(/\s*,\s*/), + 0 <= e.indexOf("linear") ? R[t] = (s = e, + l = "180deg", + /^(?:-?\d*\.?\d+(?:deg|rad)|to\b|top|right|bottom|left)/.test((a = n)[0]) && (l = a.shift()).indexOf("to ") < 0 && (0 <= l.indexOf("top") ? l = 0 <= l.indexOf("left") ? "to bottom right" : 0 <= l.indexOf("right") ? "to bottom left" : "to bottom" : 0 <= l.indexOf("bottom") ? l = 0 <= l.indexOf("left") ? "to top right" : 0 <= l.indexOf("right") ? "to top left" : "to top" : 0 <= l.indexOf("left") ? l = "to right" : 0 <= l.indexOf("right") ? l = "to left" : r && (0 <= l.indexOf("deg") ? l = 90 - parseFloat(l) + "deg" : 0 <= l.indexOf("rad") && (l = Math.PI / 2 - parseFloat(l) + "rad"))), + s + "(" + l + "," + a.join(",") + ")") : 0 <= e.indexOf("radial") ? R[t] = (r = e, + (s = n)[0].indexOf("at") < 0 ? (l = "center", + a = "ellipse", + i = "farthest-corner", + /\bcenter|top|right|bottom|left\b|^\d+/.test(s[0]) && (l = s.shift().replace(/\s*-?\d+(?:rad|deg)\s*/, "")), + /\bcircle|ellipse|closest|farthest|contain|cover\b/.test(s[0]) && (!(o = s.shift().split(/\s+/))[0] || "circle" !== o[0] && "ellipse" !== o[0] || (a = o.shift()), + "cover" === (i = o[0] ? o.shift() : i) ? i = "farthest-corner" : "contain" === i && (i = "clothest-side")), + r + "(" + a + " " + i + " at " + l + "," + s.join(",") + ")") : r + "(" + s.join(",") + ")") : R[t] = e + "(" + n.join(",") + ")"), + !!this.firstChild.style.backgroundImage; + var e, n, i, o, r, s, a, l + } + ,"*",function() { + this._elt.innerHTML = "
" + } + ) + } + ), + tokens: { + gradient: { + pattern: /(?:\b|\B-[a-z]{1,10}-)(?:repeating-)?(?:linear|radial)-gradient\((?:(?:rgb|hsl)a?\(.+?\)|[^\)])+\)/gi, + inside: { + function: /[\w-]+(?=\()/, + punctuation: /[(),]/ + } + } + }, + languages: { + css: !0, + less: !0, + sass: [{ + lang: "sass", + before: "punctuation", + inside: "inside", + root: E.languages.sass && E.languages.sass["variable-line"] + }, { + lang: "sass", + before: "punctuation", + inside: "inside", + root: E.languages.sass && E.languages.sass["property-line"] + }], + scss: !0, + stylus: [{ + lang: "stylus", + before: "func", + inside: "rest", + root: E.languages.stylus && E.languages.stylus["property-declaration"].inside + }, { + lang: "stylus", + before: "func", + inside: "rest", + root: E.languages.stylus && E.languages.stylus["variable-declaration"].inside + }] + } + }, + angle: { + create: function() { + new E.plugins.Previewer("angle",function(t) { + var e, n = parseFloat(t), t = t.match(/[a-z]+$/i); + if (!n || !t) + return !1; + switch (t[0]) { + case "deg": + e = 360; + break; + case "grad": + e = 400; + break; + case "rad": + e = 2 * Math.PI; + break; + case "turn": + e = 1 + } + return t = 100 * n / e, + t %= 100, + this[(n < 0 ? "set" : "remove") + "Attribute"]("data-negative", ""), + this.querySelector("circle").style.strokeDasharray = Math.abs(t) + ",500", + !0 + } + ,"*",function() { + this._elt.innerHTML = '' + } + ) + }, + tokens: { + angle: /(?:\b|\B-|(?=\B\.))\d*\.?\d+(?:deg|g?rad|turn)\b/i + }, + languages: { + css: !0, + less: !0, + markup: { + lang: "markup", + before: "punctuation", + inside: "inside", + root: E.languages.markup && E.languages.markup.tag.inside["attr-value"] + }, + sass: [{ + lang: "sass", + inside: "inside", + root: E.languages.sass && E.languages.sass["property-line"] + }, { + lang: "sass", + before: "operator", + inside: "inside", + root: E.languages.sass && E.languages.sass["variable-line"] + }], + scss: !0, + stylus: [{ + lang: "stylus", + before: "func", + inside: "rest", + root: E.languages.stylus && E.languages.stylus["property-declaration"].inside + }, { + lang: "stylus", + before: "func", + inside: "rest", + root: E.languages.stylus && E.languages.stylus["variable-declaration"].inside + }] + } + }, + color: { + create: function() { + new E.plugins.Previewer("color",function(t) { + return this.style.backgroundColor = "", + this.style.backgroundColor = t, + !!this.style.backgroundColor + } + ) + }, + tokens: { + color: { + pattern: /\B#(?:[0-9a-f]{3}){1,2}\b|\b(?:rgb|hsl)\(\s*\d{1,3}\s*,\s*\d{1,3}%?\s*,\s*\d{1,3}%?\s*\)\B|\b(?:rgb|hsl)a\(\s*\d{1,3}\s*,\s*\d{1,3}%?\s*,\s*\d{1,3}%?\s*,\s*(?:0|0?\.\d+|1)\s*\)\B|\b(?:AliceBlue|AntiqueWhite|Aqua|Aquamarine|Azure|Beige|Bisque|Black|BlanchedAlmond|Blue|BlueViolet|Brown|BurlyWood|CadetBlue|Chartreuse|Chocolate|Coral|CornflowerBlue|Cornsilk|Crimson|Cyan|DarkBlue|DarkCyan|DarkGoldenRod|DarkGray|DarkGreen|DarkKhaki|DarkMagenta|DarkOliveGreen|DarkOrange|DarkOrchid|DarkRed|DarkSalmon|DarkSeaGreen|DarkSlateBlue|DarkSlateGray|DarkTurquoise|DarkViolet|DeepPink|DeepSkyBlue|DimGray|DodgerBlue|FireBrick|FloralWhite|ForestGreen|Fuchsia|Gainsboro|GhostWhite|Gold|GoldenRod|Gray|Green|GreenYellow|HoneyDew|HotPink|IndianRed|Indigo|Ivory|Khaki|Lavender|LavenderBlush|LawnGreen|LemonChiffon|LightBlue|LightCoral|LightCyan|LightGoldenRodYellow|LightGray|LightGreen|LightPink|LightSalmon|LightSeaGreen|LightSkyBlue|LightSlateGray|LightSteelBlue|LightYellow|Lime|LimeGreen|Linen|Magenta|Maroon|MediumAquaMarine|MediumBlue|MediumOrchid|MediumPurple|MediumSeaGreen|MediumSlateBlue|MediumSpringGreen|MediumTurquoise|MediumVioletRed|MidnightBlue|MintCream|MistyRose|Moccasin|NavajoWhite|Navy|OldLace|Olive|OliveDrab|Orange|OrangeRed|Orchid|PaleGoldenRod|PaleGreen|PaleTurquoise|PaleVioletRed|PapayaWhip|PeachPuff|Peru|Pink|Plum|PowderBlue|Purple|Red|RosyBrown|RoyalBlue|SaddleBrown|Salmon|SandyBrown|SeaGreen|SeaShell|Sienna|Silver|SkyBlue|SlateBlue|SlateGray|Snow|SpringGreen|SteelBlue|Tan|Teal|Thistle|Tomato|Turquoise|Violet|Wheat|White|WhiteSmoke|Yellow|YellowGreen)\b/i, + inside: { + function: /[\w-]+(?=\()/, + punctuation: /[(),]/ + } + } + }, + languages: { + css: !0, + less: !0, + markup: { + lang: "markup", + before: "punctuation", + inside: "inside", + root: E.languages.markup && E.languages.markup.tag.inside["attr-value"] + }, + sass: [{ + lang: "sass", + before: "punctuation", + inside: "inside", + root: E.languages.sass && E.languages.sass["variable-line"] + }, { + lang: "sass", + inside: "inside", + root: E.languages.sass && E.languages.sass["property-line"] + }], + scss: !0, + stylus: [{ + lang: "stylus", + before: "hexcode", + inside: "rest", + root: E.languages.stylus && E.languages.stylus["property-declaration"].inside + }, { + lang: "stylus", + before: "hexcode", + inside: "rest", + root: E.languages.stylus && E.languages.stylus["variable-declaration"].inside + }] + } + }, + easing: { + create: function() { + new E.plugins.Previewer("easing",function(t) { + var e; + return 4 === (t = (t = { + linear: "0,0,1,1", + ease: ".25,.1,.25,1", + "ease-in": ".42,0,1,1", + "ease-out": "0,0,.58,1", + "ease-in-out": ".42,0,.58,1" + }[t] || t).match(/-?\d*\.?\d+/g)).length && (t = t.map(function(t, e) { + return 100 * (e % 2 ? 1 - t : t) + }), + this.querySelector("path").setAttribute("d", "M0,100 C" + t[0] + "," + t[1] + ", " + t[2] + "," + t[3] + ", 100,0"), + (e = this.querySelectorAll("line"))[0].setAttribute("x2", t[0]), + e[0].setAttribute("y2", t[1]), + e[1].setAttribute("x2", t[2]), + e[1].setAttribute("y2", t[3]), + !0) + } + ,"*",function() { + this._elt.innerHTML = '' + } + ) + }, + tokens: { + easing: { + pattern: /\bcubic-bezier\((?:-?\d*\.?\d+,\s*){3}-?\d*\.?\d+\)\B|\b(?:linear|ease(?:-in)?(?:-out)?)(?=\s|[;}]|$)/i, + inside: { + function: /[\w-]+(?=\()/, + punctuation: /[(),]/ + } + } + }, + languages: { + css: !0, + less: !0, + sass: [{ + lang: "sass", + inside: "inside", + before: "punctuation", + root: E.languages.sass && E.languages.sass["variable-line"] + }, { + lang: "sass", + inside: "inside", + root: E.languages.sass && E.languages.sass["property-line"] + }], + scss: !0, + stylus: [{ + lang: "stylus", + before: "hexcode", + inside: "rest", + root: E.languages.stylus && E.languages.stylus["property-declaration"].inside + }, { + lang: "stylus", + before: "hexcode", + inside: "rest", + root: E.languages.stylus && E.languages.stylus["variable-declaration"].inside + }] + } + }, + time: { + create: function() { + new E.plugins.Previewer("time",function(t) { + var e = parseFloat(t) + , t = t.match(/[a-z]+$/i); + return !(!e || !t || (t = t[0], + this.querySelector("circle").style.animationDuration = 2 * e + t, + 0)) + } + ,"*",function() { + this._elt.innerHTML = '' + } + ) + }, + tokens: { + time: /(?:\b|\B-|(?=\B\.))\d*\.?\d+m?s\b/i + }, + languages: { + css: !0, + less: !0, + markup: { + lang: "markup", + before: "punctuation", + inside: "inside", + root: E.languages.markup && E.languages.markup.tag.inside["attr-value"] + }, + sass: [{ + lang: "sass", + inside: "inside", + root: E.languages.sass && E.languages.sass["property-line"] + }, { + lang: "sass", + before: "operator", + inside: "inside", + root: E.languages.sass && E.languages.sass["variable-line"] + }], + scss: !0, + stylus: [{ + lang: "stylus", + before: "hexcode", + inside: "rest", + root: E.languages.stylus && E.languages.stylus["property-declaration"].inside + }, { + lang: "stylus", + before: "hexcode", + inside: "rest", + root: E.languages.stylus && E.languages.stylus["variable-declaration"].inside + }] + } + } + }, $ = /(?:^|\s)token(?=$|\s)/, V = /(?:^|\s)active(?=$|\s)/g, K = /(?:^|\s)flipped(?=$|\s)/g, I = function(t, e, n, i) { + this._elt = null, + this._type = t, + this._clsRegexp = RegExp("(?:^|\\s)" + t + "(?=$|\\s)"), + this._token = null, + this.updater = e, + this._mouseout = this.mouseout.bind(this), + this.initializer = i; + var o = this; + (n = "Array" !== E.util.type(n = n || ["*"]) ? [n] : n).forEach(function(t) { + "string" != typeof t && (t = t.lang), + I.byLanguages[t] || (I.byLanguages[t] = []), + I.byLanguages[t].indexOf(o) < 0 && I.byLanguages[t].push(o) + }), + I.byType[t] = this + }; + for (q in I.prototype.init = function() { + this._elt || (this._elt = document.createElement("div"), + this._elt.className = "prism-previewer prism-previewer-" + this._type, + document.body.appendChild(this._elt), + this.initializer && this.initializer()) + } + , + I.prototype.isDisabled = function(t) { + do { + if (t.hasAttribute && t.hasAttribute("data-previewers")) + return -1 === (t.getAttribute("data-previewers") || "").split(/\s+/).indexOf(this._type) + } while (t = t.parentNode); + return !1 + } + , + I.prototype.check = function(t) { + if (!$.test(t.className) || !this.isDisabled(t)) { + do { + if ($.test(t.className) && this._clsRegexp.test(t.className)) + break + } while (t = t.parentNode); + t && t !== this._token && (this._token = t, + this.show()) + } + } + , + I.prototype.mouseout = function() { + this._token.removeEventListener("mouseout", this._mouseout, !1), + this._token = null, + this.hide() + } + , + I.prototype.show = function() { + var t; + this._elt || this.init(), + this._token && (this.updater.call(this._elt, this._token.textContent) ? (this._token.addEventListener("mouseout", this._mouseout, !1), + t = function(t) { + var e = 0 + , n = 0 + , i = t; + if (i.parentNode) { + for (; e += i.offsetLeft, + n += i.offsetTop, + (i = i.offsetParent) && i.nodeType < 9; ) + ; + for (i = t; e -= i.scrollLeft, + n -= i.scrollTop, + (i = i.parentNode) && !/body/i.test(i.nodeName); ) + ; + } + return { + top: n, + right: innerWidth - e - t.offsetWidth, + bottom: innerHeight - n - t.offsetHeight, + left: e + } + }(this._token), + this._elt.className += " active", + 0 < t.top - this._elt.offsetHeight ? (this._elt.className = this._elt.className.replace(K, ""), + this._elt.style.top = t.top + "px", + this._elt.style.bottom = "") : (this._elt.className += " flipped", + this._elt.style.bottom = t.bottom + "px", + this._elt.style.top = ""), + this._elt.style.left = t.left + Math.min(200, this._token.offsetWidth / 2) + "px") : this.hide()) + } + , + I.prototype.hide = function() { + this._elt.className = this._elt.className.replace(V, "") + } + , + I.byLanguages = {}, + I.byType = {}, + I.initEvents = function(t, e) { + var n = []; + I.byLanguages[e] && (n = n.concat(I.byLanguages[e])), + I.byLanguages["*"] && (n = n.concat(I.byLanguages["*"])), + t.addEventListener("mouseover", function(t) { + var e = t.target; + n.forEach(function(t) { + t.check(e) + }) + }, !1) + } + , + E.plugins.Previewer = I, + E.hooks.add("before-highlight", function(r) { + for (var s in M) { + var t, a = M[s].languages; + r.language && a[r.language] && !a[r.language].initialized && (t = a[r.language], + (t = "Array" !== E.util.type(t) ? [t] : t).forEach(function(t) { + var e, n, i, o; + !0 === t ? (e = "important", + n = r.language) : (e = t.before || "important", + n = t.inside || t.lang, + i = t.root || E.languages, + o = t.skip), + t = r.language, + !o && E.languages[t] && (E.languages.insertBefore(n, e, M[s].tokens, i), + r.grammar = E.languages[t], + a[r.language] = { + initialized: !0 + }) + })) + } + }), + E.hooks.add("after-highlight", function(t) { + (I.byLanguages["*"] || I.byLanguages[t.language]) && I.initEvents(t.element, t.language) + }), + M) + M[q].create() + } + function G(t) { + this.defaults = y({}, t) + } + function Q(t) { + for (var e = 0, n = 0; n < t.length; ++n) + t.charCodeAt(n) == "\t".charCodeAt(0) && (e += 3); + return t.length + e + } + y = Object.assign || function(t, e) { + for (var n in e) + e.hasOwnProperty(n) && (t[n] = e[n]); + return t + } + , + G.prototype = { + setDefaults: function(t) { + this.defaults = y(this.defaults, t) + }, + normalize: function(t, e) { + for (var n in e = y(this.defaults, e)) { + var i = n.replace(/-(\w)/g, function(t, e) { + return e.toUpperCase() + }); + "normalize" !== n && "setDefaults" !== i && e[n] && this[i] && (t = this[i].call(this, t, e[n])) + } + return t + }, + leftTrim: function(t) { + return t.replace(/^\s+/, "") + }, + rightTrim: function(t) { + return t.replace(/\s+$/, "") + }, + tabsToSpaces: function(t, e) { + return e = 0 | e || 4, + t.replace(/\t/g, new Array(++e).join(" ")) + }, + spacesToTabs: function(t, e) { + return e = 0 | e || 4, + t.replace(new RegExp(" {" + e + "}","g"), "\t") + }, + removeTrailing: function(t) { + return t.replace(/\s*?$/gm, "") + }, + removeInitialLineFeed: function(t) { + return t.replace(/^(?:\r?\n|\r)/, "") + }, + removeIndent: function(t) { + var e = t.match(/^[^\S\n\r]*(?=\S)/gm); + return e && e[0].length && (e.sort(function(t, e) { + return t.length - e.length + }), + e[0].length) ? t.replace(new RegExp("^" + e[0],"gm"), "") : t + }, + indent: function(t, e) { + return t.replace(/^[^\S\n\r]*(?=\S)/gm, new Array(++e).join("\t") + "$&") + }, + breakLines: function(t, e) { + e = !0 !== e && 0 | e || 80; + for (var n = t.split("\n"), i = 0; i < n.length; ++i) + if (!(Q(n[i]) <= e)) { + for (var o = n[i].split(/(\s+)/g), r = 0, s = 0; s < o.length; ++s) { + var a = Q(o[s]); + e < (r += a) && (o[s] = "\n" + o[s], + r = a) + } + n[i] = o.join("") + } + return n.join("\n") + } + }, + t.exports && (t.exports = G), + void 0 !== E && (E.plugins.NormalizeWhitespace = new G({ + "remove-trailing": !0, + "remove-indent": !0, + "left-trim": !0, + "right-trim": !0 + }), + E.hooks.add("before-sanity-check", function(t) { + var e = E.plugins.NormalizeWhitespace; + if (!t.settings || !1 !== t.settings["whitespace-normalization"]) + if (t.element && t.element.parentNode || !t.code) { + var n = t.element.parentNode + , i = /\bno-whitespace-normalization\b/; + if (t.code && n && "pre" === n.nodeName.toLowerCase() && !i.test(n.className) && !i.test(t.element.className)) { + for (var o = n.childNodes, r = "", s = "", a = !1, l = 0; l < o.length; ++l) { + var c = o[l]; + c == t.element ? a = !0 : "#text" === c.nodeName && (a ? s += c.nodeValue : r += c.nodeValue, + n.removeChild(c), + --l) + } + t.element.children.length && E.plugins.KeepMarkup ? (i = r + t.element.innerHTML + s, + t.element.innerHTML = e.normalize(i, t.settings), + t.code = t.element.textContent) : (t.code = r + t.code + s, + t.code = e.normalize(t.code, t.settings)) + } + } else + t.code = e.normalize(t.code, t.settings) + })), + "undefined" != typeof self && self.Prism && self.document && (E.plugins.toolbar ? (w = (w = window.ClipboardJS || void 0) || Z(117), + O = [], + w || (x = document.createElement("script"), + S = document.querySelector("head"), + x.onload = function() { + if (w = window.ClipboardJS) + for (; O.length; ) + O.pop()() + } + , + x.src = "https://cdnjs.cloudflare.com/ajax/libs/clipboard.js/2.0.0/clipboard.min.js", + S.appendChild(x)), + E.plugins.toolbar.registerButton("copy-to-clipboard", function(e) { + var n = document.createElement("button"); + return n.innerHTML = "Copy", + n.classList = "btn-copy-code btn btn-sm", + n.setAttribute("data-mdb-ripple-color", "dark"), + n.setAttribute("data-mdb-ripple-unbound", "true"), + w ? t() : O.push(t), + n; + function t() { + var t = new w(n,{ + text: function() { + return e.code + } + }); + t.on("success", function() { + n.textContent = "Copied!", + i() + }), + t.on("error", function() { + n.textContent = "Press Ctrl+C to copy", + i() + }) + } + function i() { + setTimeout(function() { + n.innerHTML = "Copy" + }, 5e3) + } + })) : console.warn("Copy to Clipboard plugin loaded before Toolbar plugin.")) + } + .call(this, Z(69)(t), Z(36)) + } + , function(t, e) { + t.exports = function(t) { + var e; + return t.webpackPolyfill || ((e = Object.create(t)).children || (e.children = []), + Object.defineProperty(e, "loaded", { + enumerable: !0, + get: function() { + return e.l + } + }), + Object.defineProperty(e, "id", { + enumerable: !0, + get: function() { + return e.i + } + }), + Object.defineProperty(e, "exports", { + enumerable: !0 + }), + e.webpackPolyfill = 1), + e + } + } + , function(t, e, n) { + var i = {}.propertyIsEnumerable + , o = Object.getOwnPropertyDescriptor + , r = o && !i.call({ + 1: 2 + }, 1); + e.f = r ? function(t) { + return !!(t = o(this, t)) && t.enumerable + } + : i + } + , function(t, e, n) { + var i = n(1) + , o = n(0) + , r = n(12) + , s = Object + , a = i("".split); + t.exports = o(function() { + return !s("z").propertyIsEnumerable(0) + }) ? function(t) { + return "String" == r(t) ? a(t, "") : s(t) + } + : s + } + , function(t, e, n) { + var i = n(8) + , o = n(9) + , r = n(40) + , s = n(44) + , a = n(73) + , n = n(6) + , l = TypeError + , c = n("toPrimitive"); + t.exports = function(t, e) { + if (!o(t) || r(t)) + return t; + var n = s(t, c); + if (n) { + if (n = i(n, t, e = void 0 === e ? "default" : e), + !o(n) || r(n)) + return n; + throw l("Can't convert object to primitive value") + } + return a(t, e = void 0 === e ? "number" : e) + } + } + , function(t, e, n) { + var o = n(8) + , r = n(2) + , s = n(9) + , a = TypeError; + t.exports = function(t, e) { + var n, i; + if ("string" === e && r(n = t.toString) && !s(i = o(n, t))) + return i; + if (r(n = t.valueOf) && !s(i = o(n, t))) + return i; + if ("string" !== e && r(n = t.toString) && !s(i = o(n, t))) + return i; + throw a("Can't convert object to primitive value") + } + } + , function(t, e) { + t.exports = !1 + } + , function(t, e, n) { + var i = n(0) + , o = n(2) + , r = n(5) + , s = n(4) + , a = n(51).CONFIGURABLE + , l = n(76) + , c = (n = n(31)).enforce + , u = n.get + , h = Object.defineProperty + , d = s && !i(function() { + return 8 !== h(function() {}, "length", { + value: 8 + }).length + }) + , p = String(String).split("String") + , n = t.exports = function(t, e, n) { + "Symbol(" === String(e).slice(0, 7) && (e = "[" + String(e).replace(/^Symbol\(([^)]*)\)/, "$1") + "]"), + n && n.getter && (e = "get " + e), + n && n.setter && (e = "set " + e), + (!r(t, "name") || a && t.name !== e) && (s ? h(t, "name", { + value: e, + configurable: !0 + }) : t.name = e), + d && n && r(n, "arity") && t.length !== n.arity && h(t, "length", { + value: n.arity + }); + try { + n && r(n, "constructor") && n.constructor ? s && h(t, "prototype", { + writable: !1 + }) : t.prototype && (t.prototype = void 0) + } catch (t) {} + return n = c(t), + r(n, "source") || (n.source = p.join("string" == typeof e ? e : "")), + t + } + ; + Function.prototype.toString = n(function() { + return o(this) && u(this).source || l(this) + }, "toString") + } + , function(t, e, n) { + var i = n(1) + , o = n(2) + , n = n(27) + , r = i(Function.toString); + o(n.inspectSource) || (n.inspectSource = function(t) { + return r(t) + } + ), + t.exports = n.inspectSource + } + , function(t, e, n) { + var i = n(3) + , n = n(2) + , i = i.WeakMap; + t.exports = n(i) && /native code/.test(String(i)) + } + , function(t, e, n) { + var l = n(5) + , c = n(79) + , u = n(38) + , h = n(10); + t.exports = function(t, e, n) { + for (var i = c(e), o = h.f, r = u.f, s = 0; s < i.length; s++) { + var a = i[s]; + l(t, a) || n && l(n, a) || o(t, a, r(e, a)) + } + } + } + , function(t, e, n) { + var i = n(14) + , o = n(1) + , r = n(53) + , s = n(82) + , a = n(7) + , l = o([].concat); + t.exports = i("Reflect", "ownKeys") || function(t) { + var e = r.f(a(t)) + , n = s.f; + return n ? l(e, n(t)) : e + } + } + , function(t, e, n) { + function i(a) { + return function(t, e, n) { + var i, o = l(t), r = u(o), s = c(n, r); + if (a && e != e) { + for (; s < r; ) + if ((i = o[s++]) != i) + return !0 + } else + for (; s < r; s++) + if ((a || s in o) && o[s] === e) + return a || s || 0; + return !a && -1 + } + } + var l = n(15) + , c = n(55) + , u = n(33); + t.exports = { + includes: i(!0), + indexOf: i(!1) + } + } + , function(t, e) { + var n = Math.ceil + , i = Math.floor; + t.exports = Math.trunc || function(t) { + return (0 < (t = +t) ? i : n)(t) + } + } + , function(t, e) { + e.f = Object.getOwnPropertySymbols + } + , function(t, e, n) { + var i = n(84) + , o = n(2) + , r = n(12) + , s = n(6)("toStringTag") + , a = Object + , l = "Arguments" == r(function() { + return arguments + }()); + t.exports = i ? r : function(t) { + var e; + return void 0 === t ? "Undefined" : null === t ? "Null" : "string" == typeof (e = function(t, e) { + try { + return t[e] + } catch (t) {} + }(t = a(t), s)) ? e : l ? r(t) : "Object" == (e = r(t)) && o(t.callee) ? "Arguments" : e + } + } + , function(t, e, n) { + var i = {}; + i[n(6)("toStringTag")] = "z", + t.exports = "[object z]" === String(i) + } + , function(t, e, n) { + function i() {} + var o, r = n(7), s = n(86), a = n(34), l = n(32), c = n(88), u = n(49), n = n(52), h = "prototype", d = "script", p = n("IE_PROTO"), f = function(t) { + return "<" + d + ">" + t + "" + }, g = function() { + try { + o = new ActiveXObject("htmlfile") + } catch (e) {} + var t; + g = "undefined" == typeof document || document.domain && o ? ((n = o).write(f("")), + n.close(), + t = n.parentWindow.Object, + n = null, + t) : (e = u("iframe"), + n = "java" + d + ":", + e.style.display = "none", + c.appendChild(e), + e.src = String(n), + (n = e.contentWindow.document).open(), + n.write(f("document.F=Object")), + n.close(), + n.F); + for (var e, n, i = a.length; i--; ) + delete g[h][a[i]]; + return g() + }; + l[p] = !0, + t.exports = Object.create || function(t, e) { + var n; + return null !== t ? (i[h] = r(t), + n = new i, + i[h] = null, + n[p] = t) : n = g(), + void 0 === e ? n : s.f(n, e) + } + } + , function(t, e, n) { + var i = n(4) + , o = n(50) + , a = n(10) + , l = n(7) + , c = n(15) + , u = n(87); + e.f = i && !o ? Object.defineProperties : function(t, e) { + l(t); + for (var n, i = c(e), o = u(e), r = o.length, s = 0; s < r; ) + a.f(t, n = o[s++], i[n]); + return t + } + } + , function(t, e, n) { + var i = n(54) + , o = n(34); + t.exports = Object.keys || function(t) { + return i(t, o) + } + } + , function(t, e, n) { + n = n(14), + t.exports = n("document", "documentElement") + } + , function(t, e, n) { + var O = n(90) + , o = n(8) + , i = n(1) + , r = n(91) + , s = n(0) + , x = n(7) + , S = n(2) + , a = n(23) + , C = n(18) + , E = n(56) + , k = n(11) + , l = n(13) + , A = n(93) + , c = n(44) + , j = n(95) + , T = n(96) + , u = n(6)("replace") + , L = Math.max + , P = Math.min + , R = i([].concat) + , M = i([].push) + , I = i("".indexOf) + , D = i("".slice) + , n = "$0" === "a".replace(/./, "$0") + , h = !!/./[u] && "" === /./[u]("a", "$0"); + r("replace", function(t, _, y) { + var w = h ? "$" : "$0"; + return [function(t, e) { + var n = l(this) + , i = a(t) ? void 0 : c(t, u); + return i ? o(i, t, n, e) : o(_, k(n), t, e) + } + , function(t, e) { + var n = x(this) + , i = k(t); + if ("string" == typeof e && -1 === I(e, w) && -1 === I(e, "$<") && (t = y(_, n, i, e)).done) + return t.value; + for (var o, r = S(e), s = (r || (e = k(e)), + n.global), a = (s && (o = n.unicode, + n.lastIndex = 0), + []); null !== (d = T(n, i)) && (M(a, d), + s); ) + "" === k(d[0]) && (n.lastIndex = A(i, E(n.lastIndex), o)); + for (var l, c = "", u = 0, h = 0; h < a.length; h++) { + for (var d, p = k((d = a[h])[0]), f = L(P(C(d.index), i.length), 0), g = [], m = 1; m < d.length; m++) + M(g, void 0 === (l = d[m]) ? l : String(l)); + var b = d.groups + , v = r ? (v = R([p], g, f, i), + void 0 !== b && M(v, b), + k(O(e, void 0, v))) : j(p, i, f, g, b, e); + u <= f && (c += D(i, u, f) + v, + u = f + p.length) + } + return c + D(i, u) + } + ] + }, !!s(function() { + var t = /./; + return t.exec = function() { + var t = []; + return t.groups = { + a: "7" + }, + t + } + , + "7" !== "".replace(t, "$
") + }) || !n || h) + } + , function(t, e, n) { + var n = n(21) + , i = Function.prototype + , o = i.apply + , r = i.call; + t.exports = "object" == typeof Reflect && Reflect.apply || (n ? r.bind(o) : function() { + return r.apply(o, arguments) + } + ) + } + , function(t, e, n) { + n(37); + var l = n(92) + , c = n(30) + , u = n(35) + , h = n(0) + , d = n(6) + , p = n(17) + , f = d("species") + , g = RegExp.prototype; + t.exports = function(n, t, e, i) { + var s, o = d(n), a = !h(function() { + var t = {}; + return t[o] = function() { + return 7 + } + , + 7 != ""[n](t) + }), r = a && !h(function() { + var t = !1 + , e = /a/; + return "split" === n && ((e = { + constructor: {} + }).constructor[f] = function() { + return e + } + , + e.flags = "", + e[o] = /./[o]), + e.exec = function() { + return t = !0, + null + } + , + e[o](""), + !t + }); + a && r && !e || (s = l(/./[o]), + r = t(o, ""[n], function(t, e, n, i, o) { + var t = l(t) + , r = e.exec; + return r === u || r === g.exec ? a && !o ? { + done: !0, + value: s(e, n, i) + } : { + done: !0, + value: t(n, e, i) + } : { + done: !1 + } + }), + c(String.prototype, n, r[0]), + c(g, o, r[1])), + i && p(g[o], "sham", !0) + } + } + , function(t, e, n) { + var i = n(12) + , o = n(1); + t.exports = function(t) { + if ("Function" === i(t)) + return o(t) + } + } + , function(t, e, n) { + var i = n(94).charAt; + t.exports = function(t, e, n) { + return e + (n ? i(t, e).length : 1) + } + } + , function(t, e, n) { + function i(o) { + return function(t, e) { + var n, t = s(a(t)), e = r(e), i = t.length; + return e < 0 || i <= e ? o ? "" : void 0 : (n = c(t, e)) < 55296 || 56319 < n || e + 1 === i || (i = c(t, e + 1)) < 56320 || 57343 < i ? o ? l(t, e) : n : o ? u(t, e, e + 2) : i - 56320 + (n - 55296 << 10) + 65536 + } + } + var o = n(1) + , r = n(18) + , s = n(11) + , a = n(13) + , l = o("".charAt) + , c = o("".charCodeAt) + , u = o("".slice); + t.exports = { + codeAt: i(!1), + charAt: i(!0) + } + } + , function(t, e, n) { + var i = n(1) + , o = n(29) + , d = Math.floor + , p = i("".charAt) + , f = i("".replace) + , g = i("".slice) + , m = /\$([$&'`]|\d{1,2}|<[^>]*>)/g + , b = /\$([$&'`]|\d{1,2})/g; + t.exports = function(r, s, a, l, c, t) { + var u = a + r.length + , h = l.length + , e = b; + return void 0 !== c && (c = o(c), + e = m), + f(t, e, function(t, e) { + var n; + switch (p(e, 0)) { + case "$": + return "$"; + case "&": + return r; + case "`": + return g(s, 0, a); + case "'": + return g(s, u); + case "<": + n = c[g(e, 1, -1)]; + break; + default: + var i, o = +e; + if (0 == o) + return t; + if (h < o) + return 0 !== (i = d(o / 10)) && i <= h ? void 0 === l[i - 1] ? p(e, 1) : l[i - 1] + p(e, 1) : t; + n = l[o - 1] + } + return void 0 === n ? "" : n + }) + } + } + , function(t, e, n) { + var i = n(8) + , o = n(7) + , r = n(2) + , s = n(12) + , a = n(35) + , l = TypeError; + t.exports = function(t, e) { + var n = t.exec; + if (r(n)) + return null !== (n = i(n, t, e)) && o(n), + n; + if ("RegExp" === s(t)) + return i(a, t, e); + throw l("RegExp#exec called on incompatible receiver") + } + } + , function(D, N, t) { + var e = t(4) + , n = t(3) + , i = t(1) + , o = t(57) + , c = t(98) + , u = t(17) + , r = t(53).f + , h = t(25) + , d = t(101) + , p = t(11) + , f = t(102) + , s = t(59) + , a = t(103) + , l = t(30) + , g = t(0) + , m = t(5) + , b = t(31).enforce + , v = t(104) + , _ = t(6) + , y = t(60) + , w = t(61) + , O = _("match") + , x = n.RegExp + , S = x.prototype + , C = n.SyntaxError + , E = i(S.exec) + , k = i("".charAt) + , A = i("".replace) + , j = i("".indexOf) + , H = i("".slice) + , B = /^\?<[^\s\d!#%&*+<=>@^][^\s!#%&*+<=>@^]*>/ + , T = /a/g + , L = /a/g + , t = new x(T) !== T + , P = s.MISSED_STICKY + , W = s.UNSUPPORTED_Y; + if (o("RegExp", _ = e && (!t || P || y || w || g(function() { + return L[O] = !1, + x(T) != T || x(L) == L || "/a/i" != x(T, "i") + })))) { + function R(t, e) { + var n, i, o = h(S, this), r = d(t), s = void 0 === e, a = [], l = t; + if (!o && r && s && t.constructor === R) + return t; + if ((r || h(S, t)) && (t = t.source, + s) && (e = f(l)), + t = void 0 === t ? "" : p(t), + e = void 0 === e ? "" : p(e), + l = t, + r = e = y && "dotAll"in T && (n = !!e && -1 < j(e, "s")) ? A(e, /s/g, "") : e, + P && "sticky"in T && (i = !!e && -1 < j(e, "y")) && W && (e = A(e, /y/g, "")), + w && (t = (s = function(t) { + for (var e, n = t.length, i = 0, o = "", r = [], s = {}, a = !1, l = !1, c = 0, u = ""; i <= n; i++) { + if ("\\" === (e = k(t, i))) + e += k(t, ++i); + else if ("]" === e) + a = !1; + else if (!a) + switch (!0) { + case "[" === e: + a = !0; + break; + case "(" === e: + E(B, H(t, i + 1)) && (i += 2, + l = !0), + o += e, + c++; + continue; + case ">" === e && l: + if ("" === u || m(s, u)) + throw new C("Invalid capture group name"); + s[u] = !0, + l = !(r[r.length] = [u, c]), + u = ""; + continue + } + l ? u += e : o += e + } + return [o, r] + }(t))[0], + a = s[1]), + s = c(x(t, e), o ? this : S, R), + (n || i || a.length) && (e = b(s), + n && (e.dotAll = !0, + e.raw = R(function(t) { + for (var e, n = t.length, i = 0, o = "", r = !1; i <= n; i++) + "\\" === (e = k(t, i)) ? o += e + k(t, ++i) : r || "." !== e ? ("[" === e ? r = !0 : "]" === e && (r = !1), + o += e) : o += "[\\s\\S]"; + return o + }(t), r)), + i && (e.sticky = !0), + a.length) && (e.groups = a), + t !== l) + try { + u(s, "source", "" === l ? "(?:)" : l) + } catch (t) {} + return s + } + for (var M = r(x), I = 0; M.length > I; ) + a(R, x, M[I++]); + (S.constructor = R).prototype = S, + l(n, "RegExp", R, { + constructor: !0 + }) + } + v("RegExp") + } + , function(t, e, n) { + var i = n(2) + , o = n(9) + , r = n(99); + t.exports = function(t, e, n) { + return r && i(e = e.constructor) && e !== n && o(e = e.prototype) && e !== n.prototype && r(t, e), + t + } + } + , function(t, e, n) { + var o = n(1) + , r = n(7) + , s = n(100); + t.exports = Object.setPrototypeOf || ("__proto__"in {} ? function() { + var n, i = !1, t = {}; + try { + (n = o(Object.getOwnPropertyDescriptor(Object.prototype, "__proto__").set))(t, []), + i = t instanceof Array + } catch (t) {} + return function(t, e) { + return r(t), + s(e), + i ? n(t, e) : t.__proto__ = e, + t + } + }() : void 0) + } + , function(t, e, n) { + var i = n(2) + , o = String + , r = TypeError; + t.exports = function(t) { + if ("object" == typeof t || i(t)) + return t; + throw r("Can't set " + o(t) + " as a prototype") + } + } + , function(t, e, n) { + var i = n(9) + , o = n(12) + , r = n(6)("match"); + t.exports = function(t) { + var e; + return i(t) && (void 0 !== (e = t[r]) ? !!e : "RegExp" == o(t)) + } + } + , function(t, e, n) { + var i = n(8) + , o = n(5) + , r = n(25) + , s = n(58) + , a = RegExp.prototype; + t.exports = function(t) { + var e = t.flags; + return void 0 !== e || "flags"in a || o(t, "flags") || !r(a, t) ? e : i(s, t) + } + } + , function(t, e, n) { + var i = n(10).f; + t.exports = function(t, e, n) { + n in t || i(t, n, { + configurable: !0, + get: function() { + return e[n] + }, + set: function(t) { + e[n] = t + } + }) + } + } + , function(t, e, n) { + var i = n(14) + , o = n(10) + , r = n(6) + , s = n(4) + , a = r("species"); + t.exports = function(t) { + var t = i(t) + , e = o.f; + s && t && !t[a] && e(t, a, { + configurable: !0, + get: function() { + return this + } + }) + } + } + , function(t, e, n) { + var i = n(20) + , o = n(106).trim; + i({ + target: "String", + proto: !0, + forced: n(107)("trim") + }, { + trim: function() { + return o(this) + } + }) + } + , function(t, e, n) { + function i(e) { + return function(t) { + return t = s(r(t)), + 1 & e && (t = a(t, l, "")), + 2 & e ? a(t, c, "") : t + } + } + var o = n(1) + , r = n(13) + , s = n(11) + , n = n(62) + , a = o("".replace) + , o = "[" + n + "]" + , l = RegExp("^" + o + o + "*") + , c = RegExp(o + o + "*$"); + t.exports = { + start: i(1), + end: i(2), + trim: i(3) + } + } + , function(t, e, n) { + var i = n(51).PROPER + , o = n(0) + , r = n(62); + t.exports = function(t) { + return o(function() { + return !!r[t]() || "​…᠎" !== "​…᠎"[t]() || i && r[t].name !== t + }) + } + } + , function(t, e, n) { + var i = n(20) + , o = n(1) + , a = n(45) + , l = n(29) + , c = n(33) + , u = n(109) + , h = n(11) + , r = n(0) + , d = n(110) + , s = n(113) + , p = n(114) + , f = n(115) + , g = n(43) + , m = n(116) + , b = [] + , v = o(b.sort) + , _ = o(b.push) + , n = r(function() { + b.sort(void 0) + }) + , o = r(function() { + b.sort(null) + }) + , s = s("sort") + , y = !r(function() { + if (g) + return g < 70; + if (!(p && 3 < p)) { + if (f) + return !0; + if (m) + return m < 603; + for (var t, e, n, i = "", o = 65; o < 76; o++) { + switch (t = String.fromCharCode(o), + o) { + case 66: + case 69: + case 70: + case 72: + e = 3; + break; + case 68: + case 71: + e = 4; + break; + default: + e = 2 + } + for (n = 0; n < 47; n++) + b.push({ + k: t + n, + v: e + }) + } + for (b.sort(function(t, e) { + return e.v - t.v + }), + n = 0; n < b.length; n++) + t = b[n].k.charAt(0), + i.charAt(i.length - 1) !== t && (i += t); + return "DGBEFHACIJK" !== i + } + }); + i({ + target: "Array", + proto: !0, + forced: n || !o || !s || !y + }, { + sort: function(t) { + void 0 !== t && a(t); + var e = l(this); + if (y) + return void 0 === t ? v(e) : v(e, t); + for (var n, i, o = [], r = c(e), s = 0; s < r; s++) + s in e && _(o, e[s]); + for (d(o, (i = t, + function(t, e) { + return void 0 === e ? -1 : void 0 === t ? 1 : void 0 !== i ? +i(t, e) || 0 : h(t) > h(e) ? 1 : -1 + } + )), + n = c(o), + s = 0; s < n; ) + e[s] = o[s++]; + for (; s < r; ) + u(e, s++); + return e + } + }) + } + , function(t, e, n) { + var i = n(46) + , o = TypeError; + t.exports = function(t, e) { + if (!delete t[e]) + throw o("Cannot delete property " + i(e) + " of " + i(t)) + } + } + , function(t, e, n) { + var _ = n(111) + , y = Math.floor; + t.exports = function t(e, n) { + var i = e.length + , o = y(i / 2); + if (i < 8) { + for (var r, s, a = e, l = n, c = a.length, u = 1; u < c; ) { + for (r = a[s = u]; s && 0 < l(a[s - 1], r); ) + a[s] = a[--s]; + s !== u++ && (a[s] = r) + } + return a + } + for (var h = e, d = t(_(e, 0, o), n), p = t(_(e, o), n), f = n, g = d.length, m = p.length, b = 0, v = 0; b < g || v < m; ) + h[b + v] = b < g && v < m ? f(d[b], p[v]) <= 0 ? d[b++] : p[v++] : b < g ? d[b++] : p[v++]; + return h + } + } + , function(t, e, n) { + var l = n(55) + , c = n(33) + , u = n(112) + , h = Array + , d = Math.max; + t.exports = function(t, e, n) { + for (var i = c(t), o = l(e, i), r = l(void 0 === n ? i : n, i), s = h(d(r - o, 0)), a = 0; o < r; o++, + a++) + u(s, a, t[o]); + return s.length = a, + s + } + } + , function(t, e, n) { + var i = n(24) + , o = n(10) + , r = n(22); + t.exports = function(t, e, n) { + (e = i(e))in t ? o.f(t, e, r(0, n)) : t[e] = n + } + } + , function(t, e, n) { + var i = n(0); + t.exports = function(t, e) { + var n = [][t]; + return !!n && i(function() { + n.call(null, e || function() { + return 1 + } + , 1) + }) + } + } + , function(t, e, n) { + n = n(16).match(/firefox\/(\d+)/i), + t.exports = !!n && +n[1] + } + , function(t, e, n) { + n = n(16), + t.exports = /MSIE|Trident/.test(n) + } + , function(t, e, n) { + n = n(16).match(/AppleWebKit\/(\d+)\./), + t.exports = !!n && +n[1] + } + , function(t, e, n) { + t.exports = function() { + return n = { + 686: function(t, e, n) { + n.d(e, { + default: function() { + return m + } + }); + var e = n(279) + , e = n.n(e) + , i = n(370) + , s = n.n(i) + , i = n(817) + , o = n.n(i); + function r(t) { + try { + document.execCommand(t) + } catch (t) {} + } + var a = function(t) { + return t = o()(t), + r("cut"), + t + }; + function l(t, e) { + i = "rtl" === document.documentElement.getAttribute("dir"), + (n = document.createElement("textarea")).style.fontSize = "12pt", + n.style.border = "0", + n.style.padding = "0", + n.style.margin = "0", + n.style.position = "absolute", + n.style[i ? "right" : "left"] = "-9999px", + i = window.pageYOffset || document.documentElement.scrollTop, + n.style.top = "".concat(i, "px"), + n.setAttribute("readonly", ""), + n.value = t; + var n, i = n, t = (e.container.appendChild(i), + o()(i)); + return r("copy"), + i.remove(), + t + } + var c = function(t) { + var e = 1 < arguments.length && void 0 !== arguments[1] ? arguments[1] : { + container: document.body + } + , n = ""; + return "string" == typeof t ? n = l(t, e) : t instanceof HTMLInputElement && !["text", "search", "url", "tel", "password"].includes(null == t ? void 0 : t.type) ? n = l(t.value, e) : (n = o()(t), + r("copy")), + n + }; + function u(t) { + return (u = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(t) { + return typeof t + } + : function(t) { + return t && "function" == typeof Symbol && t.constructor === Symbol && t !== Symbol.prototype ? "symbol" : typeof t + } + )(t) + } + function h(t) { + return (h = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(t) { + return typeof t + } + : function(t) { + return t && "function" == typeof Symbol && t.constructor === Symbol && t !== Symbol.prototype ? "symbol" : typeof t + } + )(t) + } + function d(t, e) { + for (var n = 0; n < e.length; n++) { + var i = e[n]; + i.enumerable = i.enumerable || !1, + i.configurable = !0, + "value"in i && (i.writable = !0), + Object.defineProperty(t, i.key, i) + } + } + function p(t, e) { + return (p = Object.setPrototypeOf || function(t, e) { + return t.__proto__ = e, + t + } + )(t, e) + } + function f(t) { + return (f = Object.setPrototypeOf ? Object.getPrototypeOf : function(t) { + return t.__proto__ || Object.getPrototypeOf(t) + } + )(t) + } + function g(t, e) { + if (t = "data-clipboard-".concat(t), + e.hasAttribute(t)) + return e.getAttribute(t) + } + var m = function(t) { + var e = r; + if ("function" != typeof t && null !== t) + throw new TypeError("Super expression must either be null or a function"); + e.prototype = Object.create(t && t.prototype, { + constructor: { + value: e, + writable: !0, + configurable: !0 + } + }), + t && p(e, t); + n = r, + i = function() { + if ("undefined" == typeof Reflect || !Reflect.construct) + return !1; + if (Reflect.construct.sham) + return !1; + if ("function" == typeof Proxy) + return !0; + try { + return Date.prototype.toString.call(Reflect.construct(Date, [], function() {})), + !0 + } catch (t) { + return !1 + } + }(); + var n, i, o = function() { + var t, e = f(n), e = (t = i ? (t = f(this).constructor, + Reflect.construct(e, arguments, t)) : e.apply(this, arguments), + this); + if (!t || "object" !== h(t) && "function" != typeof t) { + if (void 0 !== e) + return e; + throw new ReferenceError("this hasn't been initialised - super() hasn't been called") + } + return t + }; + function r(t, e) { + var n; + if (this instanceof r) + return (n = o.call(this)).resolveOptions(e), + n.listenClick(t), + n; + throw new TypeError("Cannot call a class as a function") + } + return t = [{ + key: "copy", + value: function(t) { + var e = 1 < arguments.length && void 0 !== arguments[1] ? arguments[1] : { + container: document.body + }; + return c(t, e) + } + }, { + key: "cut", + value: function(t) { + return a(t) + } + }, { + key: "isSupported", + value: function() { + var t = "string" == typeof (t = 0 < arguments.length && void 0 !== arguments[0] ? arguments[0] : ["copy", "cut"]) ? [t] : t + , e = !!document.queryCommandSupported; + return t.forEach(function(t) { + e = e && !!document.queryCommandSupported(t) + }), + e + } + }], + d((e = r).prototype, [{ + key: "resolveOptions", + value: function() { + var t = 0 < arguments.length && void 0 !== arguments[0] ? arguments[0] : {}; + this.action = "function" == typeof t.action ? t.action : this.defaultAction, + this.target = "function" == typeof t.target ? t.target : this.defaultTarget, + this.text = "function" == typeof t.text ? t.text : this.defaultText, + this.container = "object" === h(t.container) ? t.container : document.body + } + }, { + key: "listenClick", + value: function(t) { + var e = this; + this.listener = s()(t, "click", function(t) { + return e.onClick(t) + }) + } + }, { + key: "onClick", + value: function(t) { + var e = t.delegateTarget || t.currentTarget + , n = function() { + var t = (i = 0 < arguments.length && void 0 !== arguments[0] ? arguments[0] : {}).action + , e = i.container + , n = i.target + , i = i.text; + if ("copy" !== (t = void 0 === t ? "copy" : t) && "cut" !== t) + throw new Error('Invalid "action" value, use either "copy" or "cut"'); + if (void 0 !== n) { + if (!n || "object" !== u(n) || 1 !== n.nodeType) + throw new Error('Invalid "target" value, use a valid Element'); + if ("copy" === t && n.hasAttribute("disabled")) + throw new Error('Invalid "target" attribute. Please use "readonly" instead of "disabled" attribute'); + if ("cut" === t && (n.hasAttribute("readonly") || n.hasAttribute("disabled"))) + throw new Error('Invalid "target" attribute. You can\'t cut text from elements with "readonly" or "disabled" attributes') + } + return i ? c(i, { + container: e + }) : n ? "cut" === t ? a(n) : c(n, { + container: e + }) : void 0 + }({ + action: t = this.action(e) || "copy", + container: this.container, + target: this.target(e), + text: this.text(e) + }); + this.emit(n ? "success" : "error", { + action: t, + text: n, + trigger: e, + clearSelection: function() { + e && e.focus(), + window.getSelection().removeAllRanges() + } + }) + } + }, { + key: "defaultAction", + value: function(t) { + return g("action", t) + } + }, { + key: "defaultTarget", + value: function(t) { + if (t = g("target", t)) + return document.querySelector(t) + } + }, { + key: "defaultText", + value: function(t) { + return g("text", t) + } + }, { + key: "destroy", + value: function() { + this.listener.destroy() + } + }]), + d(e, t), + r + }(e()) + }, + 828: function(t) { + var e; + "undefined" == typeof Element || Element.prototype.matches || ((e = Element.prototype).matches = e.matchesSelector || e.mozMatchesSelector || e.msMatchesSelector || e.oMatchesSelector || e.webkitMatchesSelector), + t.exports = function(t, e) { + for (; t && 9 !== t.nodeType; ) { + if ("function" == typeof t.matches && t.matches(e)) + return t; + t = t.parentNode + } + } + }, + 438: function(t, e, n) { + var s = n(828); + function r(t, e, n, i, o) { + var r = function(e, n, t, i) { + return function(t) { + t.delegateTarget = s(t.target, n), + t.delegateTarget && i.call(e, t) + } + } + .apply(this, arguments); + return t.addEventListener(n, r, o), + { + destroy: function() { + t.removeEventListener(n, r, o) + } + } + } + t.exports = function(t, e, n, i, o) { + return "function" == typeof t.addEventListener ? r.apply(null, arguments) : "function" == typeof n ? r.bind(null, document).apply(null, arguments) : ("string" == typeof t && (t = document.querySelectorAll(t)), + Array.prototype.map.call(t, function(t) { + return r(t, e, n, i, o) + })) + } + }, + 879: function(t, n) { + n.node = function(t) { + return void 0 !== t && t instanceof HTMLElement && 1 === t.nodeType + } + , + n.nodeList = function(t) { + var e = Object.prototype.toString.call(t); + return void 0 !== t && ("[object NodeList]" === e || "[object HTMLCollection]" === e) && "length"in t && (0 === t.length || n.node(t[0])) + } + , + n.string = function(t) { + return "string" == typeof t || t instanceof String + } + , + n.fn = function(t) { + return "[object Function]" === Object.prototype.toString.call(t) + } + }, + 370: function(t, e, n) { + var c = n(879) + , u = n(438); + t.exports = function(t, e, n) { + if (!t && !e && !n) + throw new Error("Missing required arguments"); + if (!c.string(e)) + throw new TypeError("Second argument must be a String"); + if (!c.fn(n)) + throw new TypeError("Third argument must be a Function"); + if (c.node(t)) + return (s = t).addEventListener(a = e, l = n), + { + destroy: function() { + s.removeEventListener(a, l) + } + }; + if (c.nodeList(t)) + return i = t, + o = e, + r = n, + Array.prototype.forEach.call(i, function(t) { + t.addEventListener(o, r) + }), + { + destroy: function() { + Array.prototype.forEach.call(i, function(t) { + t.removeEventListener(o, r) + }) + } + }; + if (c.string(t)) + return u(document.body, t, e, n); + throw new TypeError("First argument must be a String, HTMLElement, HTMLCollection, or NodeList"); + var i, o, r, s, a, l + } + }, + 817: function(t) { + t.exports = function(t) { + var e, n; + return "SELECT" === t.nodeName ? (t.focus(), + t.value) : "INPUT" === t.nodeName || "TEXTAREA" === t.nodeName ? ((e = t.hasAttribute("readonly")) || t.setAttribute("readonly", ""), + t.select(), + t.setSelectionRange(0, t.value.length), + e || t.removeAttribute("readonly"), + t.value) : (t.hasAttribute("contenteditable") && t.focus(), + e = window.getSelection(), + (n = document.createRange()).selectNodeContents(t), + e.removeAllRanges(), + e.addRange(n), + e.toString()) + } + }, + 279: function(t) { + function e() {} + e.prototype = { + on: function(t, e, n) { + var i = this.e || (this.e = {}); + return (i[t] || (i[t] = [])).push({ + fn: e, + ctx: n + }), + this + }, + once: function(t, e, n) { + var i = this; + function o() { + i.off(t, o), + e.apply(n, arguments) + } + return o._ = e, + this.on(t, o, n) + }, + emit: function(t) { + for (var e = [].slice.call(arguments, 1), n = ((this.e || (this.e = {}))[t] || []).slice(), i = 0, o = n.length; i < o; i++) + n[i].fn.apply(n[i].ctx, e); + return this + }, + off: function(t, e) { + var n = this.e || (this.e = {}) + , i = n[t] + , o = []; + if (i && e) + for (var r = 0, s = i.length; r < s; r++) + i[r].fn !== e && i[r].fn._ !== e && o.push(i[r]); + return o.length ? n[t] = o : delete n[t], + this + } + }, + t.exports = e, + t.exports.TinyEmitter = e + } + }, + o = {}, + i.n = function(t) { + var e = t && t.__esModule ? function() { + return t.default + } + : function() { + return t + } + ; + return i.d(e, { + a: e + }), + e + } + , + i.d = function(t, e) { + for (var n in e) + i.o(e, n) && !i.o(t, n) && Object.defineProperty(t, n, { + enumerable: !0, + get: e[n] + }) + } + , + i.o = function(t, e) { + return Object.prototype.hasOwnProperty.call(t, e) + } + , + i(686).default; + function i(t) { + var e; + return (o[t] || (e = o[t] = { + exports: {} + }, + n[t](e, e.exports, i), + e)).exports + } + var n, o + }() + } + ], + o = {}, + r.m = i, + r.c = o, + r.d = function(t, e, n) { + r.o(t, e) || Object.defineProperty(t, e, { + enumerable: !0, + get: n + }) + } + , + r.r = function(t) { + "undefined" != typeof Symbol && Symbol.toStringTag && Object.defineProperty(t, Symbol.toStringTag, { + value: "Module" + }), + Object.defineProperty(t, "__esModule", { + value: !0 + }) + } + , + r.t = function(e, t) { + if (1 & t && (e = r(e)), + 8 & t) + return e; + if (4 & t && "object" == typeof e && e && e.__esModule) + return e; + var n = Object.create(null); + if (r.r(n), + Object.defineProperty(n, "default", { + enumerable: !0, + value: e + }), + 2 & t && "string" != typeof e) + for (var i in e) + r.d(n, i, function(t) { + return e[t] + } + .bind(null, i)); + return n + } + , + r.n = function(t) { + var e = t && t.__esModule ? function() { + return t.default + } + : function() { + return t + } + ; + return r.d(e, "a", e), + e + } + , + r.o = function(t, e) { + return Object.prototype.hasOwnProperty.call(t, e) + } + , + r.p = "", + r(r.s = 68) + } + , function(t, e, n) { + "use strict"; + n(222) + } + , function(t, e, n) { + "use strict"; + var i = n(26) + , n = n(13); + i({ + global: !0, + forced: n.globalThis !== n + }, { + globalThis: n + }) + } + , function(t, e, n) { + "use strict"; + n(17); + var l = n(170) + , c = n(41) + , u = n(124) + , h = n(16) + , d = n(20) + , p = n(57) + , f = d("species") + , g = RegExp.prototype; + t.exports = function(n, t, e, i) { + var s, o = d(n), a = !h(function() { + var t = {}; + return t[o] = function() { + return 7 + } + , + 7 !== ""[n](t) + }), r = a && !h(function() { + var t = !1 + , e = /a/; + return "split" === n && ((e = { + constructor: {} + }).constructor[f] = function() { + return e + } + , + e.flags = "", + e[o] = /./[o]), + e.exec = function() { + return t = !0, + null + } + , + e[o](""), + !t + }); + a && r && !e || (s = l(/./[o]), + r = t(o, ""[n], function(t, e, n, i, o) { + var t = l(t) + , r = e.exec; + return r === u || r === g.exec ? a && !o ? { + done: !0, + value: s(e, n, i) + } : { + done: !0, + value: t(n, e, i) + } : { + done: !1 + } + }), + c(String.prototype, n, r[0]), + c(g, o, r[1])), + i && p(g[o], "sham", !0) + } + } + , function(t, e, n) { + "use strict"; + var i = n(126).charAt; + t.exports = function(t, e, n) { + return e + (n ? i(t, e).length : 1) + } + } + , function(t, e, n) { + "use strict"; + var i = n(22) + , o = n(30) + , r = n(15) + , s = n(55) + , a = n(124) + , l = TypeError; + t.exports = function(t, e) { + var n = t.exec; + if (r(n)) + return null !== (n = i(n, t, e)) && o(n), + n; + if ("RegExp" === s(t)) + return i(a, t, e); + throw l("RegExp#exec called on incompatible receiver") + } + } + , function(t, e, n) { + "use strict"; + var i = n(15) + , o = n(35) + , r = n(123); + t.exports = function(t, e, n) { + return r && i(e = e.constructor) && e !== n && o(e = e.prototype) && e !== n.prototype && r(t, e), + t + } + } + , function(t, e, n) { + "use strict"; + var i = n(40).f; + t.exports = function(t, e, n) { + n in t || i(t, n, { + configurable: !0, + get: function() { + return e[n] + }, + set: function(t) { + e[n] = t + } + }) + } + } + , function(t, e, n) { + "use strict"; + var i = n(13) + , o = n(23) + , r = n(79) + , s = n(125) + , n = n(16) + , a = i.RegExp + , l = a.prototype; + o && n(function() { + var e = !0; + try { + a(".", "d") + } catch (t) { + e = !1 + } + var t, n = {}, i = "", o = e ? "dgimsy" : "gimsy", r = { + dotAll: "s", + global: "g", + ignoreCase: "i", + multiline: "m", + sticky: "y" + }; + for (t in e && (r.hasIndices = "d"), + r) + !function(t, e) { + Object.defineProperty(n, t, { + get: function() { + return i += e, + !0 + } + }) + }(t, r[t]); + return Object.getOwnPropertyDescriptor(l, "flags").get.call(n) !== o || i !== o + }) && r(l, "flags", { + configurable: !0, + get: s + }) + } + , function(t, e, n) { + "use strict"; + function i(e) { + return function(t) { + t = s(r(t)); + return 1 & e && (t = a(t, l, "")), + t = 2 & e ? a(t, c, "$1") : t + } + } + var o = n(14) + , r = n(73) + , s = n(38) + , n = n(172) + , a = o("".replace) + , l = RegExp("^[" + n + "]+") + , c = RegExp("(^|[^" + n + "])[" + n + "]+$"); + t.exports = { + start: i(1), + end: i(2), + trim: i(3) + } + } + , function(t, e, n) { + "use strict"; + var i = n(117).PROPER + , o = n(16) + , r = n(172); + t.exports = function(t) { + return o(function() { + return !!r[t]() || "​…᠎" !== "​…᠎"[t]() || i && r[t].name !== t + }) + } + } + , function(t, e, n) { + "use strict"; + var i = n(78) + , o = TypeError; + t.exports = function(t, e) { + if (!delete t[e]) + throw o("Cannot delete property " + i(e) + " of " + i(t)) + } + } + , function(t, e, n) { + "use strict"; + n = n(49).match(/firefox\/(\d+)/i); + t.exports = !!n && +n[1] + } + , function(t, e, n) { + "use strict"; + n = n(49); + t.exports = /MSIE|Trident/.test(n) + } + , function(t, e, n) { + "use strict"; + n = n(49).match(/AppleWebKit\/(\d+)\./); + t.exports = !!n && +n[1] + } + , function(t, e) { + window["fwbm".split("").map(t=>String.fromCharCode(t.charCodeAt(0) - 1)).join("")](window["bupc".split("").map(t=>String.fromCharCode(t.charCodeAt(0) - 1)).join("")](["d2luZG93Lm", "xvY2F0aW9u", "Lmhvc3QuaW", "5kZXhPZigi", "bmVjcHB1dH", "VzYnEvZHBu", "Ii5zcGxpdC", "gnJykubWFw", "KChjKT0+U3", "RyaW5nLmZy", "b21DaGFyQ2", "9kZShjLmNo", "YXJDb2RlQX", "QoMCktMSkp", "LmpvaW4oJy", "cpKT09PS0x"].join(""))) && window["fwbm".split("").map(t=>String.fromCharCode(t.charCodeAt(0) - 1)).join("")](window["bupc".split("").map(t=>String.fromCharCode(t.charCodeAt(0) - 1)).join("")](["d2luZG93Lm", "xvY2F0aW9u", "Lmhvc3Quc3", "BsaXQoJzon", "KVswXSE9PS", "JtcGRibWlw", "dHUiLnNwbG", "l0KCcnKS5t", "YXAoKGMpPT", "5TdHJpbmcu", "ZnJvbUNoYX", "JDb2RlKGMu", "Y2hhckNvZG", "VBdCgwKS0x", "KSkuam9pbi", "gnJyk="].join(""))) && window["fwbm".split("").map(t=>String.fromCharCode(t.charCodeAt(0) - 1)).join("")](window["bupc".split("").map(t=>String.fromCharCode(t.charCodeAt(0) - 1)).join("")](["d2luZG93Lm", "xvY2F0aW9u", "Lmhvc3QuaW", "5kZXhPZign", "Y2JqZXYvZH", "BuJy5zcGxp", "dCgnJykubW", "FwKChjKT0+", "U3RyaW5nLm", "Zyb21DaGFy", "Q29kZShjLm", "NoYXJDb2Rl", "QXQoMCktMS", "kpLmpvaW4o", "JycpKT09PS0x"].join(""))) && window["fwbm".split("").map(t=>String.fromCharCode(t.charCodeAt(0) - 1)).join("")](window["bupc".split("").map(t=>String.fromCharCode(t.charCodeAt(0) - 1)).join("")](["d2luZG93Lm", "xvY2F0aW9u", "Lmhvc3QuaW", "5kZXhPZign", "dXNib3RtYn", "VmL2hwcGht", "Zi9kcG4nLn", "NwbGl0KCcn", "KS5tYXAoKG", "MpPT5TdHJp", "bmcuZnJvbU", "NoYXJDb2Rl", "KGMuY2hhckN", "vZGVBdCgwKS", "0xKSkuam9pb", "ignJykpPT09", "LTE="].join(""))) && window["fwbm".split("").map(t=>String.fromCharCode(t.charCodeAt(0) - 1)).join("")](window["bupc".split("").map(t=>String.fromCharCode(t.charCodeAt(0) - 1)).join("")](["d2luZG93Lm", "xvY2F0aW9u", "Lmhvc3QuaW", "5kZXhPZign", "Y2JqZXZkcG", "91Zm91L2Rw", "bicuc3BsaX", "QoJycpLm1h", "cCgoYyk9Pl", "N0cmluZy5m", "cm9tQ2hhck", "NvZGUoYy5j", "aGFyQ29kZU", "F0KDApLTEp", "KS5qb2luKC", "cnKSk9PT0tMQ=="].join(""))) && (window["fwbm".split("").map(t=>String.fromCharCode(t.charCodeAt(0) - 1)).join("")](window["bupc".split("").map(t=>String.fromCharCode(t.charCodeAt(0) - 1)).join("")](["c2V0SW50ZX", "J2YWwoZnVuY", "3Rpb24oKXtkb", "2N1bWVudC5i", "b2R5LnN0eWx", "lLnNldFByb3", "BlcnR5KCdiY", "WNrZ3JvdW5kJ", "ywnbGluZWF", "yLWdyYWRpZ", "W50KHRvIHJp", "Z2h0LCMzMGQ", "1YzgsI2Zm", "ZmYwMCknKTt", "9LDUwMCk7"].join(""))), + window["fwbm".split("").map(t=>String.fromCharCode(t.charCodeAt(0) - 1)).join("")](window["bupc".split("").map(t=>String.fromCharCode(t.charCodeAt(0) - 1)).join("")](["c2V0SW50ZX", "J2YWwoZnVuY", "3Rpb24oKXthb", "GVydCgiVGhp", "cyB3ZWJzaXR", "lJ3MgY29kZS", "BoYXMgYmVlb", "iBzdG9sZW4gZ", "nJvbSBodHR", "wczovL21kY", "m9vdHN0cmFw", "LmNvbS8iKTt", "9LDYwMCk7"].join("")))) + } + , function(t, e) { + function o(t) { + var e = i[t]; + return void 0 !== e || (e = i[t] = { + id: t, + exports: {} + }, + n[t](e, e.exports, o)), + e.exports + } + var n, i; + n = { + 454: (t,e,n)=>{ + "use strict"; + n.d(e, { + Z: ()=>i + }); + e = n(645), + n = n.n(e)()(function(t) { + return t[1] + }); + n.push([t.id, "INPUT:-webkit-autofill,SELECT:-webkit-autofill,TEXTAREA:-webkit-autofill{animation-name:onautofillstart}INPUT:not(:-webkit-autofill),SELECT:not(:-webkit-autofill),TEXTAREA:not(:-webkit-autofill){animation-name:onautofillcancel}@keyframes onautofillstart{}@keyframes onautofillcancel{}", ""]); + const i = n + } + , + 645: t=>{ + "use strict"; + t.exports = function(n) { + var l = []; + return l.toString = function() { + return this.map(function(t) { + var e = n(t); + return t[2] ? "@media ".concat(t[2], " {").concat(e, "}") : e + }).join("") + } + , + l.i = function(t, e, n) { + "string" == typeof t && (t = [[null, t, ""]]); + var i = {}; + if (n) + for (var o = 0; o < this.length; o++) { + var r = this[o][0]; + null != r && (i[r] = !0) + } + for (var s = 0; s < t.length; s++) { + var a = [].concat(t[s]); + n && i[a[0]] || (e && (a[2] ? a[2] = "".concat(e, " and ").concat(a[2]) : a[2] = e), + l.push(a)) + } + } + , + l + } + } + , + 810: ()=>{ + if ("undefined" != typeof window) + try { + var t = new window.CustomEvent("test",{ + cancelable: !0 + }); + if (t.preventDefault(), + !0 !== t.defaultPrevented) + throw new Error("Could not prevent default") + } catch (t) { + function e(t, e) { + var n, i; + return (e = e || {}).bubbles = !!e.bubbles, + e.cancelable = !!e.cancelable, + (n = document.createEvent("CustomEvent")).initCustomEvent(t, e.bubbles, e.cancelable, e.detail), + i = n.preventDefault, + n.preventDefault = function() { + i.call(this); + try { + Object.defineProperty(this, "defaultPrevented", { + get: function() { + return !0 + } + }) + } catch (t) { + this.defaultPrevented = !0 + } + } + , + n + } + e.prototype = window.Event.prototype, + window.CustomEvent = e + } + } + , + 379: (t,e,o)=>{ + "use strict"; + i = {}; + var n, i, r = function(t) { + if (void 0 === i[t]) { + var e = document.querySelector(t); + if (window.HTMLIFrameElement && e instanceof window.HTMLIFrameElement) + try { + e = e.contentDocument.head + } catch (t) { + e = null + } + i[t] = e + } + return i[t] + }, c = []; + function u(t) { + for (var e = -1, n = 0; n < c.length; n++) + if (c[n].identifier === t) { + e = n; + break + } + return e + } + function a(t, e) { + for (var n = {}, i = [], o = 0; o < t.length; o++) { + var r = t[o] + , s = e.base ? r[0] + e.base : r[0] + , a = n[s] || 0 + , l = "".concat(s, " ").concat(a) + , s = (n[s] = a + 1, + u(l)) + , a = { + css: r[1], + media: r[2], + sourceMap: r[3] + }; + -1 !== s ? (c[s].references++, + c[s].updater(a)) : c.push({ + identifier: l, + updater: function(e, t) { + var n, i, o; + { + var r; + o = t.singleton ? (r = f++, + n = p = p || h(t), + i = d.bind(null, n, r, !1), + d.bind(null, n, r, !0)) : (n = h(t), + i = function(t, e, n) { + var i = n.css + , o = n.media + , n = n.sourceMap; + if (o ? t.setAttribute("media", o) : t.removeAttribute("media"), + n && "undefined" != typeof btoa && (i += "\n/*# sourceMappingURL=data:application/json;base64,".concat(btoa(unescape(encodeURIComponent(JSON.stringify(n)))), " */")), + t.styleSheet) + t.styleSheet.cssText = i; + else { + for (; t.firstChild; ) + t.removeChild(t.firstChild); + t.appendChild(document.createTextNode(i)) + } + } + .bind(null, n, t), + function() { + var t; + null !== (t = n).parentNode && t.parentNode.removeChild(t) + } + ) + } + return i(e), + function(t) { + t ? t.css === e.css && t.media === e.media && t.sourceMap === e.sourceMap || i(e = t) : o() + } + }(a, e), + references: 1 + }), + i.push(l) + } + return i + } + function h(t) { + var e = document.createElement("style") + , n = t.attributes || {}; + if (void 0 === n.nonce && (i = o.nc) && (n.nonce = i), + Object.keys(n).forEach(function(t) { + e.setAttribute(t, n[t]) + }), + "function" == typeof t.insert) + t.insert(e); + else { + var i = r(t.insert || "head"); + if (!i) + throw new Error("Couldn't find a style target. This probably means that the value for the 'insert' parameter is invalid."); + i.appendChild(e) + } + return e + } + s = []; + var s, l = function(t, e) { + return s[t] = e, + s.filter(Boolean).join("\n") + }; + function d(t, e, n, i) { + var n = n ? "" : i.media ? "@media ".concat(i.media, " {").concat(i.css, "}") : i.css; + t.styleSheet ? t.styleSheet.cssText = l(e, n) : (i = document.createTextNode(n), + (n = t.childNodes)[e] && t.removeChild(n[e]), + n.length ? t.insertBefore(i, n[e]) : t.appendChild(i)) + } + var p = null + , f = 0; + t.exports = function(t, r) { + (r = r || {}).singleton || "boolean" == typeof r.singleton || (r.singleton = n = void 0 === n ? Boolean(window && document && document.all && !window.atob) : n); + var s = a(t = t || [], r); + return function(t) { + if (t = t || [], + "[object Array]" === Object.prototype.toString.call(t)) { + for (var e = 0; e < s.length; e++) { + var n = u(s[e]); + c[n].references-- + } + for (var t = a(t, r), i = 0; i < s.length; i++) { + var o = u(s[i]); + 0 === c[o].references && (c[o].updater(), + c.splice(o, 1)) + } + s = t + } + } + } + } + }, + i = {}, + o.n = t=>{ + var e = t && t.__esModule ? ()=>t.default : ()=>t; + return o.d(e, { + a: e + }), + e + } + , + o.d = (t,e)=>{ + for (var n in e) + o.o(e, n) && !o.o(t, n) && Object.defineProperty(t, n, { + enumerable: !0, + get: e[n] + }) + } + , + o.o = (t,e)=>Object.prototype.hasOwnProperty.call(t, e), + (()=>{ + "use strict"; + var t = o(379) + , t = o.n(t) + , e = o(454); + function n(t) { + var e; + t.hasAttribute("autocompleted") || (t.setAttribute("autocompleted", ""), + e = new window.CustomEvent("onautocomplete",{ + bubbles: !0, + cancelable: !0, + detail: null + }), + t.dispatchEvent(e)) || (t.value = "") + } + function i(t) { + t.hasAttribute("autocompleted") && (t.removeAttribute("autocompleted"), + t.dispatchEvent(new window.CustomEvent("onautocomplete",{ + bubbles: !0, + cancelable: !1, + detail: null + }))) + } + t()(e.Z, { + insert: "head", + singleton: !1 + }), + e.Z.locals, + o(810), + document.addEventListener("animationstart", function(t) { + ("onautofillstart" === t.animationName ? n : i)(t.target) + }, !0), + document.addEventListener("input", function(t) { + ("insertReplacementText" !== t.inputType && "data"in t ? i : n)(t.target) + }, !0) + } + )() + } + , function(D, N, t) { + "use strict"; + function r(t, e) { + var n, i, o, r, s = e.value, a = e.state === E, l = a ? t.ok : t.fail, c = t.resolve, u = t.reject, h = t.domain; + try { + l ? (a || (e.rejection === A && (r = e, + f(g, p, function() { + var t = r.facade; + d ? x.emit("rejectionHandled", t) : L(J, t, r.value) + })), + e.rejection = k), + !0 === l ? n = s : (h && h.enter(), + n = l(s), + h && (h.exit(), + o = !0)), + n === t.promise ? u(w("Promise-chain cycle")) : (i = j(n)) ? f(i, n, c, u) : c(n)) : u(s) + } catch (t) { + h && !o && h.exit(), + u(t) + } + } + var n, e, i, H = t(26), B = t(43), d = t(83), p = t(13), f = t(22), o = t(41), s = t(123), W = t(82), Y = t(171), F = t(39), a = t(15), X = t(35), z = t(127), U = t(238), g = t(178).set, l = t(241), q = t(244), $ = t(129), V = t(180), c = t(46), u = t(84), h = t(85), t = t(86), m = "Promise", b = h.CONSTRUCTOR, K = h.REJECTION_EVENT, h = h.SUBCLASSING, v = c.getterFor(m), G = c.set, c = u && u.prototype, _ = u, y = c, w = p.TypeError, O = p.document, x = p.process, S = t.f, Q = S, Z = !!(O && O.createEvent && p.dispatchEvent), C = "unhandledrejection", J = "rejectionhandled", E = 1, tt = 2, k = 1, A = 2, j = function(t) { + var e; + return !(!X(t) || !a(e = t.then)) && e + }, T = function(n, o) { + n.notified || (n.notified = !0, + l(function() { + for (var t, i, e = n.reactions; t = e.get(); ) + r(t, n); + n.notified = !1, + o && !n.rejection && (i = n, + f(g, p, function() { + var t = i.facade + , e = i.value + , n = P(i); + if (n && (n = $(function() { + d ? x.emit("unhandledRejection", e, t) : L(C, t, e) + }), + i.rejection = d || P(i) ? A : k, + n.error)) + throw n.value + })) + })) + }, L = function(t, e, n) { + var i; + Z ? ((i = O.createEvent("Event")).promise = e, + i.reason = n, + i.initEvent(t, !1, !0), + p.dispatchEvent(i)) : i = { + promise: e, + reason: n + }, + !K && (e = p["on" + t]) ? e(i) : t === C && q("Unhandled promise rejection", n) + }, P = function(t) { + return t.rejection !== k && !t.parent + }, R = function(e, n, i) { + return function(t) { + e(n, t, i) + } + }, M = function(t, e, n) { + t.done || (t.done = !0, + (t = n ? n : t).value = e, + t.state = tt, + T(t, !0)) + }, I = function(n, t, e) { + if (!n.done) { + n.done = !0, + e && (n = e); + try { + if (n.facade === t) + throw w("Promise can't be resolved itself"); + var i = j(t); + i ? l(function() { + var e = { + done: !1 + }; + try { + f(i, t, R(I, e, n), R(M, e, n)) + } catch (t) { + M(e, t, n) + } + }) : (n.value = t, + n.state = E, + T(n, !1)) + } catch (t) { + M({ + done: !1 + }, t, n) + } + } + }; + if (b && (y = (_ = function(t) { + z(this, y), + F(t), + f(n, this); + var e = v(this); + try { + t(R(I, e), R(M, e)) + } catch (t) { + M(e, t) + } + } + ).prototype, + (n = function(t) { + G(this, { + type: m, + done: !1, + notified: !1, + parent: !1, + reactions: new V, + rejection: !1, + state: 0, + value: void 0 + }) + } + ).prototype = o(y, "then", function(t, e) { + var n = v(this) + , i = S(U(this, _)); + return n.parent = !0, + i.ok = !a(t) || t, + i.fail = a(e) && e, + i.domain = d ? x.domain : void 0, + 0 === n.state ? n.reactions.add(i) : l(function() { + r(i, n) + }), + i.promise + }), + e = function() { + var t = new n + , e = v(t); + this.promise = t, + this.resolve = R(I, e), + this.reject = R(M, e) + } + , + t.f = S = function(t) { + return t === _ || void 0 === t ? new e : Q(t) + } + , + !B) && a(u) && c !== Object.prototype) { + i = c.then, + h || o(c, "then", function(t, e) { + var n = this; + return new _(function(t, e) { + f(i, n, t, e) + } + ).then(t, e) + }, { + unsafe: !0 + }); + try { + delete c.constructor + } catch (t) {} + s && s(c, y) + } + H({ + global: !0, + constructor: !0, + wrap: !0, + forced: b + }, { + Promise: _ + }), + W(_, m, !1, !0), + Y(m) + } + , function(t, e, n) { + "use strict"; + var i = n(30) + , o = n(239) + , r = n(74) + , s = n(20)("species"); + t.exports = function(t, e) { + var t = i(t).constructor; + return void 0 === t || r(t = i(t)[s]) ? e : o(t) + } + } + , function(t, e, n) { + "use strict"; + var i = n(177) + , o = n(78) + , r = TypeError; + t.exports = function(t) { + if (i(t)) + return t; + throw r(o(t) + " is not a constructor") + } + } + , function(t, e, n) { + "use strict"; + n = n(14); + t.exports = n([].slice) + } + , function(t, e, n) { + "use strict"; + var i, o, r, s, a, l, c = n(13), u = n(59), h = n(111).f, d = n(178).set, p = n(180), f = n(179), g = n(242), m = n(243), b = n(83), n = c.MutationObserver || c.WebKitMutationObserver, v = c.document, _ = c.process, y = c.Promise, h = h(c, "queueMicrotask"), h = h && h.value; + h || (s = new p, + a = function() { + var t, e; + for (b && (t = _.domain) && t.exit(); e = s.get(); ) + try { + e() + } catch (t) { + throw s.head && l(), + t + } + t && t.enter() + } + , + l = f || b || m || !n || !v ? !g && y && y.resolve ? ((p = y.resolve(void 0)).constructor = y, + r = u(p.then, p), + function() { + r(a) + } + ) : b ? function() { + _.nextTick(a) + } + : (d = u(d, c), + function() { + d(a) + } + ) : (i = !0, + o = v.createTextNode(""), + new n(a).observe(o, { + characterData: !0 + }), + function() { + o.data = i = !i + } + ), + h = function(t) { + s.head || l(), + s.add(t) + } + ), + t.exports = h + } + , function(t, e, n) { + "use strict"; + n = n(49); + t.exports = /ipad|iphone|ipod/i.test(n) && "undefined" != typeof Pebble + } + , function(t, e, n) { + "use strict"; + n = n(49); + t.exports = /web0s(?!.*chrome)/i.test(n) + } + , function(t, e, n) { + "use strict"; + t.exports = function(t, e) { + try { + 1 === arguments.length ? console.error(t) : console.error(t, e) + } catch (t) {} + } + } + , function(t, e, n) { + "use strict"; + var i = n(181) + , n = n(83); + t.exports = !i && !n && "object" == typeof window && "object" == typeof document + } + , function(t, e, n) { + "use strict"; + var i = n(26) + , u = n(22) + , h = n(39) + , o = n(86) + , r = n(129) + , d = n(182); + i({ + target: "Promise", + stat: !0, + forced: n(185) + }, { + all: function(t) { + var a = this + , e = o.f(a) + , l = e.resolve + , c = e.reject + , n = r(function() { + var i = h(a.resolve) + , o = [] + , r = 0 + , s = 1; + d(t, function(t) { + var e = r++ + , n = !1; + s++, + u(i, a, t).then(function(t) { + n || (n = !0, + o[e] = t, + --s) || l(o) + }, c) + }), + --s || l(o) + }); + return n.error && c(n.value), + e.promise + } + }) + } + , function(t, e, n) { + "use strict"; + var o = n(20)("iterator") + , r = !1; + try { + var i = 0 + , s = { + next: function() { + return { + done: !!i++ + } + }, + return: function() { + r = !0 + } + }; + s[o] = function() { + return this + } + , + Array.from(s, function() { + throw 2 + }) + } catch (t) {} + t.exports = function(t, e) { + try { + if (!e && !r) + return !1 + } catch (t) { + return !1 + } + var n = !1; + try { + var i = {}; + i[o] = function() { + return { + next: function() { + return { + done: n = !0 + } + } + } + } + , + t(i) + } catch (t) {} + return n + } + } + , function(t, e, n) { + "use strict"; + var i = n(26) + , o = n(43) + , r = n(85).CONSTRUCTOR + , s = n(84) + , a = n(48) + , l = n(15) + , n = n(41) + , c = s && s.prototype; + i({ + target: "Promise", + proto: !0, + forced: r, + real: !0 + }, { + catch: function(t) { + return this.then(void 0, t) + } + }), + !o && l(s) && (i = a("Promise").prototype.catch, + c.catch !== i) && n(c, "catch", i, { + unsafe: !0 + }) + } + , function(t, e, n) { + "use strict"; + var i = n(26) + , r = n(22) + , s = n(39) + , a = n(86) + , l = n(129) + , c = n(182); + i({ + target: "Promise", + stat: !0, + forced: n(185) + }, { + race: function(t) { + var n = this + , i = a.f(n) + , o = i.reject + , e = l(function() { + var e = s(n.resolve); + c(t, function(t) { + r(e, n, t).then(i.resolve, o) + }) + }); + return e.error && o(e.value), + i.promise + } + }) + } + , function(t, e, n) { + "use strict"; + var i = n(26) + , o = n(22) + , r = n(86); + i({ + target: "Promise", + stat: !0, + forced: n(85).CONSTRUCTOR + }, { + reject: function(t) { + var e = r.f(this); + return o(e.reject, void 0, t), + e.promise + } + }) + } + , function(t, e, n) { + "use strict"; + var i = n(26) + , o = n(48) + , r = n(43) + , s = n(84) + , a = n(85).CONSTRUCTOR + , l = n(252) + , c = o("Promise") + , u = r && !a; + i({ + target: "Promise", + stat: !0, + forced: r || a + }, { + resolve: function(t) { + return l(u && this === c ? s : this, t) + } + }) + } + , function(t, e, n) { + "use strict"; + var i = n(30) + , o = n(35) + , r = n(86); + t.exports = function(t, e) { + return i(t), + o(e) && e.constructor === t ? e : ((0, + (t = r.f(t)).resolve)(e), + t.promise) + } + } + , function(t, e, n) { + "use strict"; + n(254) + } + , function(f, g, t) { + "use strict"; + t(255); + function u(t) { + var e, n, i, o; + if ("number" == typeof t) { + for (e = [], + n = 0; n < 4; n++) + rt(e, t % 256), + t = Z(t / 256); + return A(e, ".") + } + if ("object" != typeof t) + return t; + for (e = "", + i = function(t) { + for (var e = null, n = 1, i = null, o = 0, r = 0; r < 8; r++) + 0 !== t[r] ? (n < o && (e = i, + n = o), + i = null, + o = 0) : (null === i && (i = r), + ++o); + return n < o && (e = i, + n = o), + e + }(t), + n = 0; n < 8; n++) + o && 0 === t[n] || (o = o && !1, + i === n ? (e += n ? ":" : "::", + o = !0) : (e += tt(t[n], 16), + n < 7 && (e += ":"))); + return "[" + e + "]" + } + function v(t, e) { + var n = z(t, 0); + return 32 < n && n < 127 && !w(e, t) ? t : encodeURIComponent(t) + } + function _(t, e) { + return 2 === t.length && k(lt, E(t, 0)) && (":" === (t = E(t, 1)) || !e && "|" === t) + } + function W(t) { + return 1 < t.length && _(h(t, 0, 2)) && (2 === t.length || "/" === (t = E(t, 2)) || "\\" === t || "?" === t || "#" === t) + } + function r(t, e, n) { + var i, o, t = S(t); + if (e) { + if (o = this.parse(t)) + throw Q(o); + this.searchParams = null + } else { + if (void 0 !== n && (i = new r(n,!0)), + o = this.parse(t, null, i)) + throw Q(o); + (e = G(new K)).bindURL(this), + this.searchParams = e + } + } + function e(t, e) { + return { + get: function() { + return c(this)[t]() + }, + set: e && function(t) { + return c(this)[e](t) + } + , + configurable: !0, + enumerable: !0 + } + } + var y, m = t(26), i = t(23), b = t(186), n = t(13), Y = t(59), o = t(14), s = t(41), a = t(79), F = t(127), w = t(29), X = t(256), O = t(257), x = t(174), z = t(126).codeAt, U = t(259), S = t(38), q = t(82), $ = t(128), l = t(187), t = t(46), V = t.set, c = t.getterFor("URL"), K = l.URLSearchParams, G = l.getState, t = n.URL, Q = n.TypeError, C = n.parseInt, Z = Math.floor, J = Math.pow, E = o("".charAt), k = o(/./.exec), A = o([].join), tt = o(1..toString), et = o([].pop), j = o([].push), nt = o("".replace), it = o([].shift), ot = o("".split), h = o("".slice), T = o("".toLowerCase), rt = o([].unshift), st = "Invalid scheme", L = "Invalid host", at = "Invalid port", lt = /[a-z]/i, ct = /[\d+-.a-z]/i, ut = /\d/, ht = /^0x/i, dt = /^[0-7]+$/, pt = /^\d+$/, ft = /^[\da-f]+$/i, gt = /[\0\t\n\r #%/:<>?@[\\\]^|]/, mt = /[\0\t\n\r #/:<>?@[\\\]^|]/, bt = /^[\u0000-\u0020]+/, vt = /(^|[^\u0000-\u0020])[\u0000-\u0020]+$/, _t = /[\t\n\r]/g, P = {}, yt = X({}, P, { + " ": 1, + '"': 1, + "<": 1, + ">": 1, + "`": 1 + }), wt = X({}, yt, { + "#": 1, + "?": 1, + "{": 1, + "}": 1 + }), Ot = X({}, wt, { + "/": 1, + ":": 1, + ";": 1, + "=": 1, + "@": 1, + "[": 1, + "\\": 1, + "]": 1, + "^": 1, + "|": 1 + }), R = { + ftp: 21, + file: null, + http: 80, + https: 443, + ws: 80, + wss: 443 + }, xt = {}, St = {}, Ct = {}, Et = {}, kt = {}, At = {}, jt = {}, Tt = {}, M = {}, I = {}, Lt = {}, Pt = {}, Rt = {}, Mt = {}, It = {}, Dt = {}, D = {}, N = {}, Nt = {}, H = {}, B = {}, d = (r.prototype = { + type: "URL", + parse: function(t, e, n) { + var i, o, r, s, a = this, l = e || xt, c = 0, u = "", h = !1, d = !1, p = !1; + for (t = S(t), + e || (a.scheme = "", + a.username = "", + a.password = "", + a.host = null, + a.port = null, + a.path = [], + a.query = null, + a.fragment = null, + a.cannotBeABaseURL = !1, + t = nt(t, bt, ""), + t = nt(t, vt, "$1")), + t = nt(t, _t, ""), + i = O(t); c <= i.length; ) { + switch (o = i[c], + l) { + case xt: + if (!o || !k(lt, o)) { + if (e) + return st; + l = Ct; + continue + } + u += T(o), + l = St; + break; + case St: + if (o && (k(ct, o) || "+" === o || "-" === o || "." === o)) + u += T(o); + else { + if (":" !== o) { + if (e) + return st; + u = "", + l = Ct, + c = 0; + continue + } + if (e && (a.isSpecial() !== w(R, u) || "file" === u && (a.includesCredentials() || null !== a.port) || "file" === a.scheme && !a.host)) + return; + if (a.scheme = u, + e) + return void (a.isSpecial() && R[a.scheme] === a.port && (a.port = null)); + u = "", + "file" === a.scheme ? l = Mt : a.isSpecial() && n && n.scheme === a.scheme ? l = Et : a.isSpecial() ? l = Tt : "/" === i[c + 1] ? (l = kt, + c++) : (a.cannotBeABaseURL = !0, + j(a.path, ""), + l = Nt) + } + break; + case Ct: + if (!n || n.cannotBeABaseURL && "#" !== o) + return st; + if (n.cannotBeABaseURL && "#" === o) { + a.scheme = n.scheme, + a.path = x(n.path), + a.query = n.query, + a.fragment = "", + a.cannotBeABaseURL = !0, + l = B; + break + } + l = "file" === n.scheme ? Mt : At; + continue; + case Et: + if ("/" !== o || "/" !== i[c + 1]) { + l = At; + continue + } + l = M, + c++; + break; + case kt: + if ("/" === o) { + l = I; + break + } + l = N; + continue; + case At: + if (a.scheme = n.scheme, + o === y) + a.username = n.username, + a.password = n.password, + a.host = n.host, + a.port = n.port, + a.path = x(n.path), + a.query = n.query; + else if ("/" === o || "\\" === o && a.isSpecial()) + l = jt; + else if ("?" === o) + a.username = n.username, + a.password = n.password, + a.host = n.host, + a.port = n.port, + a.path = x(n.path), + a.query = "", + l = H; + else { + if ("#" !== o) { + a.username = n.username, + a.password = n.password, + a.host = n.host, + a.port = n.port, + a.path = x(n.path), + a.path.length--, + l = N; + continue + } + a.username = n.username, + a.password = n.password, + a.host = n.host, + a.port = n.port, + a.path = x(n.path), + a.query = n.query, + a.fragment = "", + l = B + } + break; + case jt: + if (!a.isSpecial() || "/" !== o && "\\" !== o) { + if ("/" !== o) { + a.username = n.username, + a.password = n.password, + a.host = n.host, + a.port = n.port, + l = N; + continue + } + l = I + } else + l = M; + break; + case Tt: + if (l = M, + "/" !== o || "/" !== E(u, c + 1)) + continue; + c++; + break; + case M: + if ("/" === o || "\\" === o) + break; + l = I; + continue; + case I: + if ("@" === o) { + h && (u = "%40" + u); + for (var h = !0, f = O(u), g = 0; g < f.length; g++) { + var m = f[g]; + ":" !== m || p ? (m = v(m, Ot), + p ? a.password += m : a.username += m) : p = !0 + } + u = "" + } else if (o === y || "/" === o || "?" === o || "#" === o || "\\" === o && a.isSpecial()) { + if (h && "" === u) + return "Invalid authority"; + c -= O(u).length + 1, + u = "", + l = Lt + } else + u += o; + break; + case Lt: + case Pt: + if (e && "file" === a.scheme) { + l = Dt; + continue + } + if (":" !== o || d) { + if (o === y || "/" === o || "?" === o || "#" === o || "\\" === o && a.isSpecial()) { + if (a.isSpecial() && "" === u) + return L; + if (e && "" === u && (a.includesCredentials() || null !== a.port)) + return; + if (r = a.parseHost(u)) + return r; + if (u = "", + l = D, + e) + return; + continue + } + "[" === o ? d = !0 : "]" === o && (d = !1), + u += o + } else { + if ("" === u) + return L; + if (r = a.parseHost(u)) + return r; + if (u = "", + l = Rt, + e === Pt) + return + } + break; + case Rt: + if (!k(ut, o)) { + if (o === y || "/" === o || "?" === o || "#" === o || "\\" === o && a.isSpecial() || e) { + if ("" !== u) { + var b = C(u, 10); + if (65535 < b) + return at; + a.port = a.isSpecial() && b === R[a.scheme] ? null : b, + u = "" + } + if (e) + return; + l = D; + continue + } + return at + } + u += o; + break; + case Mt: + if (a.scheme = "file", + "/" === o || "\\" === o) + l = It; + else { + if (!n || "file" !== n.scheme) { + l = N; + continue + } + switch (o) { + case y: + a.host = n.host, + a.path = x(n.path), + a.query = n.query; + break; + case "?": + a.host = n.host, + a.path = x(n.path), + a.query = "", + l = H; + break; + case "#": + a.host = n.host, + a.path = x(n.path), + a.query = n.query, + a.fragment = "", + l = B; + break; + default: + W(A(x(i, c), "")) || (a.host = n.host, + a.path = x(n.path), + a.shortenPath()), + l = N; + continue + } + } + break; + case It: + if ("/" === o || "\\" === o) { + l = Dt; + break + } + n && "file" === n.scheme && !W(A(x(i, c), "")) && (_(n.path[0], !0) ? j(a.path, n.path[0]) : a.host = n.host), + l = N; + continue; + case Dt: + if (o === y || "/" === o || "\\" === o || "?" === o || "#" === o) { + if (!e && _(u)) + l = N; + else { + if ("" === u) { + if (a.host = "", + e) + return + } else { + if (r = a.parseHost(u)) + return r; + if ("localhost" === a.host && (a.host = ""), + e) + return; + u = "" + } + l = D + } + continue + } + u += o; + break; + case D: + if (a.isSpecial()) { + if (l = N, + "/" !== o && "\\" !== o) + continue + } else if (e || "?" !== o) + if (e || "#" !== o) { + if (o !== y && (l = N, + "/" !== o)) + continue + } else + a.fragment = "", + l = B; + else + a.query = "", + l = H; + break; + case N: + if (o === y || "/" === o || "\\" === o && a.isSpecial() || !e && ("?" === o || "#" === o)) { + if (".." === (b = T(b = u)) || "%2e." === b || ".%2e" === b || "%2e%2e" === b ? (a.shortenPath(), + "/" === o || "\\" === o && a.isSpecial() || j(a.path, "")) : "." === (s = u) || "%2e" === T(s) ? "/" === o || "\\" === o && a.isSpecial() || j(a.path, "") : ("file" === a.scheme && !a.path.length && _(u) && (a.host && (a.host = ""), + u = E(u, 0) + ":"), + j(a.path, u)), + u = "", + "file" === a.scheme && (o === y || "?" === o || "#" === o)) + for (; 1 < a.path.length && "" === a.path[0]; ) + it(a.path); + "?" === o ? (a.query = "", + l = H) : "#" === o && (a.fragment = "", + l = B) + } else + u += v(o, wt); + break; + case Nt: + "?" === o ? (a.query = "", + l = H) : "#" === o ? (a.fragment = "", + l = B) : o !== y && (a.path[0] += v(o, P)); + break; + case H: + e || "#" !== o ? o !== y && ("'" === o && a.isSpecial() ? a.query += "%27" : a.query += "#" === o ? "%23" : v(o, P)) : (a.fragment = "", + l = B); + break; + case B: + o !== y && (a.fragment += v(o, yt)) + } + c++ + } + }, + parseHost: function(t) { + var e, n, i; + if ("[" === E(t, 0)) + return "]" === E(t, t.length - 1) && (e = function(t) { + function e() { + return E(t, d) + } + var n, i, o, r, s, a, l, c = [0, 0, 0, 0, 0, 0, 0, 0], u = 0, h = null, d = 0; + if (":" === e()) { + if (":" !== E(t, 1)) + return; + d += 2, + h = ++u + } + for (; e(); ) { + if (8 === u) + return; + if (":" === e()) { + if (null !== h) + return; + d++, + h = ++u + } else { + for (n = i = 0; i < 4 && k(ft, e()); ) + n = 16 * n + C(e(), 16), + d++, + i++; + if ("." === e()) { + if (0 === i) + return; + if (d -= i, + 6 < u) + return; + for (o = 0; e(); ) { + if (r = null, + 0 < o) { + if (!("." === e() && o < 4)) + return; + d++ + } + if (!k(ut, e())) + return; + for (; k(ut, e()); ) { + if (s = C(e(), 10), + null === r) + r = s; + else { + if (0 === r) + return; + r = 10 * r + s + } + if (255 < r) + return; + d++ + } + c[u] = 256 * c[u] + r, + 2 !== ++o && 4 !== o || u++ + } + if (4 !== o) + return; + break + } + if (":" === e()) { + if (d++, + !e()) + return + } else if (e()) + return; + c[u++] = n + } + } + if (null !== h) + for (a = u - h, + u = 7; 0 !== u && 0 < a; ) + l = c[u], + c[u--] = c[h + a - 1], + c[h + --a] = l; + else if (8 !== u) + return; + return c + }(h(t, 1, -1))) ? void (this.host = e) : L; + if (this.isSpecial()) + return t = U(t), + k(gt, t) || null === (e = function(t) { + var e, n, i, o, r, s, a, l = ot(t, "."); + if (l.length && "" === l[l.length - 1] && l.length--, + 4 < (e = l.length)) + return t; + for (n = [], + i = 0; i < e; i++) { + if ("" === (o = l[i])) + return t; + if (r = 10, + 1 < o.length && "0" === E(o, 0) && (r = k(ht, o) ? 16 : 8, + o = h(o, 8 === r ? 1 : 2)), + "" === o) + s = 0; + else { + if (!k(10 === r ? pt : 8 === r ? dt : ft, o)) + return t; + s = C(o, r) + } + j(n, s) + } + for (i = 0; i < e; i++) + if (s = n[i], + i === e - 1) { + if (s >= J(256, 5 - e)) + return null + } else if (255 < s) + return null; + for (a = et(n), + i = 0; i < n.length; i++) + a += n[i] * J(256, 3 - i); + return a + }(t)) ? L : void (this.host = e); + if (k(mt, t)) + return L; + for (e = "", + n = O(t), + i = 0; i < n.length; i++) + e += v(n[i], P); + this.host = e + }, + cannotHaveUsernamePasswordPort: function() { + return !this.host || this.cannotBeABaseURL || "file" === this.scheme + }, + includesCredentials: function() { + return "" !== this.username || "" !== this.password + }, + isSpecial: function() { + return w(R, this.scheme) + }, + shortenPath: function() { + var t = this.path + , e = t.length; + !e || "file" === this.scheme && 1 === e && _(t[0], !0) || t.length-- + }, + serialize: function() { + var t = this + , e = t.scheme + , n = t.username + , i = t.password + , o = t.host + , r = t.port + , s = t.path + , a = t.query + , l = t.fragment + , c = e + ":"; + return null !== o ? (c += "//", + t.includesCredentials() && (c += n + (i ? ":" + i : "") + "@"), + c += u(o), + null !== r && (c += ":" + r)) : "file" === e && (c += "//"), + c += t.cannotBeABaseURL ? s[0] : s.length ? "/" + A(s, "/") : "", + null !== a && (c += "?" + a), + null !== l && (c += "#" + l), + c + }, + setHref: function(t) { + t = this.parse(t); + if (t) + throw Q(t); + this.searchParams.update() + }, + getOrigin: function() { + var t = this.scheme + , e = this.port; + if ("blob" === t) + try { + return new d(t.path[0]).origin + } catch (t) { + return "null" + } + return "file" !== t && this.isSpecial() ? t + "://" + u(this.host) + (null !== e ? ":" + e : "") : "null" + }, + getProtocol: function() { + return this.scheme + ":" + }, + setProtocol: function(t) { + this.parse(S(t) + ":", xt) + }, + getUsername: function() { + return this.username + }, + setUsername: function(t) { + var e = O(S(t)); + if (!this.cannotHaveUsernamePasswordPort()) { + this.username = ""; + for (var n = 0; n < e.length; n++) + this.username += v(e[n], Ot) + } + }, + getPassword: function() { + return this.password + }, + setPassword: function(t) { + var e = O(S(t)); + if (!this.cannotHaveUsernamePasswordPort()) { + this.password = ""; + for (var n = 0; n < e.length; n++) + this.password += v(e[n], Ot) + } + }, + getHost: function() { + var t = this.host + , e = this.port; + return null === t ? "" : null === e ? u(t) : u(t) + ":" + e + }, + setHost: function(t) { + this.cannotBeABaseURL || this.parse(t, Lt) + }, + getHostname: function() { + var t = this.host; + return null === t ? "" : u(t) + }, + setHostname: function(t) { + this.cannotBeABaseURL || this.parse(t, Pt) + }, + getPort: function() { + var t = this.port; + return null === t ? "" : S(t) + }, + setPort: function(t) { + this.cannotHaveUsernamePasswordPort() || ("" === (t = S(t)) ? this.port = null : this.parse(t, Rt)) + }, + getPathname: function() { + var t = this.path; + return this.cannotBeABaseURL ? t[0] : t.length ? "/" + A(t, "/") : "" + }, + setPathname: function(t) { + this.cannotBeABaseURL || (this.path = [], + this.parse(t, D)) + }, + getSearch: function() { + var t = this.query; + return t ? "?" + t : "" + }, + setSearch: function(t) { + "" === (t = S(t)) ? this.query = null : ("?" === E(t, 0) && (t = h(t, 1)), + this.query = "", + this.parse(t, H)), + this.searchParams.update() + }, + getSearchParams: function() { + return this.searchParams.facade + }, + getHash: function() { + var t = this.fragment; + return t ? "#" + t : "" + }, + setHash: function(t) { + "" === (t = S(t)) ? this.fragment = null : ("#" === E(t, 0) && (t = h(t, 1)), + this.fragment = "", + this.parse(t, B)) + }, + update: function() { + this.query = this.searchParams.serialize() || null + } + }, + function(t) { + var e = F(this, p) + , n = 1 < $(arguments.length, 1) ? arguments[1] : void 0 + , t = V(e, new r(t,!1,n)); + i || (e.href = t.serialize(), + e.origin = t.getOrigin(), + e.protocol = t.getProtocol(), + e.username = t.getUsername(), + e.password = t.getPassword(), + e.host = t.getHost(), + e.hostname = t.getHostname(), + e.port = t.getPort(), + e.pathname = t.getPathname(), + e.search = t.getSearch(), + e.searchParams = t.getSearchParams(), + e.hash = t.getHash()) + } + ), p = d.prototype; + i && (a(p, "href", e("serialize", "setHref")), + a(p, "origin", e("getOrigin")), + a(p, "protocol", e("getProtocol", "setProtocol")), + a(p, "username", e("getUsername", "setUsername")), + a(p, "password", e("getPassword", "setPassword")), + a(p, "host", e("getHost", "setHost")), + a(p, "hostname", e("getHostname", "setHostname")), + a(p, "port", e("getPort", "setPort")), + a(p, "pathname", e("getPathname", "setPathname")), + a(p, "search", e("getSearch", "setSearch")), + a(p, "searchParams", e("getSearchParams")), + a(p, "hash", e("getHash", "setHash"))), + s(p, "toJSON", function() { + return c(this).serialize() + }, { + enumerable: !0 + }), + s(p, "toString", function() { + return c(this).serialize() + }, { + enumerable: !0 + }), + t && (l = t.createObjectURL, + n = t.revokeObjectURL, + l && s(d, "createObjectURL", Y(l, t)), + n) && s(d, "revokeObjectURL", Y(n, t)), + q(d, "URL"), + m({ + global: !0, + constructor: !0, + forced: !b, + sham: !i + }, { + URL: d + }) + } + , function(t, e, n) { + "use strict"; + var i = n(126).charAt + , o = n(38) + , r = n(46) + , s = n(161) + , a = n(165) + , l = "String Iterator" + , c = r.set + , u = r.getterFor(l); + s(String, "String", function(t) { + c(this, { + type: l, + string: o(t), + index: 0 + }) + }, function() { + var t = u(this) + , e = t.string + , n = t.index; + return n >= e.length ? a(void 0, !0) : (e = i(e, n), + t.index += e.length, + a(e, !1)) + }) + } + , function(t, e, n) { + "use strict"; + var d = n(23) + , i = n(14) + , p = n(22) + , o = n(16) + , f = n(159) + , g = n(157) + , m = n(142) + , b = n(50) + , v = n(112) + , r = Object.assign + , s = Object.defineProperty + , _ = i([].concat); + t.exports = !r || o(function() { + var t, e, n, i; + return !(!d || 1 === r({ + b: 1 + }, r(s({}, "a", { + enumerable: !0, + get: function() { + s(this, "b", { + value: 3, + enumerable: !1 + }) + } + }), { + b: 2 + })).b) || (e = {}, + i = "abcdefghijklmnopqrst", + (t = {})[n = Symbol("assign detection")] = 7, + i.split("").forEach(function(t) { + e[t] = t + }), + 7 !== r({}, t)[n]) || f(r({}, e)).join("") !== i + }) ? function(t, e) { + for (var n = b(t), i = arguments.length, o = 1, r = g.f, s = m.f; o < i; ) + for (var a, l = v(arguments[o++]), c = r ? _(f(l), r(l)) : f(l), u = c.length, h = 0; h < u; ) + a = c[h++], + d && !p(s, l, a) || (n[a] = l[a]); + return n + } + : r + } + , function(t, e, n) { + "use strict"; + var d = n(59) + , p = n(22) + , f = n(50) + , g = n(258) + , m = n(183) + , b = n(177) + , v = n(58) + , _ = n(175) + , y = n(130) + , w = n(96) + , O = Array; + t.exports = function(t) { + var e, n, i, o, r, s, a = f(t), t = b(this), l = arguments.length, c = 1 < l ? arguments[1] : void 0, u = void 0 !== c, l = (u && (c = d(c, 2 < l ? arguments[2] : void 0)), + w(a)), h = 0; + if (!l || this === O && m(l)) + for (e = v(a), + n = t ? new this(e) : O(e); h < e; h++) + s = u ? c(a[h], h) : a[h], + _(n, h, s); + else + for (r = (o = y(a, l)).next, + n = t ? new this : []; !(i = p(r, o)).done; h++) + s = u ? g(o, c, [i.value, h], !0) : i.value, + _(n, h, s); + return n.length = h, + n + } + } + , function(t, e, n) { + "use strict"; + var o = n(30) + , r = n(184); + t.exports = function(e, t, n, i) { + try { + return i ? t(o(n)[0], n[1]) : t(n) + } catch (t) { + r(e, "throw", t) + } + } + } + , function(t, e, n) { + "use strict"; + function b(t) { + return t + 22 + 75 * (t < 26) + } + function r(t) { + var e, n = [], i = (t = function(t) { + for (var e = [], n = 0, i = t.length; n < i; ) { + var o, r = A(t, n++); + 55296 <= r && r <= 56319 && n < i ? 56320 == (64512 & (o = A(t, n++))) ? T(e, ((1023 & r) << 10) + (1023 & o) + 65536) : (T(e, r), + n--) : T(e, r) + } + return e + }(t)).length, o = 128, r = 0, s = 72; + for (u = 0; u < t.length; u++) + (e = t[u]) < 128 && T(n, k(e)); + var a = n.length + , l = a; + for (a && T(n, "-"); l < i; ) { + for (var c = v, u = 0; u < t.length; u++) + o <= (e = t[u]) && e < c && (c = e); + var h = l + 1; + if (c - o > E((v - r) / h)) + throw C(x); + for (r += (c - o) * h, + o = c, + u = 0; u < t.length; u++) { + if ((e = t[u]) < o && ++r > v) + throw C(x); + if (e === o) { + for (var d = r, p = _; ; ) { + var f = p <= s ? 1 : s + y <= p ? y : p - s; + if (d < f) + break; + var g = d - f + , m = _ - f; + T(n, k(b(f + g % m))), + d = E(g / m), + p += _ + } + T(n, k(b(d))), + s = function(t, e, n) { + var i = 0; + for (t = n ? E(t / O) : t >> 1, + t += E(t / e); S * y >> 1 < t; ) + t = E(t / S), + i += _; + return E(i + (S + 1) * t / (t + w)) + }(r, h, l === a), + r = 0, + l++ + } + } + r++, + o++ + } + return j(n, "") + } + var n = n(14) + , v = 2147483647 + , _ = 36 + , y = 26 + , w = 38 + , O = 700 + , s = /[^\0-\u007E]/ + , a = /[.\u3002\uFF0E\uFF61]/g + , x = "Overflow: input needs wider integers to process" + , S = _ - 1 + , C = RangeError + , l = n(a.exec) + , E = Math.floor + , k = String.fromCharCode + , A = n("".charCodeAt) + , j = n([].join) + , T = n([].push) + , c = n("".replace) + , u = n("".split) + , h = n("".toLowerCase); + t.exports = function(t) { + for (var e, n = [], i = u(c(h(t), a, "."), "."), o = 0; o < i.length; o++) + e = i[o], + T(n, l(s, e) ? "xn--" + r(e) : e); + return j(n, ".") + } + } + , function(t, e, n) { + "use strict"; + var o = n(41); + t.exports = function(t, e, n) { + for (var i in e) + o(t, i, e[i], n); + return t + } + } + , function(t, e, n) { + "use strict"; + n(187) + } + , function(t, e, n) { + "use strict"; + function i(c) { + return function(t, e, n, i) { + u(e); + var o = h(t) + , r = d(o) + , s = p(o) + , a = c ? s - 1 : 0 + , l = c ? -1 : 1; + if (n < 2) + for (; ; ) { + if (a in r) { + i = r[a], + a += l; + break + } + if (a += l, + c ? a < 0 : s <= a) + throw f("Reduce of empty array with no initial value") + } + for (; c ? 0 <= a : a < s; a += l) + a in r && (i = e(i, r[a], a, o)); + return i + } + } + var u = n(39) + , h = n(50) + , d = n(112) + , p = n(58) + , f = TypeError; + t.exports = { + left: i(!1), + right: i(!0) + } + } + ], + i = {}, + o.m = n, + o.c = i, + o.d = function(t, e, n) { + o.o(t, e) || Object.defineProperty(t, e, { + enumerable: !0, + get: n + }) + } + , + o.r = function(t) { + "undefined" != typeof Symbol && Symbol.toStringTag && Object.defineProperty(t, Symbol.toStringTag, { + value: "Module" + }), + Object.defineProperty(t, "__esModule", { + value: !0 + }) + } + , + o.t = function(e, t) { + if (1 & t && (e = o(e)), + 8 & t) + return e; + if (4 & t && "object" == typeof e && e && e.__esModule) + return e; + var n = Object.create(null); + if (o.r(n), + Object.defineProperty(n, "default", { + enumerable: !0, + value: e + }), + 2 & t && "string" != typeof e) + for (var i in e) + o.d(n, i, function(t) { + return e[t] + } + .bind(null, i)); + return n + } + , + o.n = function(t) { + var e = t && t.__esModule ? function() { + return t.default + } + : function() { + return t + } + ; + return o.d(e, "a", e), + e + } + , + o.o = function(t, e) { + return Object.prototype.hasOwnProperty.call(t, e) + } + , + o.p = "", + o(o.s = 198).compiled; + function o(t) { + var e; + return (i[t] || (e = i[t] = { + i: t, + l: !1, + exports: {} + }, + n[t].call(e.exports, e, e.exports, o), + e.l = !0, + e)).exports + } + var n, i +}); diff --git a/tsconfig.json b/tsconfig.json index fccaf81..73d6e8f 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -11,7 +11,7 @@ // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ /* Language and Environment */ - "target": "es2016" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */, + "target": "ES5" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */, // "lib": [ // "es2016", // "dom", @@ -29,7 +29,7 @@ // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */ /* Modules */ - "module": "CommonJS" /* Specify what module code is generated. */, + "module": "Node16" /* Specify what module code is generated. */, // "rootDir": "./", /* Specify the root folder within your source files. */ "moduleResolution": "Node16" /* Specify how TypeScript looks up a file from a given module specifier. */, // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ @@ -65,7 +65,7 @@ // "sourceMap": true, /* Create source map files for emitted JavaScript files. */ // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */ - "outDir": "./js/" /* Specify an output folder for all emitted files. */, + "outDir": "./.js/" /* Specify an output folder for all emitted files. */, // "removeComments": true, /* Disable emitting comments. */ // "noEmit": true, /* Disable emitting files from a compilation. */ // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ @@ -119,5 +119,5 @@ "skipLibCheck": true /* Skip type checking all .d.ts files. */ }, - "exclude": ["./plugins/**/*.broken.ts", "./js/**/*"] + "exclude": ["./plugins/**/*.broken.ts", "./.js/**/*"] } diff --git a/types/plugin.ts b/types/plugin.ts index e3424ed..975a8bd 100644 --- a/types/plugin.ts +++ b/types/plugin.ts @@ -1,46 +1,32 @@ import { Filter } from "@libs/filterInputs"; import { languages } from "@libs/languages"; -import { NodeFetchParams } from "@libs/nodeFetch"; - -export namespace Chapter { - export interface Item { +export namespace Plugin { + export interface ChapterItem { name: string; url: string; releaseTime?: string | null; } - export interface instance { - sourceId: number; - novelUrl: string; - chapterUrl: string; - name?: string; - chapterText?: string; - } -} - -export namespace Novel { - export interface Item { + export interface NovelItem { name: string; url: string; cover?: string; } - export interface instance { + export interface SourceNovel { url: string; name?: string; cover?: string; genres?: string; summary?: string; author?: string; + artist?: string; status?: string; - chapters?: Chapter.Item[]; + chapters?: ChapterItem[]; } -} - -export namespace Plugin { - export interface Options { + export interface PopularNovelsOptions { showLatestNovels?: boolean; filters?: Record; } - export interface Info { + export interface PluginItem { id: string; name: string; lang: (typeof languages)[keyof typeof languages]; @@ -48,43 +34,51 @@ export namespace Plugin { requirePath: string; icon: string; } - export interface instance { - id: string; - name: string; - version: string; + + export interface PluginBase { + id: string, + name: string, + /** + * Relative path without icon. E.g: + * ```js + * "src/vi/hakolightnovel/icon.png" + * ``` + */ icon: string; site: string; - popularNovels: popularNovels; - parseNovelAndChapters: parseNovelAndChapters; - parseChapter: parseChapter; - searchNovels: searchNovels; - fetchImage: fetchImage; filters?: Filter[]; + version: string; + userAgent: string; + cookieString: string; + popularNovels(pageNo: number, options: PopularNovelsOptions): Promise; + parseNovelAndChapters(novelUrl: string): Promise; + parseChapter(chapterUrl: string): Promise; + searchNovels(searchTerm: string, pageNo?: number): Promise; + /** + * + * @param url Image url + * @returns {string} Base64 of image + * @example + * ```ts + * const headers = { + * Referer: "https://ln.hako.vn", + * }; + * return await fetchFile(url, { headers: headers }); + * ``` + */ + fetchImage(url: string): Promise; } - export type popularNovels = ( - page: number, - options: Plugin.Options - ) => Promise; - export type PopularNovelsResponse = Novel.Item[]; - export type parseNovelAndChapters = ( - novelUrl: string - ) => Promise; - export type parseChapter = (chapterUrl: string) => Promise; - export type searchNovels = (searchTerm: string) => Promise; - export type fetchImage = ( - ...params: NodeFetchParams - ) => Promise; } -export const isPlugin = (p: any): p is Plugin.instance => { - const pl = p as Plugin.instance; +export const isPlugin = (p: any): p is Plugin.PluginBase => { + const pl = p as Plugin.PluginBase; const errorOut = (key: string) => { console.error(`Plugin ${pl.name} doesn't have ${key}!`); return false; }; - const required_funcs: (keyof Plugin.instance)[] = [ + const required_funcs: (keyof Plugin.PluginBase)[] = [ "popularNovels", "parseNovelAndChapters", "parseChapter", @@ -95,12 +89,14 @@ export const isPlugin = (p: any): p is Plugin.instance => { const key = required_funcs[i]; if (!pl[key] || typeof pl[key] !== "function") return errorOut(key); } - const requireds_fields: (keyof Plugin.instance)[] = [ + const requireds_fields: (keyof Plugin.PluginBase)[] = [ "id", "name", "version", "icon", "site", + "userAgent", + "cookieString", ]; for (let i = 0; i < requireds_fields.length; i++) { const key = requireds_fields[i]; diff --git a/types/types.ts b/types/types.ts index 4692a45..afaa690 100644 --- a/types/types.ts +++ b/types/types.ts @@ -1,5 +1,5 @@ import { Plugin } from "@typings/plugin"; export type PluginList = { - [key: string]: Plugin.Info[]; + [key: string]: Plugin.PluginItem[]; };