diff --git a/.dist/nyagami/plugins.json b/.dist/nyagami/plugins.json
new file mode 100644
index 0000000..b4d2dcd
--- /dev/null
+++ b/.dist/nyagami/plugins.json
@@ -0,0 +1,708 @@
+{
+ "العربية": [
+ {
+ "id": "ar-mtl",
+ "name": "ArMTL[madara]",
+ "site": "https://ar-mtl.club/",
+ "lang": "العربية",
+ "version": "1.0.0",
+ "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/arabic/ArMTL[madara].js",
+ "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/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/fix-plugins/.js/plugins/arabic/ArNovel[madara].js",
+ "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/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/fix-plugins/.js/plugins/arabic/HizoManga[madara].js",
+ "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/madara/icons/hizomanga.png"
+ },
+ {
+ "id": "kol-novel",
+ "name": "Kol Novel[wpmangastream]",
+ "site": "https://kolnovel.com/",
+ "lang": "العربية",
+ "version": "1.0.0",
+ "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/arabic/KolNovel[wpmangastream].js",
+ "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/wpmangastream/icons/kol-novel.png"
+ },
+ {
+ "id": "kolnovel",
+ "name": "KolNovel",
+ "site": "https://kolnovel.lol/",
+ "lang": "العربية",
+ "version": "1.0.0",
+ "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/arabic/kolnovel.js",
+ "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/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/fix-plugins/.js/plugins/arabic/Novel4Up[madara].js",
+ "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/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/fix-plugins/.js/plugins/arabic/Riwyat[madara].js",
+ "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/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/fix-plugins/.js/plugins/arabic/TeamXNovel[madara].js",
+ "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/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/nyagami/plugins/fix-plugins/.js/plugins/chinese/linovelib.js",
+ "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/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/nyagami/plugins/fix-plugins/.js/plugins/english/FirstKissNovel[madara].js",
+ "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/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/fix-plugins/.js/plugins/english/bestlightnovel.js",
+ "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/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/fix-plugins/.js/plugins/english/BoxNovel[madara].js",
+ "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/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/fix-plugins/.js/plugins/english/ClickNovel[madara].js",
+ "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/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/fix-plugins/.js/plugins/english/CrateNovel[madara].js",
+ "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/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/fix-plugins/.js/plugins/english/DaoNovel[madara].js",
+ "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/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/fix-plugins/.js/plugins/english/FansTranslations[madara].js",
+ "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/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/fix-plugins/.js/plugins/english/FreeNovelMe[madara].js",
+ "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/madara/icons/freenovelme.png"
+ },
+ {
+ "id": "ftest",
+ "name": "Filter Test",
+ "site": "https://noblemtl.com/",
+ "lang": "English",
+ "version": "1.0.0",
+ "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/english/filterTests.js",
+ "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/src/en/noblemtl/icon.png"
+ },
+ {
+ "id": "FWN.com",
+ "name": "Web NOVEL",
+ "site": "https://freewebnovel.com",
+ "lang": "English",
+ "version": "1.0.0",
+ "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/english/freewebnovel.js",
+ "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/src/en/freewebnovel/icon.png"
+ },
+ {
+ "id": "guavaread",
+ "name": "Guavaread[madara]",
+ "site": "https://guavaread.com/",
+ "lang": "English",
+ "version": "1.0.0",
+ "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/english/Guavaread[madara].js",
+ "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/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/fix-plugins/.js/plugins/english/LightNovelHeaven[madara].js",
+ "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/madara/icons/lightnovelheaven.png"
+ },
+ {
+ "id": "Ltnovel.com",
+ "name": "Ltnovel[readwn]",
+ "site": "https://www.ltnovel.com",
+ "lang": "English",
+ "version": "1.0.0",
+ "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/english/Ltnovel[readwn].js",
+ "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/readwn/icons/ltnovel.png"
+ },
+ {
+ "id": "lunarletters",
+ "name": "LunarLetters[madara]",
+ "site": "https://www.lunarletters.com/",
+ "lang": "English",
+ "version": "1.0.0",
+ "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/english/LunarLetters[madara].js",
+ "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/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/fix-plugins/.js/plugins/english/MostNovel[madara].js",
+ "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/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/fix-plugins/.js/plugins/english/MTLNovel[madara].js",
+ "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/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/fix-plugins/.js/plugins/english/MTLNovelClub[madara].js",
+ "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/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/fix-plugins/.js/plugins/english/MysticalSeries[madara].js",
+ "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/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/fix-plugins/.js/plugins/english/NeoSekaiTranslations[madara].js",
+ "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/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/fix-plugins/.js/plugins/english/nobleMTL.js",
+ "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/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/fix-plugins/.js/plugins/english/NocturneTranslations[madara].js",
+ "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/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/fix-plugins/.js/plugins/english/NoobchanTranslation[madara].js",
+ "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/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/fix-plugins/.js/plugins/english/NovelMultiverse[madara].js",
+ "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/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/fix-plugins/.js/plugins/english/NovelR18[madara].js",
+ "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/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/fix-plugins/.js/plugins/english/Novelroomnet[madara].js",
+ "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/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/fix-plugins/.js/plugins/english/Novelstic[madara].js",
+ "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/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/fix-plugins/.js/plugins/english/NovelTranslate[madara].js",
+ "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/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/fix-plugins/.js/plugins/english/OnlyMTL[madara].js",
+ "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/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/fix-plugins/.js/plugins/english/pandaMTL.js",
+ "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/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/fix-plugins/.js/plugins/english/ReadWebNovels[madara].js",
+ "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/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/fix-plugins/.js/plugins/english/SleepyTranslations[madara].js",
+ "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/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/fix-plugins/.js/plugins/english/SonicMTL[madara].js",
+ "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/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/fix-plugins/.js/plugins/english/SugarBabies[madara].js",
+ "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/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/fix-plugins/.js/plugins/english/SweetEscapeTranslations[madara].js",
+ "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/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/fix-plugins/.js/plugins/english/WebNovelLover[madara].js",
+ "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/madara/icons/webnovellover.png"
+ },
+ {
+ "id": "wuxiacity",
+ "name": "Wuxiacity[readwn]",
+ "site": "https://www.wuxiacity.com",
+ "lang": "English",
+ "version": "1.0.0",
+ "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/english/Wuxiacity[readwn].js",
+ "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/readwn/icons/wuxiacity.png"
+ },
+ {
+ "id": "wuxiap",
+ "name": "Wuxiap[readwn]",
+ "site": "https://www.wuxiap.com",
+ "lang": "English",
+ "version": "1.0.0",
+ "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/english/Wuxiap[readwn].js",
+ "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/readwn/icons/wuxiap.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/fix-plugins/.js/plugins/english/WuxiaWorldSite[madara].js",
+ "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/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/fix-plugins/.js/plugins/english/ZetroTranslation[madara].js",
+ "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/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/fix-plugins/.js/plugins/english/ZinnNovel[madara].js",
+ "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/madara/icons/zinnnovel.png"
+ }
+ ],
+ "français, française": [
+ {
+ "id": "chireads.com",
+ "name": "Chireads",
+ "site": "https://chireads.com",
+ "lang": "français, française",
+ "version": "1.0.0",
+ "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/french/chireads.js",
+ "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/src/fr/chireads/icon.png"
+ },
+ {
+ "id": "lightnovelfr",
+ "name": "Ligh Novel FR[wpmangastream]",
+ "site": "https://lightnovelfr.com/",
+ "lang": "français, française",
+ "version": "1.0.0",
+ "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/french/LighNovelFR[wpmangastream].js",
+ "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/wpmangastream/icons/lightnovelfr.png"
+ },
+ {
+ "id": "NDG.com",
+ "name": "NovelDeGlace",
+ "site": "https://noveldeglace.com/",
+ "lang": "français, française",
+ "version": "1.0.0",
+ "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/french/noveldeglace.js",
+ "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/src/fr/noveldeglace/icon.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/fix-plugins/.js/plugins/indonesian/MeioNovel[madara].js",
+ "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/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/fix-plugins/.js/plugins/indonesian/MoreNovel[madara].js",
+ "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/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/fix-plugins/.js/plugins/indonesian/WBNovel[madara].js",
+ "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/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/fix-plugins/.js/plugins/portuguese/lightnovelbrasil.js",
+ "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/wpmangastream/icons/lightnovelbrasil.png"
+ }
+ ],
+ "русский язык": [
+ {
+ "id": "AT",
+ "name": "Автор Тудей",
+ "site": "https://author.today",
+ "lang": "русский язык",
+ "version": "1.0.0",
+ "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/russian/authortoday.js",
+ "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/src/ru/authortoday/icon.png"
+ },
+ {
+ "id": "bookhamster",
+ "name": "Bookhamster[ifreedom]",
+ "site": "https://bookhamster.ru",
+ "lang": "русский язык",
+ "version": "1.0.0",
+ "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/russian/Bookhamster[ifreedom].js",
+ "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/ifreedom/icons/bookhamster.png"
+ },
+ {
+ "id": "bookriver",
+ "name": "Bookriver",
+ "site": "https://bookriver.ru",
+ "lang": "русский язык",
+ "version": "1.0.0",
+ "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/russian/bookriver.js",
+ "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/src/ru/bookriver/icon.png"
+ },
+ {
+ "id": "erolate",
+ "name": "Erolate[rulate]",
+ "site": "https://erolate.com",
+ "lang": "русский язык",
+ "version": "1.0.0",
+ "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/russian/Erolate[rulate].js",
+ "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/rulate/icons/erolate.png"
+ },
+ {
+ "id": "ficbook",
+ "name": "ficbook",
+ "site": "https://ficbook.net",
+ "lang": "русский язык",
+ "version": "1.0.0",
+ "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/russian/ficbook.js",
+ "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/src/ru/ficbook/icon.png"
+ },
+ {
+ "id": "freedlit.space",
+ "name": "LitSpace",
+ "site": "https://freedlit.space",
+ "lang": "русский язык",
+ "version": "1.0.0",
+ "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/russian/LitSpace.js",
+ "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/src/ru/freedlit/icon.png"
+ },
+ {
+ "id": "ifreedom",
+ "name": "Свободный Мир Ранобэ[ifreedom]",
+ "site": "https://ifreedom.su",
+ "lang": "русский язык",
+ "version": "1.0.0",
+ "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/russian/СвободныйМирРанобэ[ifreedom].js",
+ "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/ifreedom/icons/ifreedom.png"
+ },
+ {
+ "id": "jaomix.ru",
+ "name": "Jaomix",
+ "site": "https://jaomix.ru",
+ "lang": "русский язык",
+ "version": "1.0.0",
+ "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/russian/jaomix.js",
+ "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/src/ru/jaomix/icon.png"
+ },
+ {
+ "id": "ReN",
+ "name": "Renovels",
+ "site": "https://renovels.org",
+ "lang": "русский язык",
+ "version": "1.0.0",
+ "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/russian/renovels.js",
+ "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/src/ru/renovels/icon.png"
+ },
+ {
+ "id": "RLIB",
+ "name": "RanobeLib",
+ "site": "https://ranobelib.me",
+ "lang": "русский язык",
+ "version": "1.0.0",
+ "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/russian/ranobelib.js",
+ "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/src/ru/ranobelib/icon.png"
+ },
+ {
+ "id": "RNBH.org",
+ "name": "RanobeHub",
+ "site": "https://ranobehub.org/",
+ "lang": "русский язык",
+ "version": "1.0.0",
+ "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/russian/ranobehub.js",
+ "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/src/ru/ranobehub/icon.png"
+ },
+ {
+ "id": "RNRF",
+ "name": "РанобэРФ",
+ "site": "https://ранобэ.рф",
+ "lang": "русский язык",
+ "version": "1.0.0",
+ "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/russian/ranoberf.js",
+ "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/src/ru/ranoberf/icon.png"
+ },
+ {
+ "id": "TL",
+ "name": "NovelTL",
+ "site": "https://novel.tl",
+ "lang": "русский язык",
+ "version": "1.0.0",
+ "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/russian/novelTL.js",
+ "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/src/ru/noveltl/icon.png"
+ },
+ {
+ "id": "tl.rulate",
+ "name": "Rulate[rulate]",
+ "site": "https://tl.rulate.ru",
+ "lang": "русский язык",
+ "version": "1.0.0",
+ "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/russian/Rulate[rulate].js",
+ "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/rulate/icons/rulate.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/nyagami/plugins/fix-plugins/.js/plugins/spanish/tunovelaligera.js",
+ "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/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/nyagami/plugins/fix-plugins/.js/plugins/turkish/lshnovel.js",
+ "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/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/fix-plugins/.js/plugins/turkish/TurkceLightNovels[madara].js",
+ "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/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/fix-plugins/.js/plugins/turkish/WebNovelOku[madara].js",
+ "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/madara/icons/webnoveloku.png"
+ }
+ ],
+ "Україна": [
+ {
+ "id": "smakolykytl",
+ "name": "Смаколики",
+ "site": "https://smakolykytl.site/",
+ "lang": "Україна",
+ "version": "1.0.0",
+ "url": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/ukraine/smakolykytl.js",
+ "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/src/ua/smakolykytl/icon.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/fix-plugins/.js/plugins/vietnamese/LNHako.js",
+ "iconUrl": "https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/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..46bc7d2
--- /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/fix-plugins/.js/plugins/arabic/ArMTL[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/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/fix-plugins/.js/plugins/arabic/ArNovel[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/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/fix-plugins/.js/plugins/arabic/HizoManga[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/madara/icons/hizomanga.png"},{"id":"kol-novel","name":"Kol Novel[wpmangastream]","site":"https://kolnovel.com/","lang":"العربية","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/arabic/KolNovel[wpmangastream].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/wpmangastream/icons/kol-novel.png"},{"id":"kolnovel","name":"KolNovel","site":"https://kolnovel.lol/","lang":"العربية","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/arabic/kolnovel.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/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/fix-plugins/.js/plugins/arabic/Novel4Up[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/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/fix-plugins/.js/plugins/arabic/Riwyat[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/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/fix-plugins/.js/plugins/arabic/TeamXNovel[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/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/nyagami/plugins/fix-plugins/.js/plugins/chinese/linovelib.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/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/nyagami/plugins/fix-plugins/.js/plugins/english/FirstKissNovel[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/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/fix-plugins/.js/plugins/english/bestlightnovel.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/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/fix-plugins/.js/plugins/english/BoxNovel[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/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/fix-plugins/.js/plugins/english/ClickNovel[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/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/fix-plugins/.js/plugins/english/CrateNovel[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/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/fix-plugins/.js/plugins/english/DaoNovel[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/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/fix-plugins/.js/plugins/english/FansTranslations[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/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/fix-plugins/.js/plugins/english/FreeNovelMe[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/madara/icons/freenovelme.png"},{"id":"ftest","name":"Filter Test","site":"https://noblemtl.com/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/english/filterTests.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/src/en/noblemtl/icon.png"},{"id":"FWN.com","name":"Web NOVEL","site":"https://freewebnovel.com","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/english/freewebnovel.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/src/en/freewebnovel/icon.png"},{"id":"guavaread","name":"Guavaread[madara]","site":"https://guavaread.com/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/english/Guavaread[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/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/fix-plugins/.js/plugins/english/LightNovelHeaven[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/madara/icons/lightnovelheaven.png"},{"id":"Ltnovel.com","name":"Ltnovel[readwn]","site":"https://www.ltnovel.com","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/english/Ltnovel[readwn].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/readwn/icons/ltnovel.png"},{"id":"lunarletters","name":"LunarLetters[madara]","site":"https://www.lunarletters.com/","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/english/LunarLetters[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/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/fix-plugins/.js/plugins/english/MostNovel[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/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/fix-plugins/.js/plugins/english/MTLNovel[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/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/fix-plugins/.js/plugins/english/MTLNovelClub[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/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/fix-plugins/.js/plugins/english/MysticalSeries[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/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/fix-plugins/.js/plugins/english/NeoSekaiTranslations[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/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/fix-plugins/.js/plugins/english/nobleMTL.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/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/fix-plugins/.js/plugins/english/NocturneTranslations[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/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/fix-plugins/.js/plugins/english/NoobchanTranslation[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/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/fix-plugins/.js/plugins/english/NovelMultiverse[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/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/fix-plugins/.js/plugins/english/NovelR18[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/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/fix-plugins/.js/plugins/english/Novelroomnet[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/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/fix-plugins/.js/plugins/english/Novelstic[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/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/fix-plugins/.js/plugins/english/NovelTranslate[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/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/fix-plugins/.js/plugins/english/OnlyMTL[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/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/fix-plugins/.js/plugins/english/pandaMTL.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/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/fix-plugins/.js/plugins/english/ReadWebNovels[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/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/fix-plugins/.js/plugins/english/SleepyTranslations[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/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/fix-plugins/.js/plugins/english/SonicMTL[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/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/fix-plugins/.js/plugins/english/SugarBabies[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/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/fix-plugins/.js/plugins/english/SweetEscapeTranslations[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/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/fix-plugins/.js/plugins/english/WebNovelLover[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/madara/icons/webnovellover.png"},{"id":"wuxiacity","name":"Wuxiacity[readwn]","site":"https://www.wuxiacity.com","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/english/Wuxiacity[readwn].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/readwn/icons/wuxiacity.png"},{"id":"wuxiap","name":"Wuxiap[readwn]","site":"https://www.wuxiap.com","lang":"English","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/english/Wuxiap[readwn].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/readwn/icons/wuxiap.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/fix-plugins/.js/plugins/english/WuxiaWorldSite[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/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/fix-plugins/.js/plugins/english/ZetroTranslation[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/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/fix-plugins/.js/plugins/english/ZinnNovel[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/madara/icons/zinnnovel.png"}],"français, française":[{"id":"chireads.com","name":"Chireads","site":"https://chireads.com","lang":"français, française","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/french/chireads.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/src/fr/chireads/icon.png"},{"id":"lightnovelfr","name":"Ligh Novel FR[wpmangastream]","site":"https://lightnovelfr.com/","lang":"français, française","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/french/LighNovelFR[wpmangastream].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/wpmangastream/icons/lightnovelfr.png"},{"id":"NDG.com","name":"NovelDeGlace","site":"https://noveldeglace.com/","lang":"français, française","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/french/noveldeglace.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/src/fr/noveldeglace/icon.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/fix-plugins/.js/plugins/indonesian/MeioNovel[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/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/fix-plugins/.js/plugins/indonesian/MoreNovel[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/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/fix-plugins/.js/plugins/indonesian/WBNovel[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/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/fix-plugins/.js/plugins/portuguese/lightnovelbrasil.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/wpmangastream/icons/lightnovelbrasil.png"}],"русский язык":[{"id":"AT","name":"Автор Тудей","site":"https://author.today","lang":"русский язык","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/russian/authortoday.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/src/ru/authortoday/icon.png"},{"id":"bookhamster","name":"Bookhamster[ifreedom]","site":"https://bookhamster.ru","lang":"русский язык","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/russian/Bookhamster[ifreedom].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/ifreedom/icons/bookhamster.png"},{"id":"bookriver","name":"Bookriver","site":"https://bookriver.ru","lang":"русский язык","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/russian/bookriver.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/src/ru/bookriver/icon.png"},{"id":"erolate","name":"Erolate[rulate]","site":"https://erolate.com","lang":"русский язык","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/russian/Erolate[rulate].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/rulate/icons/erolate.png"},{"id":"ficbook","name":"ficbook","site":"https://ficbook.net","lang":"русский язык","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/russian/ficbook.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/src/ru/ficbook/icon.png"},{"id":"freedlit.space","name":"LitSpace","site":"https://freedlit.space","lang":"русский язык","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/russian/LitSpace.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/src/ru/freedlit/icon.png"},{"id":"ifreedom","name":"Свободный Мир Ранобэ[ifreedom]","site":"https://ifreedom.su","lang":"русский язык","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/russian/СвободныйМирРанобэ[ifreedom].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/ifreedom/icons/ifreedom.png"},{"id":"jaomix.ru","name":"Jaomix","site":"https://jaomix.ru","lang":"русский язык","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/russian/jaomix.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/src/ru/jaomix/icon.png"},{"id":"ReN","name":"Renovels","site":"https://renovels.org","lang":"русский язык","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/russian/renovels.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/src/ru/renovels/icon.png"},{"id":"RLIB","name":"RanobeLib","site":"https://ranobelib.me","lang":"русский язык","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/russian/ranobelib.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/src/ru/ranobelib/icon.png"},{"id":"RNBH.org","name":"RanobeHub","site":"https://ranobehub.org/","lang":"русский язык","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/russian/ranobehub.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/src/ru/ranobehub/icon.png"},{"id":"RNRF","name":"РанобэРФ","site":"https://ранобэ.рф","lang":"русский язык","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/russian/ranoberf.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/src/ru/ranoberf/icon.png"},{"id":"TL","name":"NovelTL","site":"https://novel.tl","lang":"русский язык","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/russian/novelTL.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/src/ru/noveltl/icon.png"},{"id":"tl.rulate","name":"Rulate[rulate]","site":"https://tl.rulate.ru","lang":"русский язык","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/russian/Rulate[rulate].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/rulate/icons/rulate.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/nyagami/plugins/fix-plugins/.js/plugins/spanish/tunovelaligera.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/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/nyagami/plugins/fix-plugins/.js/plugins/turkish/lshnovel.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/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/fix-plugins/.js/plugins/turkish/TurkceLightNovels[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/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/fix-plugins/.js/plugins/turkish/WebNovelOku[madara].js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/multisrc/madara/icons/webnoveloku.png"}],"Україна":[{"id":"smakolykytl","name":"Смаколики","site":"https://smakolykytl.site/","lang":"Україна","version":"1.0.0","url":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/.js/plugins/ukraine/smakolykytl.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/src/ua/smakolykytl/icon.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/fix-plugins/.js/plugins/vietnamese/LNHako.js","iconUrl":"https://raw.githubusercontent.com/nyagami/plugins/fix-plugins/icons/src/vi/hakolightnovel/icon.png"}]}
\ No newline at end of file
diff --git a/.js/plugins/arabic/ArMTL[madara].js b/.js/plugins/arabic/ArMTL[madara].js
index 058ef94..6e5c3ad 100644
--- a/.js/plugins/arabic/ArMTL[madara].js
+++ b/.js/plugins/arabic/ArMTL[madara].js
@@ -62,7 +62,6 @@ var MadaraPlugin = /** @class */ (function () {
this.site = metadata.sourceSite;
this.version = "1.0.0";
this.userAgent = "";
- this.cookieString = "";
this.options = metadata.options;
this.filters = metadata.filters;
}
diff --git a/.js/plugins/arabic/ArNovel[madara].js b/.js/plugins/arabic/ArNovel[madara].js
index a413818..4e19077 100644
--- a/.js/plugins/arabic/ArNovel[madara].js
+++ b/.js/plugins/arabic/ArNovel[madara].js
@@ -63,7 +63,6 @@ var MadaraPlugin = /** @class */ (function () {
this.site = metadata.sourceSite;
this.version = "1.0.0";
this.userAgent = "";
- this.cookieString = "";
this.options = metadata.options;
this.filters = metadata.filters;
}
diff --git a/.js/plugins/arabic/HizoManga[madara].js b/.js/plugins/arabic/HizoManga[madara].js
index 2796c26..99e8627 100644
--- a/.js/plugins/arabic/HizoManga[madara].js
+++ b/.js/plugins/arabic/HizoManga[madara].js
@@ -63,7 +63,6 @@ var MadaraPlugin = /** @class */ (function () {
this.site = metadata.sourceSite;
this.version = "1.0.0";
this.userAgent = "";
- this.cookieString = "";
this.options = metadata.options;
this.filters = metadata.filters;
}
diff --git a/.js/plugins/arabic/KolNovel[wpmangastream].js b/.js/plugins/arabic/KolNovel[wpmangastream].js
index 0bb1f5a..950cba9 100644
--- a/.js/plugins/arabic/KolNovel[wpmangastream].js
+++ b/.js/plugins/arabic/KolNovel[wpmangastream].js
@@ -47,7 +47,6 @@ var WPmangaStreamPlugin = /** @class */ (function () {
this.site = metadata.sourceSite;
this.version = "1.0.0";
this.userAgent = "";
- this.cookieString = "";
this.options = metadata.options;
}
WPmangaStreamPlugin.prototype.popularNovels = function (page) {
diff --git a/.js/plugins/arabic/Novel4Up[madara].js b/.js/plugins/arabic/Novel4Up[madara].js
index cbe2559..ce1c830 100644
--- a/.js/plugins/arabic/Novel4Up[madara].js
+++ b/.js/plugins/arabic/Novel4Up[madara].js
@@ -63,7 +63,6 @@ var MadaraPlugin = /** @class */ (function () {
this.site = metadata.sourceSite;
this.version = "1.0.0";
this.userAgent = "";
- this.cookieString = "";
this.options = metadata.options;
this.filters = metadata.filters;
}
diff --git a/.js/plugins/arabic/Riwyat[madara].js b/.js/plugins/arabic/Riwyat[madara].js
index 0f0d017..18c74a1 100644
--- a/.js/plugins/arabic/Riwyat[madara].js
+++ b/.js/plugins/arabic/Riwyat[madara].js
@@ -63,7 +63,6 @@ var MadaraPlugin = /** @class */ (function () {
this.site = metadata.sourceSite;
this.version = "1.0.0";
this.userAgent = "";
- this.cookieString = "";
this.options = metadata.options;
this.filters = metadata.filters;
}
diff --git a/.js/plugins/arabic/TeamXNovel[madara].js b/.js/plugins/arabic/TeamXNovel[madara].js
index 671e2f1..83f921c 100644
--- a/.js/plugins/arabic/TeamXNovel[madara].js
+++ b/.js/plugins/arabic/TeamXNovel[madara].js
@@ -62,7 +62,6 @@ var MadaraPlugin = /** @class */ (function () {
this.site = metadata.sourceSite;
this.version = "1.0.0";
this.userAgent = "";
- this.cookieString = "";
this.options = metadata.options;
this.filters = metadata.filters;
}
diff --git a/.js/plugins/arabic/kolnovel.js b/.js/plugins/arabic/kolnovel.js
index ee83f11..ac4d1ff 100644
--- a/.js/plugins/arabic/kolnovel.js
+++ b/.js/plugins/arabic/kolnovel.js
@@ -47,7 +47,6 @@ var KolNovel = /** @class */ (function () {
this.site = "https://kolnovel.lol/";
this.version = "1.0.0";
this.userAgent = "";
- this.cookieString = "";
this.filters = {
order: {
label: "ترتيب حسب",
@@ -148,9 +147,6 @@ var KolNovel = /** @class */ (function () {
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();
})];
@@ -185,9 +181,6 @@ var KolNovel = /** @class */ (function () {
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();
@@ -258,9 +251,6 @@ var KolNovel = /** @class */ (function () {
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();
@@ -286,9 +276,6 @@ var KolNovel = /** @class */ (function () {
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();
diff --git a/.js/plugins/chinese/linovelib.js b/.js/plugins/chinese/linovelib.js
index af5c997..68b5eba 100644
--- a/.js/plugins/chinese/linovelib.js
+++ b/.js/plugins/chinese/linovelib.js
@@ -48,7 +48,6 @@ var Linovelib = /** @class */ (function () {
this.site = "https://w.linovelib.com";
this.version = "1.0.0";
this.userAgent = "";
- this.cookieString = "";
this.filters = {
sort: {
label: "Sort By",
@@ -83,9 +82,6 @@ var Linovelib = /** @class */ (function () {
link += filters.sort;
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();
})];
@@ -124,9 +120,6 @@ var Linovelib = /** @class */ (function () {
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();
@@ -206,9 +199,6 @@ var Linovelib = /** @class */ (function () {
switch (_a.label) {
case 0:
headers = new Headers();
- if (this.cookieString) {
- headers.append("cookie", this.cookieString);
- }
chapterText = "", pageText = "";
pageNumber = 1;
skillgg = {
@@ -416,9 +406,6 @@ var Linovelib = /** @class */ (function () {
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 () {
diff --git a/.js/plugins/english/BoxNovel[madara].js b/.js/plugins/english/BoxNovel[madara].js
index ec9ba27..fbb35c7 100644
--- a/.js/plugins/english/BoxNovel[madara].js
+++ b/.js/plugins/english/BoxNovel[madara].js
@@ -63,7 +63,6 @@ var MadaraPlugin = /** @class */ (function () {
this.site = metadata.sourceSite;
this.version = "1.0.0";
this.userAgent = "";
- this.cookieString = "";
this.options = metadata.options;
this.filters = metadata.filters;
}
diff --git a/.js/plugins/english/ClickNovel[madara].js b/.js/plugins/english/ClickNovel[madara].js
index 8205354..5fe892c 100644
--- a/.js/plugins/english/ClickNovel[madara].js
+++ b/.js/plugins/english/ClickNovel[madara].js
@@ -62,7 +62,6 @@ var MadaraPlugin = /** @class */ (function () {
this.site = metadata.sourceSite;
this.version = "1.0.0";
this.userAgent = "";
- this.cookieString = "";
this.options = metadata.options;
this.filters = metadata.filters;
}
diff --git a/.js/plugins/english/CrateNovel[madara].js b/.js/plugins/english/CrateNovel[madara].js
index 4dd0ddd..ccf5133 100644
--- a/.js/plugins/english/CrateNovel[madara].js
+++ b/.js/plugins/english/CrateNovel[madara].js
@@ -62,7 +62,6 @@ var MadaraPlugin = /** @class */ (function () {
this.site = metadata.sourceSite;
this.version = "1.0.0";
this.userAgent = "";
- this.cookieString = "";
this.options = metadata.options;
this.filters = metadata.filters;
}
diff --git a/.js/plugins/english/DaoNovel[madara].js b/.js/plugins/english/DaoNovel[madara].js
index 3ad500d..957db49 100644
--- a/.js/plugins/english/DaoNovel[madara].js
+++ b/.js/plugins/english/DaoNovel[madara].js
@@ -63,7 +63,6 @@ var MadaraPlugin = /** @class */ (function () {
this.site = metadata.sourceSite;
this.version = "1.0.0";
this.userAgent = "";
- this.cookieString = "";
this.options = metadata.options;
this.filters = metadata.filters;
}
diff --git a/.js/plugins/english/FansTranslations[madara].js b/.js/plugins/english/FansTranslations[madara].js
index cb72eef..65fa9de 100644
--- a/.js/plugins/english/FansTranslations[madara].js
+++ b/.js/plugins/english/FansTranslations[madara].js
@@ -63,7 +63,6 @@ var MadaraPlugin = /** @class */ (function () {
this.site = metadata.sourceSite;
this.version = "1.0.0";
this.userAgent = "";
- this.cookieString = "";
this.options = metadata.options;
this.filters = metadata.filters;
}
diff --git a/.js/plugins/english/FirstKissNovel[madara].js b/.js/plugins/english/FirstKissNovel[madara].js
index 41e25c2..55f4dc5 100644
--- a/.js/plugins/english/FirstKissNovel[madara].js
+++ b/.js/plugins/english/FirstKissNovel[madara].js
@@ -63,7 +63,6 @@ var MadaraPlugin = /** @class */ (function () {
this.site = metadata.sourceSite;
this.version = "1.0.0";
this.userAgent = "";
- this.cookieString = "";
this.options = metadata.options;
this.filters = metadata.filters;
}
diff --git a/.js/plugins/english/FreeNovelMe[madara].js b/.js/plugins/english/FreeNovelMe[madara].js
index e4f4d3d..8ea5734 100644
--- a/.js/plugins/english/FreeNovelMe[madara].js
+++ b/.js/plugins/english/FreeNovelMe[madara].js
@@ -63,7 +63,6 @@ var MadaraPlugin = /** @class */ (function () {
this.site = metadata.sourceSite;
this.version = "1.0.0";
this.userAgent = "";
- this.cookieString = "";
this.options = metadata.options;
this.filters = metadata.filters;
}
diff --git a/.js/plugins/english/Guavaread[madara].js b/.js/plugins/english/Guavaread[madara].js
index 2e196eb..d3ce1a2 100644
--- a/.js/plugins/english/Guavaread[madara].js
+++ b/.js/plugins/english/Guavaread[madara].js
@@ -63,7 +63,6 @@ var MadaraPlugin = /** @class */ (function () {
this.site = metadata.sourceSite;
this.version = "1.0.0";
this.userAgent = "";
- this.cookieString = "";
this.options = metadata.options;
this.filters = metadata.filters;
}
diff --git a/.js/plugins/english/LightNovelHeaven[madara].js b/.js/plugins/english/LightNovelHeaven[madara].js
index bb21c84..bb21424 100644
--- a/.js/plugins/english/LightNovelHeaven[madara].js
+++ b/.js/plugins/english/LightNovelHeaven[madara].js
@@ -63,7 +63,6 @@ var MadaraPlugin = /** @class */ (function () {
this.site = metadata.sourceSite;
this.version = "1.0.0";
this.userAgent = "";
- this.cookieString = "";
this.options = metadata.options;
this.filters = metadata.filters;
}
diff --git a/.js/plugins/english/Ltnovel[readwn].js b/.js/plugins/english/Ltnovel[readwn].js
index de3d7a5..7ab3fe9 100644
--- a/.js/plugins/english/Ltnovel[readwn].js
+++ b/.js/plugins/english/Ltnovel[readwn].js
@@ -50,7 +50,6 @@ var ReadwnPlugin = /** @class */ (function () {
this.site = metadata.sourceSite;
this.version = "1.0.0";
this.userAgent = "";
- this.cookieString = "";
this.filters = metadata.filters;
}
ReadwnPlugin.prototype.popularNovels = function (pageNo, _a) {
diff --git a/.js/plugins/english/LunarLetters[madara].js b/.js/plugins/english/LunarLetters[madara].js
index 52934ef..e9cc152 100644
--- a/.js/plugins/english/LunarLetters[madara].js
+++ b/.js/plugins/english/LunarLetters[madara].js
@@ -63,7 +63,6 @@ var MadaraPlugin = /** @class */ (function () {
this.site = metadata.sourceSite;
this.version = "1.0.0";
this.userAgent = "";
- this.cookieString = "";
this.options = metadata.options;
this.filters = metadata.filters;
}
diff --git a/.js/plugins/english/MTLNovelClub[madara].js b/.js/plugins/english/MTLNovelClub[madara].js
index 7322277..7cf11f7 100644
--- a/.js/plugins/english/MTLNovelClub[madara].js
+++ b/.js/plugins/english/MTLNovelClub[madara].js
@@ -62,7 +62,6 @@ var MadaraPlugin = /** @class */ (function () {
this.site = metadata.sourceSite;
this.version = "1.0.0";
this.userAgent = "";
- this.cookieString = "";
this.options = metadata.options;
this.filters = metadata.filters;
}
diff --git a/.js/plugins/english/MTLNovel[madara].js b/.js/plugins/english/MTLNovel[madara].js
index 80b1123..7d7d83a 100644
--- a/.js/plugins/english/MTLNovel[madara].js
+++ b/.js/plugins/english/MTLNovel[madara].js
@@ -63,7 +63,6 @@ var MadaraPlugin = /** @class */ (function () {
this.site = metadata.sourceSite;
this.version = "1.0.0";
this.userAgent = "";
- this.cookieString = "";
this.options = metadata.options;
this.filters = metadata.filters;
}
diff --git a/.js/plugins/english/MostNovel[madara].js b/.js/plugins/english/MostNovel[madara].js
index 56efbbe..57fad40 100644
--- a/.js/plugins/english/MostNovel[madara].js
+++ b/.js/plugins/english/MostNovel[madara].js
@@ -63,7 +63,6 @@ var MadaraPlugin = /** @class */ (function () {
this.site = metadata.sourceSite;
this.version = "1.0.0";
this.userAgent = "";
- this.cookieString = "";
this.options = metadata.options;
this.filters = metadata.filters;
}
diff --git a/.js/plugins/english/MysticalSeries[madara].js b/.js/plugins/english/MysticalSeries[madara].js
index bb16025..51cb318 100644
--- a/.js/plugins/english/MysticalSeries[madara].js
+++ b/.js/plugins/english/MysticalSeries[madara].js
@@ -63,7 +63,6 @@ var MadaraPlugin = /** @class */ (function () {
this.site = metadata.sourceSite;
this.version = "1.0.0";
this.userAgent = "";
- this.cookieString = "";
this.options = metadata.options;
this.filters = metadata.filters;
}
diff --git a/.js/plugins/english/NeoSekaiTranslations[madara].js b/.js/plugins/english/NeoSekaiTranslations[madara].js
index 1a040ad..db2d111 100644
--- a/.js/plugins/english/NeoSekaiTranslations[madara].js
+++ b/.js/plugins/english/NeoSekaiTranslations[madara].js
@@ -63,7 +63,6 @@ var MadaraPlugin = /** @class */ (function () {
this.site = metadata.sourceSite;
this.version = "1.0.0";
this.userAgent = "";
- this.cookieString = "";
this.options = metadata.options;
this.filters = metadata.filters;
}
diff --git a/.js/plugins/english/NocturneTranslations[madara].js b/.js/plugins/english/NocturneTranslations[madara].js
index 7fa2cff..8e8117e 100644
--- a/.js/plugins/english/NocturneTranslations[madara].js
+++ b/.js/plugins/english/NocturneTranslations[madara].js
@@ -63,7 +63,6 @@ var MadaraPlugin = /** @class */ (function () {
this.site = metadata.sourceSite;
this.version = "1.0.0";
this.userAgent = "";
- this.cookieString = "";
this.options = metadata.options;
this.filters = metadata.filters;
}
diff --git a/.js/plugins/english/NoobchanTranslation[madara].js b/.js/plugins/english/NoobchanTranslation[madara].js
index c4afe19..c6869bd 100644
--- a/.js/plugins/english/NoobchanTranslation[madara].js
+++ b/.js/plugins/english/NoobchanTranslation[madara].js
@@ -62,7 +62,6 @@ var MadaraPlugin = /** @class */ (function () {
this.site = metadata.sourceSite;
this.version = "1.0.0";
this.userAgent = "";
- this.cookieString = "";
this.options = metadata.options;
this.filters = metadata.filters;
}
diff --git a/.js/plugins/english/NovelMultiverse[madara].js b/.js/plugins/english/NovelMultiverse[madara].js
index 16ce5e7..82999dd 100644
--- a/.js/plugins/english/NovelMultiverse[madara].js
+++ b/.js/plugins/english/NovelMultiverse[madara].js
@@ -63,7 +63,6 @@ var MadaraPlugin = /** @class */ (function () {
this.site = metadata.sourceSite;
this.version = "1.0.0";
this.userAgent = "";
- this.cookieString = "";
this.options = metadata.options;
this.filters = metadata.filters;
}
diff --git a/.js/plugins/english/NovelR18[madara].js b/.js/plugins/english/NovelR18[madara].js
index 832f8ed..006a267 100644
--- a/.js/plugins/english/NovelR18[madara].js
+++ b/.js/plugins/english/NovelR18[madara].js
@@ -63,7 +63,6 @@ var MadaraPlugin = /** @class */ (function () {
this.site = metadata.sourceSite;
this.version = "1.0.0";
this.userAgent = "";
- this.cookieString = "";
this.options = metadata.options;
this.filters = metadata.filters;
}
diff --git a/.js/plugins/english/NovelTranslate[madara].js b/.js/plugins/english/NovelTranslate[madara].js
index c9bf1bf..132ba49 100644
--- a/.js/plugins/english/NovelTranslate[madara].js
+++ b/.js/plugins/english/NovelTranslate[madara].js
@@ -63,7 +63,6 @@ var MadaraPlugin = /** @class */ (function () {
this.site = metadata.sourceSite;
this.version = "1.0.0";
this.userAgent = "";
- this.cookieString = "";
this.options = metadata.options;
this.filters = metadata.filters;
}
diff --git a/.js/plugins/english/Novelroomnet[madara].js b/.js/plugins/english/Novelroomnet[madara].js
index 858af3f..b46a881 100644
--- a/.js/plugins/english/Novelroomnet[madara].js
+++ b/.js/plugins/english/Novelroomnet[madara].js
@@ -62,7 +62,6 @@ var MadaraPlugin = /** @class */ (function () {
this.site = metadata.sourceSite;
this.version = "1.0.0";
this.userAgent = "";
- this.cookieString = "";
this.options = metadata.options;
this.filters = metadata.filters;
}
diff --git a/.js/plugins/english/Novelstic[madara].js b/.js/plugins/english/Novelstic[madara].js
index 753b6b9..ea89ef7 100644
--- a/.js/plugins/english/Novelstic[madara].js
+++ b/.js/plugins/english/Novelstic[madara].js
@@ -63,7 +63,6 @@ var MadaraPlugin = /** @class */ (function () {
this.site = metadata.sourceSite;
this.version = "1.0.0";
this.userAgent = "";
- this.cookieString = "";
this.options = metadata.options;
this.filters = metadata.filters;
}
diff --git a/.js/plugins/english/OnlyMTL[madara].js b/.js/plugins/english/OnlyMTL[madara].js
index 3f5c69a..7f8aaca 100644
--- a/.js/plugins/english/OnlyMTL[madara].js
+++ b/.js/plugins/english/OnlyMTL[madara].js
@@ -62,7 +62,6 @@ var MadaraPlugin = /** @class */ (function () {
this.site = metadata.sourceSite;
this.version = "1.0.0";
this.userAgent = "";
- this.cookieString = "";
this.options = metadata.options;
this.filters = metadata.filters;
}
diff --git a/.js/plugins/english/ReadWebNovels[madara].js b/.js/plugins/english/ReadWebNovels[madara].js
index a2ae423..a9d44bc 100644
--- a/.js/plugins/english/ReadWebNovels[madara].js
+++ b/.js/plugins/english/ReadWebNovels[madara].js
@@ -63,7 +63,6 @@ var MadaraPlugin = /** @class */ (function () {
this.site = metadata.sourceSite;
this.version = "1.0.0";
this.userAgent = "";
- this.cookieString = "";
this.options = metadata.options;
this.filters = metadata.filters;
}
diff --git a/.js/plugins/english/SleepyTranslations[madara].js b/.js/plugins/english/SleepyTranslations[madara].js
index ff37039..5ac5b62 100644
--- a/.js/plugins/english/SleepyTranslations[madara].js
+++ b/.js/plugins/english/SleepyTranslations[madara].js
@@ -63,7 +63,6 @@ var MadaraPlugin = /** @class */ (function () {
this.site = metadata.sourceSite;
this.version = "1.0.0";
this.userAgent = "";
- this.cookieString = "";
this.options = metadata.options;
this.filters = metadata.filters;
}
diff --git a/.js/plugins/english/SonicMTL[madara].js b/.js/plugins/english/SonicMTL[madara].js
index c42c8d2..f4832dd 100644
--- a/.js/plugins/english/SonicMTL[madara].js
+++ b/.js/plugins/english/SonicMTL[madara].js
@@ -63,7 +63,6 @@ var MadaraPlugin = /** @class */ (function () {
this.site = metadata.sourceSite;
this.version = "1.0.0";
this.userAgent = "";
- this.cookieString = "";
this.options = metadata.options;
this.filters = metadata.filters;
}
diff --git a/.js/plugins/english/SugarBabies[madara].js b/.js/plugins/english/SugarBabies[madara].js
index 4e9570b..e6bb195 100644
--- a/.js/plugins/english/SugarBabies[madara].js
+++ b/.js/plugins/english/SugarBabies[madara].js
@@ -62,7 +62,6 @@ var MadaraPlugin = /** @class */ (function () {
this.site = metadata.sourceSite;
this.version = "1.0.0";
this.userAgent = "";
- this.cookieString = "";
this.options = metadata.options;
this.filters = metadata.filters;
}
diff --git a/.js/plugins/english/SweetEscapeTranslations[madara].js b/.js/plugins/english/SweetEscapeTranslations[madara].js
index 7b44d52..3e3f9fb 100644
--- a/.js/plugins/english/SweetEscapeTranslations[madara].js
+++ b/.js/plugins/english/SweetEscapeTranslations[madara].js
@@ -63,7 +63,6 @@ var MadaraPlugin = /** @class */ (function () {
this.site = metadata.sourceSite;
this.version = "1.0.0";
this.userAgent = "";
- this.cookieString = "";
this.options = metadata.options;
this.filters = metadata.filters;
}
diff --git a/.js/plugins/english/WebNovelLover[madara].js b/.js/plugins/english/WebNovelLover[madara].js
index 49249af..7a39e84 100644
--- a/.js/plugins/english/WebNovelLover[madara].js
+++ b/.js/plugins/english/WebNovelLover[madara].js
@@ -63,7 +63,6 @@ var MadaraPlugin = /** @class */ (function () {
this.site = metadata.sourceSite;
this.version = "1.0.0";
this.userAgent = "";
- this.cookieString = "";
this.options = metadata.options;
this.filters = metadata.filters;
}
diff --git a/.js/plugins/english/WuxiaWorldSite[madara].js b/.js/plugins/english/WuxiaWorldSite[madara].js
index 0c8f52e..e4d2307 100644
--- a/.js/plugins/english/WuxiaWorldSite[madara].js
+++ b/.js/plugins/english/WuxiaWorldSite[madara].js
@@ -63,7 +63,6 @@ var MadaraPlugin = /** @class */ (function () {
this.site = metadata.sourceSite;
this.version = "1.0.0";
this.userAgent = "";
- this.cookieString = "";
this.options = metadata.options;
this.filters = metadata.filters;
}
diff --git a/.js/plugins/english/Wuxiacity[readwn].js b/.js/plugins/english/Wuxiacity[readwn].js
index 61d40c3..3e83f84 100644
--- a/.js/plugins/english/Wuxiacity[readwn].js
+++ b/.js/plugins/english/Wuxiacity[readwn].js
@@ -50,7 +50,6 @@ var ReadwnPlugin = /** @class */ (function () {
this.site = metadata.sourceSite;
this.version = "1.0.0";
this.userAgent = "";
- this.cookieString = "";
this.filters = metadata.filters;
}
ReadwnPlugin.prototype.popularNovels = function (pageNo, _a) {
diff --git a/.js/plugins/english/Wuxiap[readwn].js b/.js/plugins/english/Wuxiap[readwn].js
index 3b7e786..7791b1d 100644
--- a/.js/plugins/english/Wuxiap[readwn].js
+++ b/.js/plugins/english/Wuxiap[readwn].js
@@ -50,7 +50,6 @@ var ReadwnPlugin = /** @class */ (function () {
this.site = metadata.sourceSite;
this.version = "1.0.0";
this.userAgent = "";
- this.cookieString = "";
this.filters = metadata.filters;
}
ReadwnPlugin.prototype.popularNovels = function (pageNo, _a) {
diff --git a/.js/plugins/english/ZetroTranslation[madara].js b/.js/plugins/english/ZetroTranslation[madara].js
index 08e00a2..72d9727 100644
--- a/.js/plugins/english/ZetroTranslation[madara].js
+++ b/.js/plugins/english/ZetroTranslation[madara].js
@@ -63,7 +63,6 @@ var MadaraPlugin = /** @class */ (function () {
this.site = metadata.sourceSite;
this.version = "1.0.0";
this.userAgent = "";
- this.cookieString = "";
this.options = metadata.options;
this.filters = metadata.filters;
}
diff --git a/.js/plugins/english/ZinnNovel[madara].js b/.js/plugins/english/ZinnNovel[madara].js
index 600de11..3435000 100644
--- a/.js/plugins/english/ZinnNovel[madara].js
+++ b/.js/plugins/english/ZinnNovel[madara].js
@@ -63,7 +63,6 @@ var MadaraPlugin = /** @class */ (function () {
this.site = metadata.sourceSite;
this.version = "1.0.0";
this.userAgent = "";
- this.cookieString = "";
this.options = metadata.options;
this.filters = metadata.filters;
}
diff --git a/.js/plugins/english/bestlightnovel.js b/.js/plugins/english/bestlightnovel.js
index 633730f..d630f5b 100644
--- a/.js/plugins/english/bestlightnovel.js
+++ b/.js/plugins/english/bestlightnovel.js
@@ -48,7 +48,6 @@ var BLN = /** @class */ (function () {
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 () {
diff --git a/.js/plugins/english/filterTests.js b/.js/plugins/english/filterTests.js
index 758908b..845db14 100644
--- a/.js/plugins/english/filterTests.js
+++ b/.js/plugins/english/filterTests.js
@@ -46,7 +46,6 @@ var FTest = /** @class */ (function () {
this.site = "https://noblemtl.com/";
this.version = "1.0.0";
this.userAgent = "";
- this.cookieString = "";
this.filters = {
picker: {
type: filterInputs_1.FilterTypes.Picker,
diff --git a/.js/plugins/english/freewebnovel.js b/.js/plugins/english/freewebnovel.js
index 7ca1b8d..3b608f2 100644
--- a/.js/plugins/english/freewebnovel.js
+++ b/.js/plugins/english/freewebnovel.js
@@ -46,7 +46,6 @@ var FreeWebNovel = /** @class */ (function () {
this.version = "1.0.0";
this.icon = "src/en/freewebnovel/icon.png";
this.userAgent = "";
- this.cookieString = "";
this.fetchImage = fetch_1.fetchFile;
}
FreeWebNovel.prototype.popularNovels = function (page, _a) {
diff --git a/.js/plugins/english/nobleMTL.js b/.js/plugins/english/nobleMTL.js
index f625bd7..bdf52e9 100644
--- a/.js/plugins/english/nobleMTL.js
+++ b/.js/plugins/english/nobleMTL.js
@@ -47,7 +47,6 @@ var NobleMTL = /** @class */ (function () {
this.site = "https://noblemtl.com/";
this.version = "1.0.0";
this.userAgent = "";
- this.cookieString = "";
this.filters = {
order: {
label: "Sort By",
@@ -196,9 +195,6 @@ var NobleMTL = /** @class */ (function () {
link += "&status=" + filters.status.value;
link += "&order=" + filters.order.value;
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();
})];
@@ -233,9 +229,6 @@ var NobleMTL = /** @class */ (function () {
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();
@@ -311,9 +304,6 @@ var NobleMTL = /** @class */ (function () {
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();
@@ -335,9 +325,6 @@ var NobleMTL = /** @class */ (function () {
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();
diff --git a/.js/plugins/english/pandaMTL.js b/.js/plugins/english/pandaMTL.js
index e8123af..68a7aba 100644
--- a/.js/plugins/english/pandaMTL.js
+++ b/.js/plugins/english/pandaMTL.js
@@ -47,7 +47,6 @@ var PandaMTL = /** @class */ (function () {
this.site = "https://pandamtl.com/";
this.version = "1.0.0";
this.userAgent = "";
- this.cookieString = "";
this.filters = {
order: {
label: "Sort By",
@@ -126,9 +125,6 @@ var PandaMTL = /** @class */ (function () {
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();
})];
@@ -163,9 +159,6 @@ var PandaMTL = /** @class */ (function () {
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();
@@ -234,9 +227,6 @@ var PandaMTL = /** @class */ (function () {
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();
@@ -258,9 +248,6 @@ var PandaMTL = /** @class */ (function () {
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();
diff --git a/.js/plugins/french/LighNovelFR[wpmangastream].js b/.js/plugins/french/LighNovelFR[wpmangastream].js
index 9d31a24..9b12f47 100644
--- a/.js/plugins/french/LighNovelFR[wpmangastream].js
+++ b/.js/plugins/french/LighNovelFR[wpmangastream].js
@@ -47,7 +47,6 @@ var WPmangaStreamPlugin = /** @class */ (function () {
this.site = metadata.sourceSite;
this.version = "1.0.0";
this.userAgent = "";
- this.cookieString = "";
this.options = metadata.options;
}
WPmangaStreamPlugin.prototype.popularNovels = function (page) {
diff --git a/.js/plugins/french/chireads.js b/.js/plugins/french/chireads.js
index a88fbb4..f9705d7 100644
--- a/.js/plugins/french/chireads.js
+++ b/.js/plugins/french/chireads.js
@@ -46,7 +46,6 @@ var ChireadsPlugin = /** @class */ (function () {
this.site = "https://chireads.com";
this.version = "1.0.0";
this.userAgent = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36";
- this.cookieString = "''";
}
ChireadsPlugin.prototype.parseNovels = function (loadedCheerio) {
return [];
diff --git a/.js/plugins/french/noveldeglace.js b/.js/plugins/french/noveldeglace.js
index 1e026a1..4c01288 100644
--- a/.js/plugins/french/noveldeglace.js
+++ b/.js/plugins/french/noveldeglace.js
@@ -47,7 +47,6 @@ var NovelDeGlacePlugin = /** @class */ (function () {
this.site = "https://noveldeglace.com/";
this.version = "1.0.0";
this.userAgent = "''";
- this.cookieString = "''";
}
NovelDeGlacePlugin.prototype.popularNovels = function (page) {
return __awaiter(this, void 0, void 0, function () {
diff --git a/.js/plugins/indonesian/MeioNovel[madara].js b/.js/plugins/indonesian/MeioNovel[madara].js
index a94c653..693ddf6 100644
--- a/.js/plugins/indonesian/MeioNovel[madara].js
+++ b/.js/plugins/indonesian/MeioNovel[madara].js
@@ -63,7 +63,6 @@ var MadaraPlugin = /** @class */ (function () {
this.site = metadata.sourceSite;
this.version = "1.0.0";
this.userAgent = "";
- this.cookieString = "";
this.options = metadata.options;
this.filters = metadata.filters;
}
diff --git a/.js/plugins/indonesian/MoreNovel[madara].js b/.js/plugins/indonesian/MoreNovel[madara].js
index 41e5ba4..0a6b70b 100644
--- a/.js/plugins/indonesian/MoreNovel[madara].js
+++ b/.js/plugins/indonesian/MoreNovel[madara].js
@@ -63,7 +63,6 @@ var MadaraPlugin = /** @class */ (function () {
this.site = metadata.sourceSite;
this.version = "1.0.0";
this.userAgent = "";
- this.cookieString = "";
this.options = metadata.options;
this.filters = metadata.filters;
}
diff --git a/.js/plugins/indonesian/WBNovel[madara].js b/.js/plugins/indonesian/WBNovel[madara].js
index 0720190..b6ef766 100644
--- a/.js/plugins/indonesian/WBNovel[madara].js
+++ b/.js/plugins/indonesian/WBNovel[madara].js
@@ -63,7 +63,6 @@ var MadaraPlugin = /** @class */ (function () {
this.site = metadata.sourceSite;
this.version = "1.0.0";
this.userAgent = "";
- this.cookieString = "";
this.options = metadata.options;
this.filters = metadata.filters;
}
diff --git a/.js/plugins/portuguese/lightnovelbrasil.js b/.js/plugins/portuguese/lightnovelbrasil.js
index 3775095..d97b4aa 100644
--- a/.js/plugins/portuguese/lightnovelbrasil.js
+++ b/.js/plugins/portuguese/lightnovelbrasil.js
@@ -47,7 +47,6 @@ var LightNovelBrasil = /** @class */ (function () {
this.site = "https://lightnovelbrasil.com/";
this.version = "1.0.0";
this.userAgent = "";
- this.cookieString = "";
this.filters = {
order: {
label: "Sort By",
@@ -196,9 +195,6 @@ var LightNovelBrasil = /** @class */ (function () {
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();
})];
@@ -233,9 +229,6 @@ var LightNovelBrasil = /** @class */ (function () {
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();
@@ -312,9 +305,6 @@ var LightNovelBrasil = /** @class */ (function () {
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();
@@ -336,9 +326,6 @@ var LightNovelBrasil = /** @class */ (function () {
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();
diff --git a/.js/plugins/russian/Bookhamster[ifreedom].js b/.js/plugins/russian/Bookhamster[ifreedom].js
index 35fd9bf..de850fa 100644
--- a/.js/plugins/russian/Bookhamster[ifreedom].js
+++ b/.js/plugins/russian/Bookhamster[ifreedom].js
@@ -49,7 +49,6 @@ var IfreedomPlugin = /** @class */ (function () {
this.site = metadata.sourceSite;
this.version = "1.0.0";
this.userAgent = "";
- this.cookieString = "";
this.filters = metadata.filters;
}
IfreedomPlugin.prototype.popularNovels = function (page, _a) {
diff --git a/.js/plugins/russian/Erolate[rulate].js b/.js/plugins/russian/Erolate[rulate].js
index bec8a53..c964bb4 100644
--- a/.js/plugins/russian/Erolate[rulate].js
+++ b/.js/plugins/russian/Erolate[rulate].js
@@ -50,7 +50,6 @@ var RulatePlugin = /** @class */ (function () {
this.site = metadata.sourceSite;
this.version = "1.0.0";
this.userAgent = "";
- this.cookieString = "";
this.filters = metadata.filters;
}
RulatePlugin.prototype.popularNovels = function (pageNo, _a) {
diff --git a/.js/plugins/russian/LitSpace.js b/.js/plugins/russian/LitSpace.js
index f333f5f..62c61ce 100644
--- a/.js/plugins/russian/LitSpace.js
+++ b/.js/plugins/russian/LitSpace.js
@@ -47,7 +47,6 @@ var freedlit = /** @class */ (function () {
this.version = "1.0.0";
this.icon = "src/ru/freedlit/icon.png";
this.userAgent = "";
- this.cookieString = "";
this.fetchImage = fetch_1.fetchFile;
this.filters = {
sort: {
diff --git a/.js/plugins/russian/Rulate[rulate].js b/.js/plugins/russian/Rulate[rulate].js
index 6490867..7d9b143 100644
--- a/.js/plugins/russian/Rulate[rulate].js
+++ b/.js/plugins/russian/Rulate[rulate].js
@@ -50,7 +50,6 @@ var RulatePlugin = /** @class */ (function () {
this.site = metadata.sourceSite;
this.version = "1.0.0";
this.userAgent = "";
- this.cookieString = "";
this.filters = metadata.filters;
}
RulatePlugin.prototype.popularNovels = function (pageNo, _a) {
diff --git a/.js/plugins/russian/authortoday.js b/.js/plugins/russian/authortoday.js
index 24e521e..f17f182 100644
--- a/.js/plugins/russian/authortoday.js
+++ b/.js/plugins/russian/authortoday.js
@@ -55,7 +55,6 @@ var AuthorToday = /** @class */ (function () {
this.site = "https://author.today";
this.version = "1.0.0";
this.userAgent = "";
- this.cookieString = "";
this.fetchImage = fetch_1.fetchFile;
this.filters = {
sort: {
diff --git a/.js/plugins/russian/bookriver.js b/.js/plugins/russian/bookriver.js
index e899700..073a616 100644
--- a/.js/plugins/russian/bookriver.js
+++ b/.js/plugins/russian/bookriver.js
@@ -52,7 +52,6 @@ var Bookriver = /** @class */ (function () {
this.version = "1.0.0";
this.icon = "src/ru/bookriver/icon.png";
this.userAgent = "";
- this.cookieString = "";
this.fetchImage = fetch_1.fetchFile;
this.filters = {
sort: {
diff --git a/.js/plugins/russian/ficbook.js b/.js/plugins/russian/ficbook.js
index aaed01a..05392a7 100644
--- a/.js/plugins/russian/ficbook.js
+++ b/.js/plugins/russian/ficbook.js
@@ -49,7 +49,6 @@ var ficbook = /** @class */ (function () {
this.version = "1.0.0";
this.icon = "src/ru/ficbook/icon.png";
this.userAgent = "";
- this.cookieString = "";
this.fetchImage = fetch_1.fetchFile;
this.filters = {
sort: {
diff --git a/.js/plugins/russian/jaomix.js b/.js/plugins/russian/jaomix.js
index 855eed6..fc68345 100644
--- a/.js/plugins/russian/jaomix.js
+++ b/.js/plugins/russian/jaomix.js
@@ -48,7 +48,6 @@ var Jaomix = /** @class */ (function () {
this.version = "1.0.0";
this.icon = "src/ru/jaomix/icon.png";
this.userAgent = "";
- this.cookieString = "";
this.fetchImage = fetch_1.fetchFile;
this.filters = {
sortby: {
diff --git a/.js/plugins/russian/novelTL.js b/.js/plugins/russian/novelTL.js
index 3fe290c..bd1555f 100644
--- a/.js/plugins/russian/novelTL.js
+++ b/.js/plugins/russian/novelTL.js
@@ -53,7 +53,6 @@ var TL = /** @class */ (function () {
this.version = "1.0.0";
this.icon = "src/ru/noveltl/icon.png";
this.userAgent = "";
- this.cookieString = "";
this.fetchImage = fetch_1.fetchFile;
this.filters = {
tags: {
diff --git a/.js/plugins/russian/ranobehub.js b/.js/plugins/russian/ranobehub.js
index ed46d68..176816a 100644
--- a/.js/plugins/russian/ranobehub.js
+++ b/.js/plugins/russian/ranobehub.js
@@ -52,7 +52,6 @@ var RNBH = /** @class */ (function () {
this.site = "https://ranobehub.org/";
this.icon = "src/ru/ranobehub/icon.png";
this.userAgent = "";
- this.cookieString = "";
this.fetchImage = fetch_1.fetchFile;
this.filters = {
sort: {
diff --git a/.js/plugins/russian/ranobelib.js b/.js/plugins/russian/ranobelib.js
index 5439908..8277a58 100644
--- a/.js/plugins/russian/ranobelib.js
+++ b/.js/plugins/russian/ranobelib.js
@@ -53,7 +53,6 @@ var RLIB = /** @class */ (function () {
this.icon = "src/ru/ranobelib/icon.png";
this.ui = undefined;
this.userAgent = "";
- this.cookieString = "";
this.fetchImage = fetch_1.fetchFile;
this.filters = {
sort: {
diff --git a/.js/plugins/russian/ranoberf.js b/.js/plugins/russian/ranoberf.js
index 05e3c2b..3211a5c 100644
--- a/.js/plugins/russian/ranoberf.js
+++ b/.js/plugins/russian/ranoberf.js
@@ -53,7 +53,6 @@ var RNRF = /** @class */ (function () {
this.version = "1.0.0";
this.icon = "src/ru/ranoberf/icon.png";
this.userAgent = "";
- this.cookieString = "";
this.fetchImage = fetch_1.fetchFile;
this.filters = {
sort: {
diff --git a/.js/plugins/russian/renovels.js b/.js/plugins/russian/renovels.js
index 2ea98f2..22d0d6d 100644
--- a/.js/plugins/russian/renovels.js
+++ b/.js/plugins/russian/renovels.js
@@ -51,7 +51,6 @@ var ReN = /** @class */ (function () {
this.version = "1.0.0";
this.icon = "src/ru/renovels/icon.png";
this.userAgent = "";
- this.cookieString = "";
this.fetchImage = fetch_1.fetchFile;
this.filters = {
sort: {
diff --git a/.js/plugins/russian/СвободныйМирРанобэ[ifreedom].js b/.js/plugins/russian/СвободныйМирРанобэ[ifreedom].js
index eedc31f..185d4f9 100644
--- a/.js/plugins/russian/СвободныйМирРанобэ[ifreedom].js
+++ b/.js/plugins/russian/СвободныйМирРанобэ[ifreedom].js
@@ -49,7 +49,6 @@ var IfreedomPlugin = /** @class */ (function () {
this.site = metadata.sourceSite;
this.version = "1.0.0";
this.userAgent = "";
- this.cookieString = "";
this.filters = metadata.filters;
}
IfreedomPlugin.prototype.popularNovels = function (page, _a) {
diff --git a/.js/plugins/spanish/tunovelaligera.js b/.js/plugins/spanish/tunovelaligera.js
index 6b71268..b8d5ee7 100644
--- a/.js/plugins/spanish/tunovelaligera.js
+++ b/.js/plugins/spanish/tunovelaligera.js
@@ -50,7 +50,6 @@ var TuNovelaLigera = /** @class */ (function () {
this.site = "https://tunovelaligera.com/";
this.version = "1.0.0";
this.userAgent = "";
- this.cookieString = "";
this.filters = {
order: {
value: "?m_orderby=rating",
@@ -137,9 +136,6 @@ var TuNovelaLigera = /** @class */ (function () {
link += "/page/".concat(pageNo);
link += filters.order;
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();
@@ -175,9 +171,6 @@ var TuNovelaLigera = /** @class */ (function () {
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();
@@ -353,9 +346,6 @@ var TuNovelaLigera = /** @class */ (function () {
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();
diff --git a/.js/plugins/turkish/TurkceLightNovels[madara].js b/.js/plugins/turkish/TurkceLightNovels[madara].js
index dae58c6..924899b 100644
--- a/.js/plugins/turkish/TurkceLightNovels[madara].js
+++ b/.js/plugins/turkish/TurkceLightNovels[madara].js
@@ -63,7 +63,6 @@ var MadaraPlugin = /** @class */ (function () {
this.site = metadata.sourceSite;
this.version = "1.0.0";
this.userAgent = "";
- this.cookieString = "";
this.options = metadata.options;
this.filters = metadata.filters;
}
diff --git a/.js/plugins/turkish/WebNovelOku[madara].js b/.js/plugins/turkish/WebNovelOku[madara].js
index cd83255..3d6aaae 100644
--- a/.js/plugins/turkish/WebNovelOku[madara].js
+++ b/.js/plugins/turkish/WebNovelOku[madara].js
@@ -63,7 +63,6 @@ var MadaraPlugin = /** @class */ (function () {
this.site = metadata.sourceSite;
this.version = "1.0.0";
this.userAgent = "";
- this.cookieString = "";
this.options = metadata.options;
this.filters = metadata.filters;
}
diff --git a/.js/plugins/turkish/lshnovel.js b/.js/plugins/turkish/lshnovel.js
index aa8f69f..46fa369 100644
--- a/.js/plugins/turkish/lshnovel.js
+++ b/.js/plugins/turkish/lshnovel.js
@@ -47,7 +47,6 @@ var LSHNovel = /** @class */ (function () {
this.site = "https://lshnovel.com/";
this.version = "1.0.0";
this.userAgent = "";
- this.cookieString = "";
this.filters = {
order: {
value: "popular",
@@ -144,9 +143,6 @@ var LSHNovel = /** @class */ (function () {
link += "&status=" + filters.status;
link += "&order=" + filters.order;
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();
})];
@@ -181,9 +177,6 @@ var LSHNovel = /** @class */ (function () {
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();
@@ -259,9 +252,6 @@ var LSHNovel = /** @class */ (function () {
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();
@@ -283,9 +273,6 @@ var LSHNovel = /** @class */ (function () {
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();
diff --git a/.js/plugins/ukraine/smakolykytl.js b/.js/plugins/ukraine/smakolykytl.js
index 213faec..24ff2df 100644
--- a/.js/plugins/ukraine/smakolykytl.js
+++ b/.js/plugins/ukraine/smakolykytl.js
@@ -50,7 +50,6 @@ var Smakolykytl = /** @class */ (function () {
this.version = "1.0.0";
this.icon = "src/ua/smakolykytl/icon.png";
this.userAgent = "";
- this.cookieString = "";
this.fetchImage = fetch_1.fetchFile;
}
Smakolykytl.prototype.popularNovels = function (pageNo, _a) {
diff --git a/.js/plugins/vietnamese/LNHako.js b/.js/plugins/vietnamese/LNHako.js
index 8653ffb..ca217ce 100644
--- a/.js/plugins/vietnamese/LNHako.js
+++ b/.js/plugins/vietnamese/LNHako.js
@@ -47,7 +47,6 @@ var HakoPlugin = /** @class */ (function () {
this.site = "https://ln.hako.vn";
this.version = "1.0.0";
this.userAgent = "";
- this.cookieString = "";
}
HakoPlugin.prototype.parseNovels = function (loadedCheerio) {
var _this = this;
diff --git a/README.md b/README.md
index 3e38c65..6f42a30 100644
--- a/README.md
+++ b/README.md
@@ -40,10 +40,6 @@ npm install
```
npm start
```
-or
-```
-nodemon
-```
+ Then open http://localhost:3000
diff --git a/index.ts b/index.ts
index f3a9cc3..3d52091 100644
--- a/index.ts
+++ b/index.ts
@@ -6,6 +6,19 @@ import express from "express";
import bodyParser from "body-parser";
import * as pluginApi from "./test_web/api/plugins";
import localizedFormat from "dayjs/plugin/localizedFormat";
+interface GlobalState {
+ UserAgent?: string,
+ Cookie?: string,
+}
+let globalState: GlobalState = {
+}
+
+export const getHeaders = () => {
+ return {
+ 'User-Agent': globalState.UserAgent,
+ 'Cookie': globalState.Cookie,
+ };
+};
const app = express();
const port = 3000;
@@ -13,6 +26,14 @@ const host = "localhost";
const dirname = path.join(__dirname, "..");
+app.use((req, res, next) => {
+ globalState.UserAgent = req.headers["user-agent"];
+ console.log('---------');
+ console.log('default headers: ', globalState);
+ console.log('---------');
+ console.log();
+ next();
+});
app.use(bodyParser.json());
app.use("/static", express.static(path.join(dirname, "test_web", "static")));
app.use("/icons", express.static(path.join(dirname, "icons")));
@@ -20,6 +41,14 @@ app.get("/all_plugins", (req, res) => {
const allPlugins = pluginApi.all_plugins();
res.json(allPlugins);
});
+app.post("/add_cookie", async (req, res) => {
+ globalState.Cookie = req.body['cookie'];
+ console.log('---------');
+ console.log('default headers: ', globalState);
+ console.log('---------');
+ console.log();
+ res.json({});
+});
app.post("/filters", async (req, res) => {
const filters = await pluginApi.getFilter(req.body['pluginRequirePath']);
res.json(filters || []);
diff --git a/libs/fetch.ts b/libs/fetch.ts
index 4249884..3678fa3 100644
--- a/libs/fetch.ts
+++ b/libs/fetch.ts
@@ -1,16 +1,44 @@
-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?: RequestInit,
+ init?: {
+ headers?: Record | Headers;
+ [x: string]: string | Record | undefined | FormData | Headers;
+ },
) {
- const headers = {
- "User-Agent": defaultUserAgentString,
- ...init?.headers,
- };
- console.log(url, { ...init, headers })
- return await fetch(url, { ...init, headers });
+ let defaultHeaders: {
+ 'User-Agent'?: string,
+ 'Cookie'?: string,
+ } = {};
+ try {
+ const getHeaders = (await import('../index.js')).getHeaders;
+ defaultHeaders = getHeaders();
+ }catch{
+ // nothing to do
+ }
+
+ if(init?.headers) {
+ if(init.headers instanceof Headers){
+ if(!init.headers.get('User-Agent') && defaultHeaders['User-Agent']){
+ init.headers.set('User-Agent', defaultHeaders['User-Agent']);
+ }
+ if(defaultHeaders.Cookie) {
+ init.headers.set('Cookie', defaultHeaders.Cookie);
+ }
+ }else{
+ init.headers = {
+ ...defaultHeaders,
+ ...init.headers,
+ };
+ }
+ }else{
+ init = {
+ ...init,
+ headers: defaultHeaders
+ }
+ }
+
+ console.log(url, init);
+ return await fetch(url, init);
}
export const fetchFile = async function (url: string, init?: RequestInit) {
diff --git a/nodemon.json b/nodemon.json
deleted file mode 100644
index f2189c1..0000000
--- a/nodemon.json
+++ /dev/null
@@ -1,5 +0,0 @@
-{
- "ext": "js,mjs,json,ts",
- "ignore": [".js/**"],
- "exec": "tsc && node ./.js/index.js"
-}
\ No newline at end of file
diff --git a/package-lock.json b/package-lock.json
index 7ae610e..32b5060 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -26,8 +26,8 @@
"@types/express": "^4.17.17",
"@types/jquery": "^3.5.28",
"@types/node": "^20.3.1",
- "nodemon": "^2.0.22",
- "pre-commit": "^1.2.2"
+ "pre-commit": "^1.2.2",
+ "tsc-watch": "^6.0.4"
}
},
"node_modules/@cspotcode/source-map-support": {
@@ -216,12 +216,6 @@
"integrity": "sha512-sU5MNKvSFdbT97qLSabU6jxceY9BfYQe9uF+b8E1rdTecpq9ROkkKoiHlblUlhgfaz9bdCByWjAI40Y3mHf1iQ==",
"dev": true
},
- "node_modules/abbrev": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
- "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==",
- "dev": true
- },
"node_modules/accepts": {
"version": "1.3.8",
"resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",
@@ -994,7 +988,7 @@
"version": "3.2.7",
"resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
"integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
- "devOptional": true,
+ "optional": true,
"dependencies": {
"ms": "^2.1.1"
}
@@ -1194,6 +1188,12 @@
"url": "https://github.com/fb55/domutils?sponsor=1"
}
},
+ "node_modules/duplexer": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz",
+ "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==",
+ "dev": true
+ },
"node_modules/duplexer2": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz",
@@ -1334,6 +1334,21 @@
"es5-ext": "~0.10.14"
}
},
+ "node_modules/event-stream": {
+ "version": "3.3.4",
+ "resolved": "https://registry.npmjs.org/event-stream/-/event-stream-3.3.4.tgz",
+ "integrity": "sha512-QHpkERcGsR0T7Qm3HNJSyXKEEj8AHNxkY3PK8TS2KJvQ7NiSHe3DDpwVKKtoYprL/AreyzFBeIkBIWChAqn60g==",
+ "dev": true,
+ "dependencies": {
+ "duplexer": "~0.1.1",
+ "from": "~0",
+ "map-stream": "~0.1.0",
+ "pause-stream": "0.0.11",
+ "split": "0.3",
+ "stream-combiner": "~0.0.4",
+ "through": "~2.3.1"
+ }
+ },
"node_modules/events": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz",
@@ -1548,6 +1563,12 @@
"node": ">= 0.6"
}
},
+ "node_modules/from": {
+ "version": "0.1.7",
+ "resolved": "https://registry.npmjs.org/from/-/from-0.1.7.tgz",
+ "integrity": "sha512-twe20eF1OxVxp/ML/kq2p1uc6KvFK/+vs8WjEbeKmV2He22MKm7YF2ANIt+EOqhJ5L3K/SuuPhk0hWQDjOM23g==",
+ "dev": true
+ },
"node_modules/fs.realpath": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
@@ -1670,15 +1691,6 @@
"node": ">= 0.4.0"
}
},
- "node_modules/has-flag": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
- "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
- "dev": true,
- "engines": {
- "node": ">=4"
- }
- },
"node_modules/has-property-descriptors": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz",
@@ -1866,12 +1878,6 @@
"node": ">= 4"
}
},
- "node_modules/ignore-by-default": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz",
- "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==",
- "dev": true
- },
"node_modules/image-size": {
"version": "0.5.5",
"resolved": "https://registry.npmjs.org/image-size/-/image-size-0.5.5.tgz",
@@ -2178,6 +2184,12 @@
"resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz",
"integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw=="
},
+ "node_modules/map-stream": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.1.0.tgz",
+ "integrity": "sha512-CkYQrPYZfWnu/DAmVCpTSX/xHpKZ80eKh2lAkyA6AJTef6bW+6JpbQZN5rofum7da+SyN1bi5ctTm+lTfcCW3g==",
+ "dev": true
+ },
"node_modules/md5.js": {
"version": "1.3.5",
"resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz",
@@ -2434,48 +2446,11 @@
"resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz",
"integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ=="
},
- "node_modules/nodemon": {
- "version": "2.0.22",
- "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.22.tgz",
- "integrity": "sha512-B8YqaKMmyuCO7BowF1Z1/mkPqLk6cs/l63Ojtd6otKjMx47Dq1utxfRxcavH1I7VSaL8n5BUaoutadnsX3AAVQ==",
- "dev": true,
- "dependencies": {
- "chokidar": "^3.5.2",
- "debug": "^3.2.7",
- "ignore-by-default": "^1.0.1",
- "minimatch": "^3.1.2",
- "pstree.remy": "^1.1.8",
- "semver": "^5.7.1",
- "simple-update-notifier": "^1.0.7",
- "supports-color": "^5.5.0",
- "touch": "^3.1.0",
- "undefsafe": "^2.0.5"
- },
- "bin": {
- "nodemon": "bin/nodemon.js"
- },
- "engines": {
- "node": ">=8.10.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/nodemon"
- }
- },
- "node_modules/nopt": {
- "version": "1.0.10",
- "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz",
- "integrity": "sha512-NWmpvLSqUrgrAC9HCuxEvb+PSloHpqVu+FqcO4eeF2h5qYRhA7ev6KvelyQAKtegUbC6RypJnlEOhd8vloNKYg==",
- "dev": true,
- "dependencies": {
- "abbrev": "1"
- },
- "bin": {
- "nopt": "bin/nopt.js"
- },
- "engines": {
- "node": "*"
- }
+ "node_modules/node-cleanup": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/node-cleanup/-/node-cleanup-2.1.2.tgz",
+ "integrity": "sha512-qN8v/s2PAJwGUtr1/hYTpNKlD6Y9rc4p8KSmJXyGdYGZsDGKXrGThikLFP9OCHFeLeEpQzPwiAtdIvBLqm//Hw==",
+ "dev": true
},
"node_modules/normalize-path": {
"version": "3.0.0",
@@ -2644,6 +2619,15 @@
"node": ">=0.10.0"
}
},
+ "node_modules/path-key": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
+ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/path-parse": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
@@ -2670,6 +2654,15 @@
"node": ">=8"
}
},
+ "node_modules/pause-stream": {
+ "version": "0.0.11",
+ "resolved": "https://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz",
+ "integrity": "sha512-e3FBlXLmN/D1S+zHzanP4E/4Z60oFAa3O051qt1pxa7DEJWKAyil6upYVXCWadEnuoqa4Pkc9oUx9zsxYeRv8A==",
+ "dev": true,
+ "dependencies": {
+ "through": "~2.3"
+ }
+ },
"node_modules/pbkdf2": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz",
@@ -2788,18 +2781,27 @@
"integrity": "sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==",
"optional": true
},
+ "node_modules/ps-tree": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/ps-tree/-/ps-tree-1.2.0.tgz",
+ "integrity": "sha512-0VnamPPYHl4uaU/nSFeZZpR21QAWRz+sRv4iW9+v/GS/J5U5iZB5BNN6J0RMoOvdx2gWM2+ZFMIm58q24e4UYA==",
+ "dev": true,
+ "dependencies": {
+ "event-stream": "=3.3.4"
+ },
+ "bin": {
+ "ps-tree": "bin/ps-tree.js"
+ },
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
"node_modules/pseudomap": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz",
"integrity": "sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==",
"dev": true
},
- "node_modules/pstree.remy": {
- "version": "1.1.8",
- "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz",
- "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==",
- "dev": true
- },
"node_modules/public-encrypt": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz",
@@ -3049,7 +3051,7 @@
"version": "5.7.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
- "devOptional": true,
+ "optional": true,
"bin": {
"semver": "bin/semver"
}
@@ -3204,27 +3206,6 @@
}
]
},
- "node_modules/simple-update-notifier": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-1.1.0.tgz",
- "integrity": "sha512-VpsrsJSUcJEseSbMHkrsrAVSdvVS5I96Qo1QAQ4FxQ9wXFcB+pjj7FB7/us9+GcgfW4ziHtYMc1J0PLczb55mg==",
- "dev": true,
- "dependencies": {
- "semver": "~7.0.0"
- },
- "engines": {
- "node": ">=8.10.0"
- }
- },
- "node_modules/simple-update-notifier/node_modules/semver": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz",
- "integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==",
- "dev": true,
- "bin": {
- "semver": "bin/semver.js"
- }
- },
"node_modules/slash": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
@@ -3260,6 +3241,18 @@
"os-shim": "^0.1.2"
}
},
+ "node_modules/split": {
+ "version": "0.3.3",
+ "resolved": "https://registry.npmjs.org/split/-/split-0.3.3.tgz",
+ "integrity": "sha512-wD2AeVmxXRBoX44wAycgjVpMhvbwdI2aZjCkvfNcH1YqHQvJVa1duWc73OyVGJUc05fhFaTZeQ/PYsrmyH0JVA==",
+ "dev": true,
+ "dependencies": {
+ "through": "2"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
"node_modules/statuses": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
@@ -3290,6 +3283,15 @@
"node": ">= 6"
}
},
+ "node_modules/stream-combiner": {
+ "version": "0.0.4",
+ "resolved": "https://registry.npmjs.org/stream-combiner/-/stream-combiner-0.0.4.tgz",
+ "integrity": "sha512-rT00SPnTVyRsaSz5zgSPma/aHSOic5U1prhYdRy5HS2kTZviFpmDgzilbtsJsxiroqACmayynDN/9VzIbX5DOw==",
+ "dev": true,
+ "dependencies": {
+ "duplexer": "~0.1.1"
+ }
+ },
"node_modules/stream-combiner2": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/stream-combiner2/-/stream-combiner2-1.1.1.tgz",
@@ -3345,6 +3347,15 @@
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
},
+ "node_modules/string-argv": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.2.tgz",
+ "integrity": "sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.6.19"
+ }
+ },
"node_modules/subarg": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/subarg/-/subarg-1.0.0.tgz",
@@ -3353,18 +3364,6 @@
"minimist": "^1.1.0"
}
},
- "node_modules/supports-color": {
- "version": "5.5.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
- "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
- "dev": true,
- "dependencies": {
- "has-flag": "^3.0.0"
- },
- "engines": {
- "node": ">=4"
- }
- },
"node_modules/supports-preserve-symlinks-flag": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
@@ -3437,18 +3436,6 @@
"node": ">=0.6"
}
},
- "node_modules/touch": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz",
- "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==",
- "dev": true,
- "dependencies": {
- "nopt": "~1.0.10"
- },
- "bin": {
- "nodetouch": "bin/nodetouch.js"
- }
- },
"node_modules/ts-node": {
"version": "10.9.1",
"resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz",
@@ -3507,6 +3494,77 @@
"tsc-alias": "dist/bin/index.js"
}
},
+ "node_modules/tsc-watch": {
+ "version": "6.0.4",
+ "resolved": "https://registry.npmjs.org/tsc-watch/-/tsc-watch-6.0.4.tgz",
+ "integrity": "sha512-cHvbvhjO86w2aGlaHgSCeQRl+Aqw6X6XN4sQMPZKF88GoP30O+oTuh5lRIJr5pgFWrRpF1AgXnJJ2DoFEIPHyg==",
+ "dev": true,
+ "dependencies": {
+ "cross-spawn": "^7.0.3",
+ "node-cleanup": "^2.1.2",
+ "ps-tree": "^1.2.0",
+ "string-argv": "^0.3.1"
+ },
+ "bin": {
+ "tsc-watch": "dist/lib/tsc-watch.js"
+ },
+ "engines": {
+ "node": ">=12.12.0"
+ },
+ "peerDependencies": {
+ "typescript": "*"
+ }
+ },
+ "node_modules/tsc-watch/node_modules/cross-spawn": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
+ "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
+ "dev": true,
+ "dependencies": {
+ "path-key": "^3.1.0",
+ "shebang-command": "^2.0.0",
+ "which": "^2.0.1"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/tsc-watch/node_modules/shebang-command": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
+ "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
+ "dev": true,
+ "dependencies": {
+ "shebang-regex": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/tsc-watch/node_modules/shebang-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
+ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/tsc-watch/node_modules/which": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+ "dev": true,
+ "dependencies": {
+ "isexe": "^2.0.0"
+ },
+ "bin": {
+ "node-which": "bin/node-which"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
"node_modules/tslib": {
"version": "2.6.2",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
@@ -3574,12 +3632,6 @@
"undeclared-identifiers": "bin.js"
}
},
- "node_modules/undefsafe": {
- "version": "2.0.5",
- "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz",
- "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==",
- "dev": true
- },
"node_modules/unpipe": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
@@ -3884,12 +3936,6 @@
"integrity": "sha512-sU5MNKvSFdbT97qLSabU6jxceY9BfYQe9uF+b8E1rdTecpq9ROkkKoiHlblUlhgfaz9bdCByWjAI40Y3mHf1iQ==",
"dev": true
},
- "abbrev": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
- "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==",
- "dev": true
- },
"accepts": {
"version": "1.3.8",
"resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",
@@ -4543,7 +4589,7 @@
"version": "3.2.7",
"resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
"integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
- "devOptional": true,
+ "optional": true,
"requires": {
"ms": "^2.1.1"
}
@@ -4686,6 +4732,12 @@
"domhandler": "^5.0.3"
}
},
+ "duplexer": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz",
+ "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==",
+ "dev": true
+ },
"duplexer2": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz",
@@ -4803,6 +4855,21 @@
"es5-ext": "~0.10.14"
}
},
+ "event-stream": {
+ "version": "3.3.4",
+ "resolved": "https://registry.npmjs.org/event-stream/-/event-stream-3.3.4.tgz",
+ "integrity": "sha512-QHpkERcGsR0T7Qm3HNJSyXKEEj8AHNxkY3PK8TS2KJvQ7NiSHe3DDpwVKKtoYprL/AreyzFBeIkBIWChAqn60g==",
+ "dev": true,
+ "requires": {
+ "duplexer": "~0.1.1",
+ "from": "~0",
+ "map-stream": "~0.1.0",
+ "pause-stream": "0.0.11",
+ "split": "0.3",
+ "stream-combiner": "~0.0.4",
+ "through": "~2.3.1"
+ }
+ },
"events": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz",
@@ -4995,6 +5062,12 @@
"resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
"integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q=="
},
+ "from": {
+ "version": "0.1.7",
+ "resolved": "https://registry.npmjs.org/from/-/from-0.1.7.tgz",
+ "integrity": "sha512-twe20eF1OxVxp/ML/kq2p1uc6KvFK/+vs8WjEbeKmV2He22MKm7YF2ANIt+EOqhJ5L3K/SuuPhk0hWQDjOM23g==",
+ "dev": true
+ },
"fs.realpath": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
@@ -5083,12 +5156,6 @@
"function-bind": "^1.1.1"
}
},
- "has-flag": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
- "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
- "dev": true
- },
"has-property-descriptors": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz",
@@ -5215,12 +5282,6 @@
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz",
"integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ=="
},
- "ignore-by-default": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz",
- "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==",
- "dev": true
- },
"image-size": {
"version": "0.5.5",
"resolved": "https://registry.npmjs.org/image-size/-/image-size-0.5.5.tgz",
@@ -5452,6 +5513,12 @@
"resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz",
"integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw=="
},
+ "map-stream": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.1.0.tgz",
+ "integrity": "sha512-CkYQrPYZfWnu/DAmVCpTSX/xHpKZ80eKh2lAkyA6AJTef6bW+6JpbQZN5rofum7da+SyN1bi5ctTm+lTfcCW3g==",
+ "dev": true
+ },
"md5.js": {
"version": "1.3.5",
"resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz",
@@ -5642,32 +5709,11 @@
"resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz",
"integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ=="
},
- "nodemon": {
- "version": "2.0.22",
- "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.22.tgz",
- "integrity": "sha512-B8YqaKMmyuCO7BowF1Z1/mkPqLk6cs/l63Ojtd6otKjMx47Dq1utxfRxcavH1I7VSaL8n5BUaoutadnsX3AAVQ==",
- "dev": true,
- "requires": {
- "chokidar": "^3.5.2",
- "debug": "^3.2.7",
- "ignore-by-default": "^1.0.1",
- "minimatch": "^3.1.2",
- "pstree.remy": "^1.1.8",
- "semver": "^5.7.1",
- "simple-update-notifier": "^1.0.7",
- "supports-color": "^5.5.0",
- "touch": "^3.1.0",
- "undefsafe": "^2.0.5"
- }
- },
- "nopt": {
- "version": "1.0.10",
- "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz",
- "integrity": "sha512-NWmpvLSqUrgrAC9HCuxEvb+PSloHpqVu+FqcO4eeF2h5qYRhA7ev6KvelyQAKtegUbC6RypJnlEOhd8vloNKYg==",
- "dev": true,
- "requires": {
- "abbrev": "1"
- }
+ "node-cleanup": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/node-cleanup/-/node-cleanup-2.1.2.tgz",
+ "integrity": "sha512-qN8v/s2PAJwGUtr1/hYTpNKlD6Y9rc4p8KSmJXyGdYGZsDGKXrGThikLFP9OCHFeLeEpQzPwiAtdIvBLqm//Hw==",
+ "dev": true
},
"normalize-path": {
"version": "3.0.0",
@@ -5797,6 +5843,12 @@
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
"integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg=="
},
+ "path-key": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
+ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
+ "dev": true
+ },
"path-parse": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
@@ -5817,6 +5869,15 @@
"resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
"integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw=="
},
+ "pause-stream": {
+ "version": "0.0.11",
+ "resolved": "https://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz",
+ "integrity": "sha512-e3FBlXLmN/D1S+zHzanP4E/4Z60oFAa3O051qt1pxa7DEJWKAyil6upYVXCWadEnuoqa4Pkc9oUx9zsxYeRv8A==",
+ "dev": true,
+ "requires": {
+ "through": "~2.3"
+ }
+ },
"pbkdf2": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz",
@@ -5899,18 +5960,21 @@
"integrity": "sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==",
"optional": true
},
+ "ps-tree": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/ps-tree/-/ps-tree-1.2.0.tgz",
+ "integrity": "sha512-0VnamPPYHl4uaU/nSFeZZpR21QAWRz+sRv4iW9+v/GS/J5U5iZB5BNN6J0RMoOvdx2gWM2+ZFMIm58q24e4UYA==",
+ "dev": true,
+ "requires": {
+ "event-stream": "=3.3.4"
+ }
+ },
"pseudomap": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz",
"integrity": "sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==",
"dev": true
},
- "pstree.remy": {
- "version": "1.1.8",
- "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz",
- "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==",
- "dev": true
- },
"public-encrypt": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz",
@@ -6094,7 +6158,7 @@
"version": "5.7.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
- "devOptional": true
+ "optional": true
},
"send": {
"version": "0.18.0",
@@ -6212,23 +6276,6 @@
"resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz",
"integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q=="
},
- "simple-update-notifier": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-1.1.0.tgz",
- "integrity": "sha512-VpsrsJSUcJEseSbMHkrsrAVSdvVS5I96Qo1QAQ4FxQ9wXFcB+pjj7FB7/us9+GcgfW4ziHtYMc1J0PLczb55mg==",
- "dev": true,
- "requires": {
- "semver": "~7.0.0"
- },
- "dependencies": {
- "semver": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz",
- "integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==",
- "dev": true
- }
- }
- },
"slash": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
@@ -6254,6 +6301,15 @@
"os-shim": "^0.1.2"
}
},
+ "split": {
+ "version": "0.3.3",
+ "resolved": "https://registry.npmjs.org/split/-/split-0.3.3.tgz",
+ "integrity": "sha512-wD2AeVmxXRBoX44wAycgjVpMhvbwdI2aZjCkvfNcH1YqHQvJVa1duWc73OyVGJUc05fhFaTZeQ/PYsrmyH0JVA==",
+ "dev": true,
+ "requires": {
+ "through": "2"
+ }
+ },
"statuses": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
@@ -6280,6 +6336,15 @@
}
}
},
+ "stream-combiner": {
+ "version": "0.0.4",
+ "resolved": "https://registry.npmjs.org/stream-combiner/-/stream-combiner-0.0.4.tgz",
+ "integrity": "sha512-rT00SPnTVyRsaSz5zgSPma/aHSOic5U1prhYdRy5HS2kTZviFpmDgzilbtsJsxiroqACmayynDN/9VzIbX5DOw==",
+ "dev": true,
+ "requires": {
+ "duplexer": "~0.1.1"
+ }
+ },
"stream-combiner2": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/stream-combiner2/-/stream-combiner2-1.1.1.tgz",
@@ -6336,6 +6401,12 @@
}
}
},
+ "string-argv": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.2.tgz",
+ "integrity": "sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==",
+ "dev": true
+ },
"subarg": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/subarg/-/subarg-1.0.0.tgz",
@@ -6344,15 +6415,6 @@
"minimist": "^1.1.0"
}
},
- "supports-color": {
- "version": "5.5.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
- "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
- "dev": true,
- "requires": {
- "has-flag": "^3.0.0"
- }
- },
"supports-preserve-symlinks-flag": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
@@ -6410,15 +6472,6 @@
"resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
"integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA=="
},
- "touch": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz",
- "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==",
- "dev": true,
- "requires": {
- "nopt": "~1.0.10"
- }
- },
"ts-node": {
"version": "10.9.1",
"resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz",
@@ -6452,6 +6505,55 @@
"plimit-lit": "^1.2.6"
}
},
+ "tsc-watch": {
+ "version": "6.0.4",
+ "resolved": "https://registry.npmjs.org/tsc-watch/-/tsc-watch-6.0.4.tgz",
+ "integrity": "sha512-cHvbvhjO86w2aGlaHgSCeQRl+Aqw6X6XN4sQMPZKF88GoP30O+oTuh5lRIJr5pgFWrRpF1AgXnJJ2DoFEIPHyg==",
+ "dev": true,
+ "requires": {
+ "cross-spawn": "^7.0.3",
+ "node-cleanup": "^2.1.2",
+ "ps-tree": "^1.2.0",
+ "string-argv": "^0.3.1"
+ },
+ "dependencies": {
+ "cross-spawn": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
+ "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
+ "dev": true,
+ "requires": {
+ "path-key": "^3.1.0",
+ "shebang-command": "^2.0.0",
+ "which": "^2.0.1"
+ }
+ },
+ "shebang-command": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
+ "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
+ "dev": true,
+ "requires": {
+ "shebang-regex": "^3.0.0"
+ }
+ },
+ "shebang-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
+ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
+ "dev": true
+ },
+ "which": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+ "dev": true,
+ "requires": {
+ "isexe": "^2.0.0"
+ }
+ }
+ }
+ },
"tslib": {
"version": "2.6.2",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
@@ -6503,12 +6605,6 @@
"xtend": "^4.0.1"
}
},
- "undefsafe": {
- "version": "2.0.5",
- "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz",
- "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==",
- "dev": true
- },
"unpipe": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
diff --git a/package.json b/package.json
index 93f5f7e..7b710e9 100644
--- a/package.json
+++ b/package.json
@@ -1,17 +1,17 @@
{
"name": "lnreader-plugins",
"version": "1.0.0",
- "description": "",
+ "description": "Plugins repo for LNReader",
"main": "index.js",
"scripts": {
- "start": "nodemon",
+ "start": "tsc-watch --onSuccess \"node ./.js/index.js\"",
"test": "exit 0",
- "json": "tsc && node ./.js/scripts/json_plugins.js && git add plugins && git add .dist && git add .js/plugins",
+ "json": "tsc && rm ./.js/index.js && node ./.js/scripts/json_plugins.js && git add plugins && git add .dist && git add .js/plugins",
"generate": "ts-node ./scripts/multisrc/generate.ts && tsc",
"clearMulti": "ts-node ./scripts/clearMultisrc.ts",
"less": "npx less ./test_web/static/css/index.less ./test_web/static/css/index.css"
},
- "author": "",
+ "author": "LNReader",
"license": "MIT",
"dependencies": {
"body-parser": "^1.20.2",
@@ -38,8 +38,8 @@
"@types/express": "^4.17.17",
"@types/jquery": "^3.5.28",
"@types/node": "^20.3.1",
- "nodemon": "^2.0.22",
- "pre-commit": "^1.2.2"
+ "pre-commit": "^1.2.2",
+ "tsc-watch": "^6.0.4"
},
"pre-commit": [
"json"
diff --git a/plugins/arabic/kolnovel.ts b/plugins/arabic/kolnovel.ts
index d73b78a..7dd851d 100644
--- a/plugins/arabic/kolnovel.ts
+++ b/plugins/arabic/kolnovel.ts
@@ -1,328 +1,315 @@
-import { load as parseHTML } from "cheerio";
-import { fetchApi, fetchFile } from "@libs/fetch";
-import { FilterTypes, Filters } from "@libs/filterInputs";
-import { Plugin } from "@typings/plugin";
-
-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.genres.value.length)
- link += filters.genres.value.map((i) => `&genre[]=${i}`).join("");
- if (filters.type.value.length)
- link += filters.type.value.map((i) => `&lang[]=${i}`).join("");
-
- link += "&status=" + (filters?.status ? filters.status : "");
-
- 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;
- }
- async parseNovelAndChapters(novelUrl: string): Promise {
- const url = novelUrl;
- 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: Plugin.SourceNovel = {
- 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: Plugin.ChapterItem[] = [];
-
- 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;
- }
- 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);
-
- 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());
-
- 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();
-
- 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;
-
- novels.push({
- name: novelName,
- url: novelUrl,
- cover: novelCover,
- });
- });
-
- return novels;
- }
- async fetchImage(url: string): Promise {
- return await fetchFile(url);
- }
- filters = {
- order: {
- label: "ترتيب حسب",
- options: [
- { label: "الإعداد الأولي", value: "" },
-
- { label: "A-Z", value: "title" },
-
- { label: "Z-A", value: "titlereverse" },
-
- { label: "أخر التحديثات", value: "update" },
-
- { label: "أخر ما تم إضافته", value: "latest" },
-
- { label: "الرائجة", value: "popular" },
- ],
- value: "",
- type: FilterTypes.Picker,
- },
- status: {
- value: "",
- label: "الحالة",
- options: [
- { label: "All", value: "" },
-
- { label: "Ongoing", value: "ongoing" },
-
- { label: "Hiatus", value: "hiatus" },
-
- { label: "Completed", value: "completed" },
- ],
- type: FilterTypes.Picker,
- },
- type: {
- value: [],
- label: "النوع",
- options: [
- { label: "إنجليزية", value: "english" },
-
- { label: "روايةلايت", value: "light-novel" },
-
- { label: "روايةويب", value: "web-novel" },
-
- { label: "صينية", value: "chinese" },
-
- { label: "عربية", value: "arabic" },
-
- { label: "كورية", value: "korean" },
-
- { label: "يابانية", value: "japanese" },
- ],
- type: FilterTypes.CheckboxGroup,
- },
- genres: {
- value: [],
- label: "تصنيف",
- options: [
- { 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" },
- ],
- type: FilterTypes.CheckboxGroup,
- },
- } satisfies Filters;
-}
-
-export default new KolNovel();
+import { load as parseHTML } from "cheerio";
+import { fetchApi, fetchFile } from "@libs/fetch";
+import { FilterTypes, Filters } from "@libs/filterInputs";
+import { Plugin } from "@typings/plugin";
+
+class KolNovel implements Plugin.PluginBase {
+ id = "kolnovel";
+ name = "KolNovel";
+ icon = "multisrc/wpmangastream/icons/kolnovel.png";
+ site = "https://kolnovel.lol/";
+ version = "1.0.0";
+ userAgent = "";
+ async popularNovels(
+ pageNo: number,
+ { filters }: Plugin.PopularNovelsOptions
+ ): Promise {
+ let link = `${this.site}series/?page=${pageNo}`;
+
+ if (filters.genres.value.length)
+ link += filters.genres.value.map((i) => `&genre[]=${i}`).join("");
+ if (filters.type.value.length)
+ link += filters.type.value.map((i) => `&lang[]=${i}`).join("");
+
+ link += "&status=" + (filters?.status ? filters.status : "");
+
+ link += "&order=" + (filters?.order ? filters.order : "popular");
+ const headers = new Headers();
+ 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;
+ }
+ async parseNovelAndChapters(novelUrl: string): Promise {
+ const url = novelUrl;
+ const headers = new Headers();
+ const result = await fetch(url, { headers });
+ const body = await result.text();
+
+ let loadedCheerio = parseHTML(body);
+
+ const novel: Plugin.SourceNovel = {
+ 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: Plugin.ChapterItem[] = [];
+
+ 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;
+ }
+ async parseChapter(chapterUrl: string): Promise {
+ const headers = new Headers();
+ const result = await fetch(chapterUrl, { headers });
+ const body = await result.text();
+
+ const loadedCheerio = parseHTML(body);
+
+ 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());
+
+ 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();
+ const result = await fetchApi(url, { headers });
+ const body = await 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;
+
+ novels.push({
+ name: novelName,
+ url: novelUrl,
+ cover: novelCover,
+ });
+ });
+
+ return novels;
+ }
+ async fetchImage(url: string): Promise {
+ return await fetchFile(url);
+ }
+ filters = {
+ order: {
+ label: "ترتيب حسب",
+ options: [
+ { label: "الإعداد الأولي", value: "" },
+
+ { label: "A-Z", value: "title" },
+
+ { label: "Z-A", value: "titlereverse" },
+
+ { label: "أخر التحديثات", value: "update" },
+
+ { label: "أخر ما تم إضافته", value: "latest" },
+
+ { label: "الرائجة", value: "popular" },
+ ],
+ value: "",
+ type: FilterTypes.Picker,
+ },
+ status: {
+ value: "",
+ label: "الحالة",
+ options: [
+ { label: "All", value: "" },
+
+ { label: "Ongoing", value: "ongoing" },
+
+ { label: "Hiatus", value: "hiatus" },
+
+ { label: "Completed", value: "completed" },
+ ],
+ type: FilterTypes.Picker,
+ },
+ type: {
+ value: [],
+ label: "النوع",
+ options: [
+ { label: "إنجليزية", value: "english" },
+
+ { label: "روايةلايت", value: "light-novel" },
+
+ { label: "روايةويب", value: "web-novel" },
+
+ { label: "صينية", value: "chinese" },
+
+ { label: "عربية", value: "arabic" },
+
+ { label: "كورية", value: "korean" },
+
+ { label: "يابانية", value: "japanese" },
+ ],
+ type: FilterTypes.CheckboxGroup,
+ },
+ genres: {
+ value: [],
+ label: "تصنيف",
+ options: [
+ { 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" },
+ ],
+ type: FilterTypes.CheckboxGroup,
+ },
+ } satisfies Filters;
+}
+
+export default new KolNovel();
diff --git a/plugins/chinese/linovelib.ts b/plugins/chinese/linovelib.ts
index 01b6d07..667267a 100644
--- a/plugins/chinese/linovelib.ts
+++ b/plugins/chinese/linovelib.ts
@@ -1,587 +1,574 @@
-import { CheerioAPI, load as parseHTML } from "cheerio";
-import { fetchApi, fetchFile } from "@libs/fetch";
-import { FilterTypes, Filters } 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;
-
- 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 = {
- sort: {
- label: "Sort By",
- value: "monthvisit",
- options: [
- { 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" },
- ],
- type: FilterTypes.Picker,
- },
- } satisfies Filters;
-}
-
-export default new Linovelib();
+import { CheerioAPI, load as parseHTML } from "cheerio";
+import { fetchApi, fetchFile } from "@libs/fetch";
+import { FilterTypes, Filters } 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 = "";
+ async popularNovels(
+ pageNo: number,
+ { filters }: Plugin.PopularNovelsOptions
+ ): Promise {
+ let link = `${this.site}/top/`;
+
+ link += filters.sort;
+
+ link += `/${pageNo}.html`;
+
+ const headers = new Headers();
+ 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();
+ 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();
+ 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();
+ 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 = {
+ sort: {
+ label: "Sort By",
+ value: "monthvisit",
+ options: [
+ { 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" },
+ ],
+ type: FilterTypes.Picker,
+ },
+ } satisfies Filters;
+}
+
+export default new Linovelib();
diff --git a/plugins/english/bestlightnovel.ts b/plugins/english/bestlightnovel.ts
index abe9c21..9da3f1c 100644
--- a/plugins/english/bestlightnovel.ts
+++ b/plugins/english/bestlightnovel.ts
@@ -1,181 +1,180 @@
-import { load as cheerioload } from "cheerio";
-import { Plugin } from "@typings/plugin";
-import { defaultCover } from "@libs/defaultCover";
-import { fetchFile } from "@libs/fetch";
-import { NovelStatus } from "@libs/novelStatus";
-
-class BLN implements Plugin.PluginBase {
- id = "BLN.com";
- name = "BestLightNovel";
- icon = "src/en/bestlightnovel/icon.png";
- site = "https://bestlightnovel.com/";
- 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;
-
- 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 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,
- url: novelUrl,
- cover: novelCover,
- };
-
- novels.push(novel);
- });
-
- return novels;
- }
- async parseNovelAndChapters(novelUrl: string): Promise {
- const url = novelUrl;
-
- const result = await fetch(url);
- if (!result.ok) {
- console.error(await result.text());
- // TODO: Cloudflare protection
- return { url, chapters: [] };
- }
- const body = await result.text();
-
- let loadedCheerio = cheerioload(body);
-
- let novel: Plugin.SourceNovel = {
- url,
- name: "",
- cover: "",
- author: "",
- status: NovelStatus.Unknown,
- genres: "",
- summary: "",
- chapters: [],
- };
-
- novel.name = loadedCheerio(".truyen_info_right h1").text().trim();
- novel.cover =
- loadedCheerio(".info_image img").attr("src") || defaultCover;
- novel.summary = loadedCheerio("#noidungm").text()?.trim();
- novel.author = 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()
- ?.trim();
-
- let status = 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()
- ?.trim();
-
- novel.status =
- status === "ONGOING"
- ? NovelStatus.Ongoing
- : status === "COMPLETED"
- ? NovelStatus.Completed
- : NovelStatus.Unknown;
-
- let novelChapters: Plugin.ChapterItem[] = [];
-
- 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;
- }
- async parseChapter(chapterUrl: string): Promise {
- const url = chapterUrl;
-
- const result = await fetch(url);
- const body = await result.text();
-
- let loadedCheerio = cheerioload(body);
-
- const chapterText = loadedCheerio("#vung_doc").html() || "";
-
- return chapterText;
- }
- async searchNovels(
- searchTerm: string,
- pageNo?: number | undefined
- ): Promise {
- const url = `${this.site}search_novels/${searchTerm}`;
-
- 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();
+import { load as cheerioload } from "cheerio";
+import { Plugin } from "@typings/plugin";
+import { defaultCover } from "@libs/defaultCover";
+import { fetchFile } from "@libs/fetch";
+import { NovelStatus } from "@libs/novelStatus";
+
+class BLN implements Plugin.PluginBase {
+ id = "BLN.com";
+ name = "BestLightNovel";
+ icon = "src/en/bestlightnovel/icon.png";
+ site = "https://bestlightnovel.com/";
+ filter?: undefined;
+ version = "1.0.0";
+ userAgent = "";
+ async popularNovels(
+ pageNo: number,
+ options: Plugin.PopularNovelsOptions
+ ): Promise {
+ const url =
+ this.site +
+ "novel_list?type=topview&category=all&state=all&page=1" +
+ pageNo;
+
+ 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 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,
+ url: novelUrl,
+ cover: novelCover,
+ };
+
+ novels.push(novel);
+ });
+
+ return novels;
+ }
+ async parseNovelAndChapters(novelUrl: string): Promise {
+ const url = novelUrl;
+
+ const result = await fetch(url);
+ if (!result.ok) {
+ console.error(await result.text());
+ // TODO: Cloudflare protection
+ return { url, chapters: [] };
+ }
+ const body = await result.text();
+
+ let loadedCheerio = cheerioload(body);
+
+ let novel: Plugin.SourceNovel = {
+ url,
+ name: "",
+ cover: "",
+ author: "",
+ status: NovelStatus.Unknown,
+ genres: "",
+ summary: "",
+ chapters: [],
+ };
+
+ novel.name = loadedCheerio(".truyen_info_right h1").text().trim();
+ novel.cover =
+ loadedCheerio(".info_image img").attr("src") || defaultCover;
+ novel.summary = loadedCheerio("#noidungm").text()?.trim();
+ novel.author = 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()
+ ?.trim();
+
+ let status = 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()
+ ?.trim();
+
+ novel.status =
+ status === "ONGOING"
+ ? NovelStatus.Ongoing
+ : status === "COMPLETED"
+ ? NovelStatus.Completed
+ : NovelStatus.Unknown;
+
+ let novelChapters: Plugin.ChapterItem[] = [];
+
+ 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;
+ }
+ async parseChapter(chapterUrl: string): Promise {
+ const url = chapterUrl;
+
+ const result = await fetch(url);
+ const body = await result.text();
+
+ let loadedCheerio = cheerioload(body);
+
+ const chapterText = loadedCheerio("#vung_doc").html() || "";
+
+ return chapterText;
+ }
+ async searchNovels(
+ searchTerm: string,
+ pageNo?: number | undefined
+ ): Promise {
+ const url = `${this.site}search_novels/${searchTerm}`;
+
+ 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/filterTests.ts b/plugins/english/filterTests.ts
index 480a202..95f4b10 100644
--- a/plugins/english/filterTests.ts
+++ b/plugins/english/filterTests.ts
@@ -9,8 +9,7 @@ class FTest implements Plugin.PluginBase {
icon = "src/en/noblemtl/icon.png";
site = "https://noblemtl.com/";
version = "1.0.0";
- userAgent = "";
- cookieString = "";
+ userAgent = "";
async popularNovels(
pageNo: number,
{ filters }: Plugin.PopularNovelsOptions
diff --git a/plugins/english/freewebnovel.ts b/plugins/english/freewebnovel.ts
index ebb6b52..4008ea8 100644
--- a/plugins/english/freewebnovel.ts
+++ b/plugins/english/freewebnovel.ts
@@ -1,104 +1,103 @@
-import { Plugin } from "@typings/plugin";
-import { fetchApi, fetchFile } from "@libs/fetch";
-import { NovelStatus } from "@libs/novelStatus";
-import { load as parseHTML } from "cheerio";
-
-class FreeWebNovel implements Plugin.PluginBase {
- id = "FWN.com";
- name = "Web NOVEL";
- site = "https://freewebnovel.com";
- version = "1.0.0";
- icon = "src/en/freewebnovel/icon.png";
- userAgent = "";
- cookieString = "";
-
- async popularNovels(
- page: number,
- { showLatestNovels }: Plugin.PopularNovelsOptions,
- ): Promise {
- const sort = showLatestNovels
- ? "/latest-release-novels/"
- : "/completed-novels/";
-
- const body = await fetchApi(this.site + sort + page).then((res) => res.text());
- const loadedCheerio = parseHTML(body);
-
- const novels: Plugin.NovelItem[] = loadedCheerio(".li-row")
- .map((index, element) => ({
- name: loadedCheerio(element).find(".tit").text(),
- cover: loadedCheerio(element).find("img").attr("src"),
- url: this.site + loadedCheerio(element).find("h3 > a").attr("href"),
- }))
- .get();
-
- return novels;
- }
-
- async parseNovelAndChapters(url: string): Promise {
- const body = await fetchApi(url).then((res) => res.text());
- const loadedCheerio = parseHTML(body);
-
- const novel: Plugin.SourceNovel = { 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, "");
-
- novel.summary = loadedCheerio(".inner").text().trim();
-
- const chapters: Plugin.ChapterItem[] = loadedCheerio("#idData > li > a")
- .map((index, element) => ({
- name: loadedCheerio(element).attr("title") || "Chapter " + index,
- releaseTime: null,
- url: this.site + loadedCheerio(element).attr("href"),
- }))
- .get();
-
- novel.chapters = chapters;
- return novel;
- }
-
- async parseChapter(chapterUrl: string): Promise {
- const body = await fetchApi(chapterUrl).then((res) => res.text());
- const loadedCheerio = parseHTML(body);
-
- const chapterText = loadedCheerio("div.txt").html() || "";
- return chapterText;
- }
-
- async searchNovels(
- searchkey: string,
- ): Promise {
- const body = await fetchApi(this.site + "/search/", {
- method: "POST",
- body: JSON.stringify({ searchkey }),
- }).then((res) => res.text());
-
- const loadedCheerio = parseHTML(body);
- const novels: Plugin.NovelItem[] = loadedCheerio(".li-row > .li > .con")
- .map((index, element) => ({
- name: loadedCheerio(element).find(".tit").text(),
- cover: loadedCheerio(element).find(".pic > a > img").attr("data-cfsrc"),
- url: this.site + loadedCheerio(element).find("h3 > a").attr("href"),
- }))
- .get();
-
- return novels;
- }
-
- fetchImage = fetchFile;
-}
-
-export default new FreeWebNovel();
+import { Plugin } from "@typings/plugin";
+import { fetchApi, fetchFile } from "@libs/fetch";
+import { NovelStatus } from "@libs/novelStatus";
+import { load as parseHTML } from "cheerio";
+
+class FreeWebNovel implements Plugin.PluginBase {
+ id = "FWN.com";
+ name = "Web NOVEL";
+ site = "https://freewebnovel.com";
+ version = "1.0.0";
+ icon = "src/en/freewebnovel/icon.png";
+ userAgent = "";
+
+ async popularNovels(
+ page: number,
+ { showLatestNovels }: Plugin.PopularNovelsOptions,
+ ): Promise {
+ const sort = showLatestNovels
+ ? "/latest-release-novels/"
+ : "/completed-novels/";
+
+ const body = await fetchApi(this.site + sort + page).then((res) => res.text());
+ const loadedCheerio = parseHTML(body);
+
+ const novels: Plugin.NovelItem[] = loadedCheerio(".li-row")
+ .map((index, element) => ({
+ name: loadedCheerio(element).find(".tit").text(),
+ cover: loadedCheerio(element).find("img").attr("src"),
+ url: this.site + loadedCheerio(element).find("h3 > a").attr("href"),
+ }))
+ .get();
+
+ return novels;
+ }
+
+ async parseNovelAndChapters(url: string): Promise {
+ const body = await fetchApi(url).then((res) => res.text());
+ const loadedCheerio = parseHTML(body);
+
+ const novel: Plugin.SourceNovel = { 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, "");
+
+ novel.summary = loadedCheerio(".inner").text().trim();
+
+ const chapters: Plugin.ChapterItem[] = loadedCheerio("#idData > li > a")
+ .map((index, element) => ({
+ name: loadedCheerio(element).attr("title") || "Chapter " + index,
+ releaseTime: null,
+ url: this.site + loadedCheerio(element).attr("href"),
+ }))
+ .get();
+
+ novel.chapters = chapters;
+ return novel;
+ }
+
+ async parseChapter(chapterUrl: string): Promise {
+ const body = await fetchApi(chapterUrl).then((res) => res.text());
+ const loadedCheerio = parseHTML(body);
+
+ const chapterText = loadedCheerio("div.txt").html() || "";
+ return chapterText;
+ }
+
+ async searchNovels(
+ searchkey: string,
+ ): Promise {
+ const body = await fetchApi(this.site + "/search/", {
+ method: "POST",
+ body: JSON.stringify({ searchkey }),
+ }).then((res) => res.text());
+
+ const loadedCheerio = parseHTML(body);
+ const novels: Plugin.NovelItem[] = loadedCheerio(".li-row > .li > .con")
+ .map((index, element) => ({
+ name: loadedCheerio(element).find(".tit").text(),
+ cover: loadedCheerio(element).find(".pic > a > img").attr("data-cfsrc"),
+ url: this.site + loadedCheerio(element).find("h3 > a").attr("href"),
+ }))
+ .get();
+
+ return novels;
+ }
+
+ fetchImage = fetchFile;
+}
+
+export default new FreeWebNovel();
diff --git a/plugins/english/nobleMTL.ts b/plugins/english/nobleMTL.ts
index 90d3a86..51e57c2 100644
--- a/plugins/english/nobleMTL.ts
+++ b/plugins/english/nobleMTL.ts
@@ -1,428 +1,415 @@
-import { load as parseHTML } from "cheerio";
-import { fetchApi, fetchFile } from "@libs/fetch";
-import { FilterTypes, Filters } from "@libs/filterInputs";
-import { Plugin } from "@typings/plugin";
-
-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.genres.value.length)
- link += filters.genres.value.map((i) => `&genre[]=${i}`).join("");
-
- if (filters.type.value.length)
- link += filters.type.value.map((i) => `&lang[]=${i}`).join("");
-
- link += "&status=" + filters.status.value;
-
- link += "&order=" + filters.order.value;
-
- 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.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;
- }
-
- 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(".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 "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();
-
- let chapter: Plugin.ChapterItem[] = [];
-
- 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;
- }
- 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();
-
- 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();
-
- const loadedCheerio = parseHTML(body);
-
- const novels: Plugin.NovelItem[] = [];
-
- 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;
- }
- async fetchImage(url: string): Promise {
- return await fetchFile(url);
- }
-
- filters = {
- order: {
- label: "Sort By",
- type: FilterTypes.Picker,
- options: [
- { 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" },
- ],
- value: "",
- },
-
- status: {
- label: "Status",
- options: [
- { label: "All", value: "" },
-
- { label: "Ongoing", value: "ongoing" },
-
- { label: "Hiatus", value: "hiatus" },
-
- { label: "Completed", value: "completed" },
- ],
- type: FilterTypes.Picker,
- value: "",
- },
- type: {
- label: "Type",
- options: [
- { 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" },
- ],
- type: FilterTypes.CheckboxGroup,
- value: [],
- },
- genres: {
- label: "Genres",
- value: [],
- options: [
- { 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" },
- ],
- type: FilterTypes.CheckboxGroup,
- },
- } satisfies Filters;
-}
-
-const Noble = new NobleMTL();
-
-export default new NobleMTL();
+import { load as parseHTML } from "cheerio";
+import { fetchApi, fetchFile } from "@libs/fetch";
+import { FilterTypes, Filters } from "@libs/filterInputs";
+import { Plugin } from "@typings/plugin";
+
+class NobleMTL implements Plugin.PluginBase {
+ id = "noblemtl";
+ name = "NobleMTL";
+ icon = "src/en/noblemtl/icon.png";
+ site = "https://noblemtl.com/";
+ version = "1.0.0";
+ userAgent = "";
+ async popularNovels(
+ pageNo: number,
+ { filters }: Plugin.PopularNovelsOptions
+ ): Promise {
+ let link = `${this.site}series/?page=${pageNo}`;
+
+ if (filters.genres.value.length)
+ link += filters.genres.value.map((i) => `&genre[]=${i}`).join("");
+
+ if (filters.type.value.length)
+ link += filters.type.value.map((i) => `&lang[]=${i}`).join("");
+
+ link += "&status=" + filters.status.value;
+
+ link += "&order=" + filters.order.value;
+
+ const headers = new Headers();
+ const body = await fetchApi(link, { headers }).then((result) =>
+ result.text()
+ );
+
+ const loadedCheerio = parseHTML(body);
+
+ const novels: Plugin.NovelItem[] = [];
+
+ 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;
+ }
+
+ async parseNovelAndChapters(novelUrl: string): Promise {
+ const url = novelUrl;
+ const headers = new Headers();
+ const result = await fetchApi(url, { headers });
+ const body = await result.text();
+
+ let loadedCheerio = parseHTML(body);
+
+ const novel: Plugin.SourceNovel = {
+ 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 "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();
+
+ let chapter: Plugin.ChapterItem[] = [];
+
+ 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;
+ }
+ async parseChapter(chapterUrl: string): Promise {
+ const headers = new Headers();
+ const result = await fetchApi(chapterUrl, { headers });
+ const body = await result.text();
+
+ 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();
+ const result = await fetchApi(url, { headers });
+ const body = await result.text();
+
+ const loadedCheerio = parseHTML(body);
+
+ const novels: Plugin.NovelItem[] = [];
+
+ 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;
+ }
+ async fetchImage(url: string): Promise {
+ return await fetchFile(url);
+ }
+
+ filters = {
+ order: {
+ label: "Sort By",
+ type: FilterTypes.Picker,
+ options: [
+ { 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" },
+ ],
+ value: "",
+ },
+
+ status: {
+ label: "Status",
+ options: [
+ { label: "All", value: "" },
+
+ { label: "Ongoing", value: "ongoing" },
+
+ { label: "Hiatus", value: "hiatus" },
+
+ { label: "Completed", value: "completed" },
+ ],
+ type: FilterTypes.Picker,
+ value: "",
+ },
+ type: {
+ label: "Type",
+ options: [
+ { 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" },
+ ],
+ type: FilterTypes.CheckboxGroup,
+ value: [],
+ },
+ genres: {
+ label: "Genres",
+ value: [],
+ options: [
+ { 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" },
+ ],
+ type: FilterTypes.CheckboxGroup,
+ },
+ } satisfies Filters;
+}
+
+const Noble = new NobleMTL();
+
+export default new NobleMTL();
diff --git a/plugins/english/pandaMTL.ts b/plugins/english/pandaMTL.ts
index 43e1988..4a84c75 100644
--- a/plugins/english/pandaMTL.ts
+++ b/plugins/english/pandaMTL.ts
@@ -1,280 +1,267 @@
-import { load as parseHTML } from "cheerio";
-import { fetchApi, fetchFile } from "@libs/fetch";
-import { FilterTypes, Filters } from "@libs/filterInputs";
-import { Plugin } from "@typings/plugin";
-
-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.genres.value.length) {
- link += filters.genres.value.map((i) => `&genre[]=${i}`).join("");
- }
-
- if (filters.type.value.length)
- link += filters.type.value.map((i) => `&lang[]=${i}`).join("");
-
- link += "&status=" + (filters?.status ? filters.status : "");
-
- 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;
- }
- 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("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 () {
- const detailName = loadedCheerio(this).text().trim();
- const 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((i, el) => loadedCheerio(el).text())
- .toArray()
- .join(",");
-
- novel.summary = loadedCheerio(".sersys")
- .find("br")
- .replaceWith("\n")
- .end()
- .text();
-
- let chapter: Plugin.ChapterItem[] = [];
-
- 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;
- }
- 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();
-
- 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();
-
- 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;
-
- novels.push({
- name: novelName,
- url: novelUrl,
- cover: novelCover,
- });
- });
-
- return novels;
- }
- async fetchImage(url: string): Promise {
- return await fetchFile(url);
- }
-
- filters = {
- order: {
- label: "Sort By",
- value: "",
- options: [
- { 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" },
- ],
- type: FilterTypes.Picker,
- },
- status: {
- label: "Status",
- value: "",
- options: [
- { label: "All", value: "" },
-
- { label: "Ongoing", value: "ongoing" },
-
- { label: "Hiatus", value: "hiatus" },
-
- { label: "Completed", value: "completed" },
- ],
- type: FilterTypes.Picker,
- },
- type: {
- value: [],
- label: "Type",
- options: [
- { label: "Light Novel (KR)", value: "light-novel-kr" },
-
- { label: "Web Novel", value: "web-novel" },
- ],
- type: FilterTypes.CheckboxGroup,
- },
- genres: {
- label: "Genres",
- value: [],
- options: [
- { 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" },
- ],
- type: FilterTypes.CheckboxGroup,
- },
- } satisfies Filters;
-}
-
-export default new PandaMTL();
+import { load as parseHTML } from "cheerio";
+import { fetchApi, fetchFile } from "@libs/fetch";
+import { FilterTypes, Filters } from "@libs/filterInputs";
+import { Plugin } from "@typings/plugin";
+
+class PandaMTL implements Plugin.PluginBase {
+ id = "pandamtl";
+ name = "PandaMTL";
+ icon = "src/en/wordpress/icon.png";
+ site = "https://pandamtl.com/";
+ version = "1.0.0";
+ userAgent = "";
+ async popularNovels(
+ pageNo: number,
+ { filters }: Plugin.PopularNovelsOptions
+ ): Promise {
+ let link = `${this.site}series/?page=${pageNo}`;
+
+ if (filters.genres.value.length) {
+ link += filters.genres.value.map((i) => `&genre[]=${i}`).join("");
+ }
+
+ if (filters.type.value.length)
+ link += filters.type.value.map((i) => `&lang[]=${i}`).join("");
+
+ link += "&status=" + (filters?.status ? filters.status : "");
+
+ link += "&order=" + (filters?.order ? filters.order : "popular");
+
+ const headers = new Headers();
+ 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;
+ }
+ async parseNovelAndChapters(novelUrl: string): Promise {
+ const url = novelUrl;
+ const headers = new Headers();
+ const result = await fetchApi(url, { headers });
+ const body = await result.text();
+
+ let loadedCheerio = parseHTML(body);
+
+ const novel: Plugin.SourceNovel = {
+ 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 () {
+ const detailName = loadedCheerio(this).text().trim();
+ const 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((i, el) => loadedCheerio(el).text())
+ .toArray()
+ .join(",");
+
+ novel.summary = loadedCheerio(".sersys")
+ .find("br")
+ .replaceWith("\n")
+ .end()
+ .text();
+
+ let chapter: Plugin.ChapterItem[] = [];
+
+ 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;
+ }
+ async parseChapter(chapterUrl: string): Promise {
+ const headers = new Headers();
+ const result = await fetchApi(chapterUrl, { headers });
+ const body = await result.text();
+
+ 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();
+ const result = await fetchApi(url, { headers });
+ const body = await 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;
+
+ novels.push({
+ name: novelName,
+ url: novelUrl,
+ cover: novelCover,
+ });
+ });
+
+ return novels;
+ }
+ async fetchImage(url: string): Promise {
+ return await fetchFile(url);
+ }
+
+ filters = {
+ order: {
+ label: "Sort By",
+ value: "",
+ options: [
+ { 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" },
+ ],
+ type: FilterTypes.Picker,
+ },
+ status: {
+ label: "Status",
+ value: "",
+ options: [
+ { label: "All", value: "" },
+
+ { label: "Ongoing", value: "ongoing" },
+
+ { label: "Hiatus", value: "hiatus" },
+
+ { label: "Completed", value: "completed" },
+ ],
+ type: FilterTypes.Picker,
+ },
+ type: {
+ value: [],
+ label: "Type",
+ options: [
+ { label: "Light Novel (KR)", value: "light-novel-kr" },
+
+ { label: "Web Novel", value: "web-novel" },
+ ],
+ type: FilterTypes.CheckboxGroup,
+ },
+ genres: {
+ label: "Genres",
+ value: [],
+ options: [
+ { 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" },
+ ],
+ type: FilterTypes.CheckboxGroup,
+ },
+ } satisfies Filters;
+}
+
+export default new PandaMTL();
diff --git a/plugins/french/chireads.ts b/plugins/french/chireads.ts
index 7e77776..3d44644 100644
--- a/plugins/french/chireads.ts
+++ b/plugins/french/chireads.ts
@@ -9,7 +9,7 @@ class ChireadsPlugin implements Plugin.PluginBase {
site: string;
version: string;
userAgent: string;
- cookieString: string;
+
constructor() {
this.id = "chireads.com";
this.name = "Chireads";
@@ -17,7 +17,6 @@ class ChireadsPlugin implements Plugin.PluginBase {
this.site = "https://chireads.com";
this.version = "1.0.0";
this.userAgent = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36";
- this.cookieString = "''";
}
parseNovels(loadedCheerio: CheerioAPI) {
return [];
diff --git a/plugins/french/noveldeglace.ts b/plugins/french/noveldeglace.ts
index c480c08..56d44ae 100644
--- a/plugins/french/noveldeglace.ts
+++ b/plugins/french/noveldeglace.ts
@@ -10,7 +10,7 @@ class NovelDeGlacePlugin implements Plugin.PluginBase{
site: string;
version: string;
userAgent: string;
- cookieString: string;
+
constructor() {
this.id = "NDG.com";
this.name = "NovelDeGlace";
@@ -18,7 +18,6 @@ class NovelDeGlacePlugin implements Plugin.PluginBase{
this.site = "https://noveldeglace.com/";
this.version = "1.0.0";
this.userAgent = "''";
- this.cookieString = "''";
}
async popularNovels(page: number): Promise {
diff --git a/plugins/portuguese/lightnovelbrasil.ts b/plugins/portuguese/lightnovelbrasil.ts
index dc50f5e..16823c7 100644
--- a/plugins/portuguese/lightnovelbrasil.ts
+++ b/plugins/portuguese/lightnovelbrasil.ts
@@ -1,426 +1,413 @@
-import { load as parseHTML } from "cheerio";
-import { fetchApi, fetchFile } from "@libs/fetch";
-import { FilterTypes, Filters } from "@libs/filterInputs";
-import { Plugin } from "@typings/plugin";
-
-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.genres.value.length)
- link += filters.genres.value.map((i) => `&genre[]=${i}`).join("");
-
- if (filters.type.value.length)
- link += filters.type.value.map((i) => `&lang[]=${i}`).join("");
-
- link += "&status=" + (filters?.status ? filters.status : "");
-
- 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.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;
- }
-
- 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(".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 "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();
-
- let chapter: Plugin.ChapterItem[] = [];
-
- 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;
- }
- 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();
-
- 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();
-
- const loadedCheerio = parseHTML(body);
-
- const novels: Plugin.NovelItem[] = [];
-
- 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;
- }
- async fetchImage(url: string): Promise {
- return await fetchFile(url);
- }
-
- filters = {
- order: {
- label: "Sort By",
- value: "",
- options: [
- { 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" },
- ],
- type: FilterTypes.Picker,
- },
- status: {
- label: "Status",
- value: "",
- options: [
- { label: "All", value: "" },
-
- { label: "Ongoing", value: "ongoing" },
-
- { label: "Hiatus", value: "hiatus" },
-
- { label: "Completed", value: "completed" },
- ],
- type: FilterTypes.Picker,
- },
- type: {
- label: "Type",
- value: [],
- options: [
- { 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" },
- ],
- type: FilterTypes.CheckboxGroup,
- },
- genres: {
- value: [],
- label: "Genres",
- options: [
- { 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" },
- ],
- type: FilterTypes.CheckboxGroup,
- },
- } satisfies Filters;
-}
-
-export default new LightNovelBrasil();
+import { load as parseHTML } from "cheerio";
+import { fetchApi, fetchFile } from "@libs/fetch";
+import { FilterTypes, Filters } from "@libs/filterInputs";
+import { Plugin } from "@typings/plugin";
+
+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 = "";
+ async popularNovels(
+ pageNo: number,
+ { filters }: Plugin.PopularNovelsOptions
+ ): Promise {
+ let link = `${this.site}series/?page=${pageNo}`;
+
+ if (filters.genres.value.length)
+ link += filters.genres.value.map((i) => `&genre[]=${i}`).join("");
+
+ if (filters.type.value.length)
+ link += filters.type.value.map((i) => `&lang[]=${i}`).join("");
+
+ link += "&status=" + (filters?.status ? filters.status : "");
+
+ link += "&order=" + (filters?.order ? filters.order : "popular");
+
+ const headers = new Headers();
+ const body = await fetchApi(link, { headers }).then((result) =>
+ result.text()
+ );
+
+ const loadedCheerio = parseHTML(body);
+
+ const novels: Plugin.NovelItem[] = [];
+
+ 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;
+ }
+
+ async parseNovelAndChapters(novelUrl: string): Promise {
+ const url = novelUrl;
+ const headers = new Headers();
+ const result = await fetchApi(url, { headers });
+ const body = await result.text();
+
+ let loadedCheerio = parseHTML(body);
+
+ const novel: Plugin.SourceNovel = {
+ 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 "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();
+
+ let chapter: Plugin.ChapterItem[] = [];
+
+ 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;
+ }
+ async parseChapter(chapterUrl: string): Promise {
+ const headers = new Headers();
+ const result = await fetchApi(chapterUrl, { headers });
+ const body = await result.text();
+
+ 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();
+ const result = await fetchApi(url, { headers });
+ const body = await result.text();
+
+ const loadedCheerio = parseHTML(body);
+
+ const novels: Plugin.NovelItem[] = [];
+
+ 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;
+ }
+ async fetchImage(url: string): Promise {
+ return await fetchFile(url);
+ }
+
+ filters = {
+ order: {
+ label: "Sort By",
+ value: "",
+ options: [
+ { 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" },
+ ],
+ type: FilterTypes.Picker,
+ },
+ status: {
+ label: "Status",
+ value: "",
+ options: [
+ { label: "All", value: "" },
+
+ { label: "Ongoing", value: "ongoing" },
+
+ { label: "Hiatus", value: "hiatus" },
+
+ { label: "Completed", value: "completed" },
+ ],
+ type: FilterTypes.Picker,
+ },
+ type: {
+ label: "Type",
+ value: [],
+ options: [
+ { 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" },
+ ],
+ type: FilterTypes.CheckboxGroup,
+ },
+ genres: {
+ value: [],
+ label: "Genres",
+ options: [
+ { 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" },
+ ],
+ type: FilterTypes.CheckboxGroup,
+ },
+ } satisfies Filters;
+}
+
+export default new LightNovelBrasil();
diff --git a/plugins/russian/LitSpace.ts b/plugins/russian/LitSpace.ts
index 14ed6b3..7f7fcb2 100644
--- a/plugins/russian/LitSpace.ts
+++ b/plugins/russian/LitSpace.ts
@@ -1,242 +1,241 @@
-import { Plugin } from "@typings/plugin";
-import { FilterTypes, Filters } from "@libs/filterInputs";
-import { fetchApi, fetchFile } from "@libs/fetch";
-import { NovelStatus } from "@libs/novelStatus";
-import { load as parseHTML } from "cheerio";
-
-class freedlit implements Plugin.PluginBase {
- id = "freedlit.space";
- name = "LitSpace";
- site = "https://freedlit.space";
- version = "1.0.0";
- icon = "src/ru/freedlit/icon.png";
- userAgent = "";
- cookieString = "";
-
- async popularNovels(
- page: number,
- { showLatestNovels, filters }: Plugin.PopularNovelsOptions,
- ): Promise {
- let url = this.site + "/get-books/all/list/" + page + "?sort=";
- url += showLatestNovels ? "recent" : filters?.sort?.value || "popular";
- url += "&status=" + (filters?.status?.value || "all");
- url += "&access=" + (filters?.access?.value || "all");
- url += "&adult=" + (filters?.adult?.value || "hide");
-
- if (filters?.genre?.value?.include?.length) {
- url += filters.genre.value.include
- .map(id => '&genres_included[]=' + id).join("");
- }
-
- if (filters?.genre?.value?.exclude?.length) {
- url += filters.genre.value.exclude
- .map(id => '&genres_excluded[]=' + id).join("");
- }
-
- const body = await fetchApi(url).then((res) => res.text());
- const loadedCheerio = parseHTML(body);
-
- const novels: Plugin.NovelItem[] = [];
- loadedCheerio("#bookListBlock > div > div").each(function () {
- const name = loadedCheerio(this).find("div > h4 > a").text()?.trim();
- const cover = loadedCheerio(this)
- .find("div > a > img")
- .attr("src")
- ?.trim();
- const url = loadedCheerio(this).find("div > h4 > a").attr("href")?.trim();
- if (!name || !url) return;
-
- novels.push({ name, cover, url });
- });
-
- return novels;
- }
-
- async parseNovelAndChapters(novelUrl: string): Promise {
- const body = await fetchApi(novelUrl).then((res) => res.text());
- const loadedCheerio = parseHTML(body);
-
- const novel: Plugin.SourceNovel = {
- url: novelUrl,
- name: loadedCheerio(".book-info h4").text(),
- cover: loadedCheerio(".book-cover > div > img").attr("src")?.trim(),
- summary: loadedCheerio("#nav-home").text()?.trim(),
- author: loadedCheerio(".book-info h5 > a").text(),
- genres: loadedCheerio(".genre-list > a")
- .map((index, element) => loadedCheerio(element).text())
- .get()
- .join(","),
- };
-
- const chapters: Plugin.ChapterItem[] = [];
-
- loadedCheerio("a.chapter-line").each(function () {
- const name = loadedCheerio(this).find("h6").text();
- const releaseTime = loadedCheerio(this).find('span[class="date"]').text();
- const url = loadedCheerio(this).attr("href");
- if (!name || !url) return;
-
- chapters.push({ name, releaseTime, url });
- });
-
- novel.chapters = chapters;
- return novel;
- }
-
- async parseChapter(chapterUrl: string): Promise {
- const body = await fetchApi(chapterUrl).then((res) => res.text());
- const loadedCheerio = parseHTML(body);
-
- loadedCheerio("div.mobile-block").remove();
- loadedCheerio("div.standart-block").remove();
-
- const chapterText = loadedCheerio('div[class="chapter"]').html() || "";
- return chapterText;
- }
-
- async searchNovels(searchTerm: string): Promise {
- const url = `${this.site}/search?query=${searchTerm}&type=all`;
- const body = await fetchApi(url).then((res) => res.text());
- const loadedCheerio = parseHTML(body);
-
- const novels: Plugin.NovelItem[] = [];
- loadedCheerio("#bookListBlock > div").each(function () {
- const name = loadedCheerio(this).find("h4 > a").text()?.trim();
- const cover = loadedCheerio(this).find("a > img").attr("src")?.trim();
- const url = loadedCheerio(this).find("h4 > a").attr("href")?.trim();
- if (!name || !url) return;
-
- novels.push({ name, cover, url });
- });
-
- return novels;
- }
- fetchImage = fetchFile;
-
- filters = {
- sort: {
- label: "Сортировка:",
- value: "",
- options: [
- { label: "По популярности", value: "popular" },
- { label: "По количеству комментариев", value: "comments" },
- { label: "По количеству лайков", value: "likes" },
- { label: "По новизне", value: "recent" },
- { label: "По просмотрам", value: "views" },
- ],
- type: FilterTypes.Picker,
- },
- genre: {
- label: "Жанры:",
- value: { include: [], exclude: [] },
- options: [
- { 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" },
- ],
- type: FilterTypes.ExcludableCheckboxGroup,
- },
- status: {
- label: "Статус:",
- value: "",
- options: [
- { label: "Любой статус", value: "all" },
- { label: "В процессе", value: "in-process" },
- { label: "Завершено", value: "finished" },
- ],
- type: FilterTypes.Picker,
- },
- access: {
- label: "Доступ:",
- value: "",
- options: [
- { label: "Любой доступ", value: "all" },
- { label: "Бесплатные", value: "free" },
- { label: "Платные", value: "paid" },
- ],
- type: FilterTypes.Picker,
- },
- adult: {
- label: "Возрастные ограничения:",
- value: "",
- options: [
- { label: "Скрыть 18+", value: "hide" },
- { label: "Показать +18", value: "show" },
- ],
- type: FilterTypes.Picker,
- },
- } satisfies Filters;
-}
-
-export default new freedlit();
+import { Plugin } from "@typings/plugin";
+import { FilterTypes, Filters } from "@libs/filterInputs";
+import { fetchApi, fetchFile } from "@libs/fetch";
+import { NovelStatus } from "@libs/novelStatus";
+import { load as parseHTML } from "cheerio";
+
+class freedlit implements Plugin.PluginBase {
+ id = "freedlit.space";
+ name = "LitSpace";
+ site = "https://freedlit.space";
+ version = "1.0.0";
+ icon = "src/ru/freedlit/icon.png";
+ userAgent = "";
+
+ async popularNovels(
+ page: number,
+ { showLatestNovels, filters }: Plugin.PopularNovelsOptions,
+ ): Promise {
+ let url = this.site + "/get-books/all/list/" + page + "?sort=";
+ url += showLatestNovels ? "recent" : filters?.sort?.value || "popular";
+ url += "&status=" + (filters?.status?.value || "all");
+ url += "&access=" + (filters?.access?.value || "all");
+ url += "&adult=" + (filters?.adult?.value || "hide");
+
+ if (filters?.genre?.value?.include?.length) {
+ url += filters.genre.value.include
+ .map(id => '&genres_included[]=' + id).join("");
+ }
+
+ if (filters?.genre?.value?.exclude?.length) {
+ url += filters.genre.value.exclude
+ .map(id => '&genres_excluded[]=' + id).join("");
+ }
+
+ const body = await fetchApi(url).then((res) => res.text());
+ const loadedCheerio = parseHTML(body);
+
+ const novels: Plugin.NovelItem[] = [];
+ loadedCheerio("#bookListBlock > div > div").each(function () {
+ const name = loadedCheerio(this).find("div > h4 > a").text()?.trim();
+ const cover = loadedCheerio(this)
+ .find("div > a > img")
+ .attr("src")
+ ?.trim();
+ const url = loadedCheerio(this).find("div > h4 > a").attr("href")?.trim();
+ if (!name || !url) return;
+
+ novels.push({ name, cover, url });
+ });
+
+ return novels;
+ }
+
+ async parseNovelAndChapters(novelUrl: string): Promise {
+ const body = await fetchApi(novelUrl).then((res) => res.text());
+ const loadedCheerio = parseHTML(body);
+
+ const novel: Plugin.SourceNovel = {
+ url: novelUrl,
+ name: loadedCheerio(".book-info h4").text(),
+ cover: loadedCheerio(".book-cover > div > img").attr("src")?.trim(),
+ summary: loadedCheerio("#nav-home").text()?.trim(),
+ author: loadedCheerio(".book-info h5 > a").text(),
+ genres: loadedCheerio(".genre-list > a")
+ .map((index, element) => loadedCheerio(element).text())
+ .get()
+ .join(","),
+ };
+
+ const chapters: Plugin.ChapterItem[] = [];
+
+ loadedCheerio("a.chapter-line").each(function () {
+ const name = loadedCheerio(this).find("h6").text();
+ const releaseTime = loadedCheerio(this).find('span[class="date"]').text();
+ const url = loadedCheerio(this).attr("href");
+ if (!name || !url) return;
+
+ chapters.push({ name, releaseTime, url });
+ });
+
+ novel.chapters = chapters;
+ return novel;
+ }
+
+ async parseChapter(chapterUrl: string): Promise {
+ const body = await fetchApi(chapterUrl).then((res) => res.text());
+ const loadedCheerio = parseHTML(body);
+
+ loadedCheerio("div.mobile-block").remove();
+ loadedCheerio("div.standart-block").remove();
+
+ const chapterText = loadedCheerio('div[class="chapter"]').html() || "";
+ return chapterText;
+ }
+
+ async searchNovels(searchTerm: string): Promise {
+ const url = `${this.site}/search?query=${searchTerm}&type=all`;
+ const body = await fetchApi(url).then((res) => res.text());
+ const loadedCheerio = parseHTML(body);
+
+ const novels: Plugin.NovelItem[] = [];
+ loadedCheerio("#bookListBlock > div").each(function () {
+ const name = loadedCheerio(this).find("h4 > a").text()?.trim();
+ const cover = loadedCheerio(this).find("a > img").attr("src")?.trim();
+ const url = loadedCheerio(this).find("h4 > a").attr("href")?.trim();
+ if (!name || !url) return;
+
+ novels.push({ name, cover, url });
+ });
+
+ return novels;
+ }
+ fetchImage = fetchFile;
+
+ filters = {
+ sort: {
+ label: "Сортировка:",
+ value: "",
+ options: [
+ { label: "По популярности", value: "popular" },
+ { label: "По количеству комментариев", value: "comments" },
+ { label: "По количеству лайков", value: "likes" },
+ { label: "По новизне", value: "recent" },
+ { label: "По просмотрам", value: "views" },
+ ],
+ type: FilterTypes.Picker,
+ },
+ genre: {
+ label: "Жанры:",
+ value: { include: [], exclude: [] },
+ options: [
+ { 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" },
+ ],
+ type: FilterTypes.ExcludableCheckboxGroup,
+ },
+ status: {
+ label: "Статус:",
+ value: "",
+ options: [
+ { label: "Любой статус", value: "all" },
+ { label: "В процессе", value: "in-process" },
+ { label: "Завершено", value: "finished" },
+ ],
+ type: FilterTypes.Picker,
+ },
+ access: {
+ label: "Доступ:",
+ value: "",
+ options: [
+ { label: "Любой доступ", value: "all" },
+ { label: "Бесплатные", value: "free" },
+ { label: "Платные", value: "paid" },
+ ],
+ type: FilterTypes.Picker,
+ },
+ adult: {
+ label: "Возрастные ограничения:",
+ value: "",
+ options: [
+ { label: "Скрыть 18+", value: "hide" },
+ { label: "Показать +18", value: "show" },
+ ],
+ type: FilterTypes.Picker,
+ },
+ } satisfies Filters;
+}
+
+export default new freedlit();
diff --git a/plugins/russian/authortoday.ts b/plugins/russian/authortoday.ts
index 5630442..a83517f 100644
--- a/plugins/russian/authortoday.ts
+++ b/plugins/russian/authortoday.ts
@@ -1,539 +1,538 @@
-import { Plugin } from "@typings/plugin";
-import { FilterTypes, Filters } from "@libs/filterInputs";
-import { defaultCover } from "@libs/defaultCover";
-import { fetchApi, fetchFile } from "@libs/fetch";
-import { NovelStatus } from "@libs/novelStatus";
-import { load as parseHTML } from "cheerio";
-import dayjs from "dayjs";
-
-const apiUrl = "https://api.author.today/";
-const token = "Bearer guest";
-
-class AuthorToday implements Plugin.PluginBase {
- id = "AT";
- name = "Автор Тудей";
- icon = "src/ru/authortoday/icon.png";
- site = "https://author.today";
- version = "1.0.0";
- userAgent = "";
- cookieString = "";
-
- async popularNovels(
- pageNo: number,
- { showLatestNovels, filters }: Plugin.PopularNovelsOptions,
- ): Promise {
- let url = apiUrl + "v1/catalog/search?page=" + pageNo;
- if (filters?.genre?.value) {
- url += "&genre=" + filters.genre.value;
- }
-
- url +=
- "&sorting=" + (showLatestNovels ? "recent" : filters?.sort?.value || "popular");
-
- url += "&form=" + (filters?.form?.value || "any");
- url += "&state=" + (filters?.state?.value || "any");
- url += "&series=" + (filters?.series?.value || "any");
- url += "&access=" + (filters?.access?.value || "any");
- url += "&promo=" + (filters?.promo?.value || "hide");
-
- const result = await fetchApi(url, {
- headers: {
- Authorization: token,
- },
- });
- const json = (await result.json()) as response;
- const novels: Plugin.NovelItem[] = [];
-
- if (json?.code === "NotFound") {
- return novels;
- }
-
- json?.searchResults?.forEach((novel) =>
- novels.push({
- name: novel.title,
- cover: novel?.coverUrl
- ? "https://cm.author.today/content/" + novel.coverUrl
- : defaultCover,
- url: this.site + "/work/" + novel.id,
- }),
- );
-
- return novels;
- }
- async parseNovelAndChapters(novelUrl: string): Promise {
- const workID = novelUrl.split("/")[4];
- const result = await fetchApi(`${apiUrl}v1/work/${workID}/details`, {
- headers: {
- Authorization: token,
- },
- });
-
- const json = (await result.json()) as responseBook;
- const novel: Plugin.SourceNovel = {
- url: novelUrl,
- name: json.title,
- cover: json?.coverUrl ? json.coverUrl.split("?")[0] : defaultCover,
- author:
- json?.originalAuthor ||
- json?.authorFIO ||
- json?.coAuthorFIO ||
- json?.secondCoAuthorFIO ||
- json?.translator ||
- "",
- genres: json?.tags?.join(", "),
- status: json?.isFinished ? NovelStatus.Completed : NovelStatus.Ongoing,
- };
-
- novel.summary = "";
- novel.summary += json?.annotation ? json.annotation + "\n" : "";
- novel.summary += json?.authorNotes
- ? "Примечания автора:\n" + json.authorNotes
- : "";
- // all chapters
- const chaptersRaw = await fetchApi(`${apiUrl}v1/work/${workID}/content`, {
- headers: {
- Authorization: token,
- },
- });
-
- const chaptersJSON = (await chaptersRaw.json()) as ChaptersEntity[];
- const chapters: Plugin.ChapterItem[] = [];
- chaptersJSON?.forEach((chapter, index) => {
- if (chapter?.isAvailable && !chapter?.isDraft) {
- chapters.push({
- name: chapter?.title || `Глава ${index + 1}`,
- releaseTime: dayjs(
- chapter?.publishTime || chapter.lastModificationTime,
- ).format("LLL"),
- url: `${apiUrl}v1/work/${workID}/chapter/${chapter.id}/text`,
- });
- }
- });
-
- novel.chapters = chapters;
- return novel;
- }
-
- async parseChapter(chapterUrl: string): Promise {
- const result = await fetchApi(chapterUrl, {
- headers: {
- Authorization: token,
- },
- });
- const json = (await result.json()) as encryptedСhapter;
-
- if (json?.code) {
- return json.code + "\n" + json?.message;
- }
-
- const 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 = parseHTML(text);
- const baseUrl = this.site;
- loadedCheerio("img").each(function () {
- if (!loadedCheerio(this).attr("src")?.startsWith("http")) {
- const src = loadedCheerio(this).attr("src");
- loadedCheerio(this).attr("src", baseUrl + src);
- }
- });
- const chapterText = loadedCheerio.html();
- return chapterText;
- }
-
- async searchNovels(
- searchTerm: string,
- pageNo?: number | undefined,
- ): Promise {
- const baseUrl = this.site;
- const url = baseUrl + "/search?category=works&q=" + searchTerm + "&page=";
- const result = await fetchApi(url + (pageNo || 1));
- const body = await result.text();
- const loadedCheerio = parseHTML(body);
- const novels: Plugin.NovelItem[] = [];
-
- loadedCheerio("div.book-row").each(function () {
- const name = loadedCheerio(this)
- .find('div[class="book-title"] a')
- .text()
- .trim();
- let cover = loadedCheerio(this).find("img").attr("src");
- const url =
- baseUrl +
- "/work/" +
- loadedCheerio(this)
- .find('div[class="book-title"] a')
- .attr("href")
- ?.split("/")[2];
-
- if (cover) {
- cover = cover.split("?")[0];
- } else {
- cover = defaultCover;
- }
-
- novels.push({ name, cover, url });
- });
-
- return novels;
- }
-
- fetchImage = fetchFile;
-
- filters = {
- sort: {
- label: "Сортировка",
- value: "",
- options: [
- { label: "По популярности", value: "popular" },
- { label: "По количеству лайков", value: "likes" },
- { label: "По комментариям", value: "comments" },
- { label: "По новизне", value: "recent" },
- { label: "По просмотрам", value: "views" },
- { label: "Набирающие популярность", value: "trending" },
- ],
- type: FilterTypes.Picker,
- },
- genre: {
- label: "Жанры",
- value: "",
- options: [
- { 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" },
- ],
- type: FilterTypes.Picker,
- },
- form: {
- label: "Форма произведения",
- value: "",
- options: [
- { label: "Любой", value: "any" },
- { label: "Перевод", value: "translation" },
- { label: "Повесть", value: "tale" },
- { label: "Рассказ", value: "story" },
- { label: "Роман", value: "novel" },
- { label: "Сборник поэзии", value: "poetry" },
- { label: "Сборник рассказов", value: "story-book" },
- ],
- type: FilterTypes.Picker,
- },
- state: {
- label: "Статус произведения",
- value: "",
- options: [
- { label: "Любой статус", value: "any" },
- { label: "В процессе", value: "in-progress" },
- { label: "Завершено", value: "finished" },
- ],
- type: FilterTypes.Picker,
- },
- series: {
- label: "Статус цикла",
- value: "",
- options: [
- { label: "Не важно", value: "any" },
- { label: "Вне цикла", value: "out" },
- { label: "Цикл завершен", value: "finished" },
- { label: "Цикл не завершен", value: "unfinished" },
- ],
- type: FilterTypes.Picker,
- },
- access: {
- label: "Тип доступа",
- value: "",
- options: [
- { label: "Любой", value: "any" },
- { label: "Платный", value: "paid" },
- { label: "Бесплатный", value: "free" },
- ],
- type: FilterTypes.Picker,
- },
- promo: {
- label: "Промо-фрагмент",
- value: "",
- options: [
- { label: "Скрывать", value: "hide" },
- { label: "Показывать", value: "show" },
- ],
- type: FilterTypes.Picker,
- },
- } satisfies Filters;
-}
-
-export default new AuthorToday();
-
-interface response {
- searchResults?: SearchResultsEntity[] | null;
- realTotalCount: number;
- code?: string;
- errorMessage?: null;
- isLastPage: boolean;
- format: Format;
- duration: Duration;
- isWorkMarkEnabled: boolean;
-}
-interface SearchResultsEntity {
- id: number;
- title: string;
- annotation: string;
- authorId: number;
- authorFIO: string;
- authorUserName: string;
- originalAuthor?: null;
- coAuthorId?: number | null;
- coAuthorFIO?: string | null;
- coAuthorUserName?: string | null;
- coAuthorConfirmed: boolean;
- seriesId: number;
- seriesTitle?: string | null;
- publishTime: string;
- lastModificationTime: string;
- finishTime?: string | null;
- isDraft: boolean;
- formEnum: string;
- genreId: number;
- firstSubGenreId: number;
- secondSubGenreId?: number | null;
- adultOnly: boolean;
- tags?: (string | null)[] | null;
- coverUrl: string;
- viewCount: number;
- commentCount: number;
- reviewCount: number;
- textLength: number;
- likeCount: number;
- showAuthor: boolean;
- price?: number | null;
- discount?: null;
- discountStartDate?: null;
- discountEndDate?: null;
- status: string;
- promoFragment: boolean;
- isExclusive: boolean;
- format: string;
- marks?: null[] | null;
- isLiked: boolean;
- isWorkMarkEnabled: boolean;
- workInLibraryState: string;
-}
-interface Format {
- enumValue: string;
- value: string;
- title: string;
- mobileTitle: string;
-}
-interface Duration {
- value: string;
- title: string;
- mobileTitle: string;
-}
-
-interface responseBook {
- chapters?: ChaptersEntity[] | null;
- allowDownloads: boolean;
- downloadErrorCode: string;
- downloadErrorMessage: string;
- privacyDownloads: string;
- collectionCount: number;
- annotation: string;
- authorNotes: string;
- atRecommendation: boolean;
- seriesWorkIds?: number[] | null;
- seriesWorkNumber: number;
- reviewCount: number;
- tags?: string[] | null;
- orderId?: null;
- orderStatus: string;
- orderStatusMessage?: null;
- contests?: null[] | null;
- galleryImages?: GalleryImagesEntity[] | null;
- booktrailerVideoUrl?: null;
- isExclusive: boolean;
- freeChapterCount: number;
- promoFragment: boolean;
- recommendations?: RecommendationsEntity[] | null;
- linkedWork?: null;
- id: number;
- title: string;
- coverUrl: string;
- lastModificationTime: string;
- lastUpdateTime: string;
- finishTime?: null;
- isFinished: boolean;
- textLength: number;
- textLengthLastRead: number;
- price: number;
- discount?: null;
- workForm: string;
- status: string;
- authorId: number;
- authorFIO: string;
- authorUserName: string;
- originalAuthor?: null;
- translator?: null;
- reciter?: null;
- coAuthorId?: null;
- coAuthorFIO?: null;
- coAuthorUserName?: null;
- coAuthorConfirmed: boolean;
- secondCoAuthorId?: null;
- secondCoAuthorFIO?: null;
- secondCoAuthorUserName?: null;
- secondCoAuthorConfirmed: boolean;
- isPurchased: boolean;
- userLikeId?: null;
- lastReadTime?: null;
- lastChapterId?: null;
- lastChapterProgress: number;
- likeCount: number;
- commentCount: number;
- rewardCount: number;
- rewardsEnabled: boolean;
- inLibraryState: string;
- addedToLibraryTime: string;
- updateInLibraryTime: string;
- privacyDisplay: string;
- state: string;
- isDraft: boolean;
- enableRedLine: boolean;
- enableTTS: boolean;
- adultOnly: boolean;
- seriesId: number;
- seriesOrder: number;
- seriesTitle: string;
- afterword: string;
- seriesNextWorkId?: null;
- genreId: number;
- firstSubGenreId: number;
- secondSubGenreId: number;
- format: string;
- marks?: null;
- purchaseTime?: null;
- likeTime?: null;
- markTime?: null;
-}
-interface ChaptersEntity {
- id: number;
- workId: number;
- title: string;
- isDraft: boolean;
- sortOrder: number;
- publishTime: string;
- lastModificationTime: string;
- textLength: number;
- isAvailable: boolean;
-}
-
-interface GalleryImagesEntity {
- id: string;
- caption?: null;
- url: string;
- height: number;
- width: number;
-}
-interface RecommendationsEntity {
- title: string;
- coverUrl: string;
- authorId: number;
- authorFIO: string;
- authorUserName: string;
- originalAuthor?: null;
- coAuthorId?: null;
- coAuthorFIO?: null;
- coAuthorUserName?: null;
- coAuthorConfirmed: boolean;
- secondCoAuthorId?: null;
- secondCoAuthorFIO?: null;
- secondCoAuthorUserName?: null;
- secondCoAuthorConfirmed: boolean;
- discount?: null;
- price?: number | null;
- lastModificationTime: string;
- finishTime: string;
- finished: boolean;
- isExclusive: boolean;
- format: string;
- status: string;
- state: string;
- removalReason?: null;
- removalReasonComment?: null;
- id: number;
-}
-
-interface encryptedСhapter {
- id: number;
- title: string;
- isDraft: boolean;
- publishTime: string;
- lastModificationTime: string;
- text: string;
- key: string;
- code?: string;
- message?: string;
-}
+import { Plugin } from "@typings/plugin";
+import { FilterTypes, Filters } from "@libs/filterInputs";
+import { defaultCover } from "@libs/defaultCover";
+import { fetchApi, fetchFile } from "@libs/fetch";
+import { NovelStatus } from "@libs/novelStatus";
+import { load as parseHTML } from "cheerio";
+import dayjs from "dayjs";
+
+const apiUrl = "https://api.author.today/";
+const token = "Bearer guest";
+
+class AuthorToday implements Plugin.PluginBase {
+ id = "AT";
+ name = "Автор Тудей";
+ icon = "src/ru/authortoday/icon.png";
+ site = "https://author.today";
+ version = "1.0.0";
+ userAgent = "";
+
+ async popularNovels(
+ pageNo: number,
+ { showLatestNovels, filters }: Plugin.PopularNovelsOptions,
+ ): Promise {
+ let url = apiUrl + "v1/catalog/search?page=" + pageNo;
+ if (filters?.genre?.value) {
+ url += "&genre=" + filters.genre.value;
+ }
+
+ url +=
+ "&sorting=" + (showLatestNovels ? "recent" : filters?.sort?.value || "popular");
+
+ url += "&form=" + (filters?.form?.value || "any");
+ url += "&state=" + (filters?.state?.value || "any");
+ url += "&series=" + (filters?.series?.value || "any");
+ url += "&access=" + (filters?.access?.value || "any");
+ url += "&promo=" + (filters?.promo?.value || "hide");
+
+ const result = await fetchApi(url, {
+ headers: {
+ Authorization: token,
+ },
+ });
+ const json = (await result.json()) as response;
+ const novels: Plugin.NovelItem[] = [];
+
+ if (json?.code === "NotFound") {
+ return novels;
+ }
+
+ json?.searchResults?.forEach((novel) =>
+ novels.push({
+ name: novel.title,
+ cover: novel?.coverUrl
+ ? "https://cm.author.today/content/" + novel.coverUrl
+ : defaultCover,
+ url: this.site + "/work/" + novel.id,
+ }),
+ );
+
+ return novels;
+ }
+ async parseNovelAndChapters(novelUrl: string): Promise {
+ const workID = novelUrl.split("/")[4];
+ const result = await fetchApi(`${apiUrl}v1/work/${workID}/details`, {
+ headers: {
+ Authorization: token,
+ },
+ });
+
+ const json = (await result.json()) as responseBook;
+ const novel: Plugin.SourceNovel = {
+ url: novelUrl,
+ name: json.title,
+ cover: json?.coverUrl ? json.coverUrl.split("?")[0] : defaultCover,
+ author:
+ json?.originalAuthor ||
+ json?.authorFIO ||
+ json?.coAuthorFIO ||
+ json?.secondCoAuthorFIO ||
+ json?.translator ||
+ "",
+ genres: json?.tags?.join(", "),
+ status: json?.isFinished ? NovelStatus.Completed : NovelStatus.Ongoing,
+ };
+
+ novel.summary = "";
+ novel.summary += json?.annotation ? json.annotation + "\n" : "";
+ novel.summary += json?.authorNotes
+ ? "Примечания автора:\n" + json.authorNotes
+ : "";
+ // all chapters
+ const chaptersRaw = await fetchApi(`${apiUrl}v1/work/${workID}/content`, {
+ headers: {
+ Authorization: token,
+ },
+ });
+
+ const chaptersJSON = (await chaptersRaw.json()) as ChaptersEntity[];
+ const chapters: Plugin.ChapterItem[] = [];
+ chaptersJSON?.forEach((chapter, index) => {
+ if (chapter?.isAvailable && !chapter?.isDraft) {
+ chapters.push({
+ name: chapter?.title || `Глава ${index + 1}`,
+ releaseTime: dayjs(
+ chapter?.publishTime || chapter.lastModificationTime,
+ ).format("LLL"),
+ url: `${apiUrl}v1/work/${workID}/chapter/${chapter.id}/text`,
+ });
+ }
+ });
+
+ novel.chapters = chapters;
+ return novel;
+ }
+
+ async parseChapter(chapterUrl: string): Promise {
+ const result = await fetchApi(chapterUrl, {
+ headers: {
+ Authorization: token,
+ },
+ });
+ const json = (await result.json()) as encryptedСhapter;
+
+ if (json?.code) {
+ return json.code + "\n" + json?.message;
+ }
+
+ const 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 = parseHTML(text);
+ const baseUrl = this.site;
+ loadedCheerio("img").each(function () {
+ if (!loadedCheerio(this).attr("src")?.startsWith("http")) {
+ const src = loadedCheerio(this).attr("src");
+ loadedCheerio(this).attr("src", baseUrl + src);
+ }
+ });
+ const chapterText = loadedCheerio.html();
+ return chapterText;
+ }
+
+ async searchNovels(
+ searchTerm: string,
+ pageNo?: number | undefined,
+ ): Promise {
+ const baseUrl = this.site;
+ const url = baseUrl + "/search?category=works&q=" + searchTerm + "&page=";
+ const result = await fetchApi(url + (pageNo || 1));
+ const body = await result.text();
+ const loadedCheerio = parseHTML(body);
+ const novels: Plugin.NovelItem[] = [];
+
+ loadedCheerio("div.book-row").each(function () {
+ const name = loadedCheerio(this)
+ .find('div[class="book-title"] a')
+ .text()
+ .trim();
+ let cover = loadedCheerio(this).find("img").attr("src");
+ const url =
+ baseUrl +
+ "/work/" +
+ loadedCheerio(this)
+ .find('div[class="book-title"] a')
+ .attr("href")
+ ?.split("/")[2];
+
+ if (cover) {
+ cover = cover.split("?")[0];
+ } else {
+ cover = defaultCover;
+ }
+
+ novels.push({ name, cover, url });
+ });
+
+ return novels;
+ }
+
+ fetchImage = fetchFile;
+
+ filters = {
+ sort: {
+ label: "Сортировка",
+ value: "",
+ options: [
+ { label: "По популярности", value: "popular" },
+ { label: "По количеству лайков", value: "likes" },
+ { label: "По комментариям", value: "comments" },
+ { label: "По новизне", value: "recent" },
+ { label: "По просмотрам", value: "views" },
+ { label: "Набирающие популярность", value: "trending" },
+ ],
+ type: FilterTypes.Picker,
+ },
+ genre: {
+ label: "Жанры",
+ value: "",
+ options: [
+ { 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" },
+ ],
+ type: FilterTypes.Picker,
+ },
+ form: {
+ label: "Форма произведения",
+ value: "",
+ options: [
+ { label: "Любой", value: "any" },
+ { label: "Перевод", value: "translation" },
+ { label: "Повесть", value: "tale" },
+ { label: "Рассказ", value: "story" },
+ { label: "Роман", value: "novel" },
+ { label: "Сборник поэзии", value: "poetry" },
+ { label: "Сборник рассказов", value: "story-book" },
+ ],
+ type: FilterTypes.Picker,
+ },
+ state: {
+ label: "Статус произведения",
+ value: "",
+ options: [
+ { label: "Любой статус", value: "any" },
+ { label: "В процессе", value: "in-progress" },
+ { label: "Завершено", value: "finished" },
+ ],
+ type: FilterTypes.Picker,
+ },
+ series: {
+ label: "Статус цикла",
+ value: "",
+ options: [
+ { label: "Не важно", value: "any" },
+ { label: "Вне цикла", value: "out" },
+ { label: "Цикл завершен", value: "finished" },
+ { label: "Цикл не завершен", value: "unfinished" },
+ ],
+ type: FilterTypes.Picker,
+ },
+ access: {
+ label: "Тип доступа",
+ value: "",
+ options: [
+ { label: "Любой", value: "any" },
+ { label: "Платный", value: "paid" },
+ { label: "Бесплатный", value: "free" },
+ ],
+ type: FilterTypes.Picker,
+ },
+ promo: {
+ label: "Промо-фрагмент",
+ value: "",
+ options: [
+ { label: "Скрывать", value: "hide" },
+ { label: "Показывать", value: "show" },
+ ],
+ type: FilterTypes.Picker,
+ },
+ } satisfies Filters;
+}
+
+export default new AuthorToday();
+
+interface response {
+ searchResults?: SearchResultsEntity[] | null;
+ realTotalCount: number;
+ code?: string;
+ errorMessage?: null;
+ isLastPage: boolean;
+ format: Format;
+ duration: Duration;
+ isWorkMarkEnabled: boolean;
+}
+interface SearchResultsEntity {
+ id: number;
+ title: string;
+ annotation: string;
+ authorId: number;
+ authorFIO: string;
+ authorUserName: string;
+ originalAuthor?: null;
+ coAuthorId?: number | null;
+ coAuthorFIO?: string | null;
+ coAuthorUserName?: string | null;
+ coAuthorConfirmed: boolean;
+ seriesId: number;
+ seriesTitle?: string | null;
+ publishTime: string;
+ lastModificationTime: string;
+ finishTime?: string | null;
+ isDraft: boolean;
+ formEnum: string;
+ genreId: number;
+ firstSubGenreId: number;
+ secondSubGenreId?: number | null;
+ adultOnly: boolean;
+ tags?: (string | null)[] | null;
+ coverUrl: string;
+ viewCount: number;
+ commentCount: number;
+ reviewCount: number;
+ textLength: number;
+ likeCount: number;
+ showAuthor: boolean;
+ price?: number | null;
+ discount?: null;
+ discountStartDate?: null;
+ discountEndDate?: null;
+ status: string;
+ promoFragment: boolean;
+ isExclusive: boolean;
+ format: string;
+ marks?: null[] | null;
+ isLiked: boolean;
+ isWorkMarkEnabled: boolean;
+ workInLibraryState: string;
+}
+interface Format {
+ enumValue: string;
+ value: string;
+ title: string;
+ mobileTitle: string;
+}
+interface Duration {
+ value: string;
+ title: string;
+ mobileTitle: string;
+}
+
+interface responseBook {
+ chapters?: ChaptersEntity[] | null;
+ allowDownloads: boolean;
+ downloadErrorCode: string;
+ downloadErrorMessage: string;
+ privacyDownloads: string;
+ collectionCount: number;
+ annotation: string;
+ authorNotes: string;
+ atRecommendation: boolean;
+ seriesWorkIds?: number[] | null;
+ seriesWorkNumber: number;
+ reviewCount: number;
+ tags?: string[] | null;
+ orderId?: null;
+ orderStatus: string;
+ orderStatusMessage?: null;
+ contests?: null[] | null;
+ galleryImages?: GalleryImagesEntity[] | null;
+ booktrailerVideoUrl?: null;
+ isExclusive: boolean;
+ freeChapterCount: number;
+ promoFragment: boolean;
+ recommendations?: RecommendationsEntity[] | null;
+ linkedWork?: null;
+ id: number;
+ title: string;
+ coverUrl: string;
+ lastModificationTime: string;
+ lastUpdateTime: string;
+ finishTime?: null;
+ isFinished: boolean;
+ textLength: number;
+ textLengthLastRead: number;
+ price: number;
+ discount?: null;
+ workForm: string;
+ status: string;
+ authorId: number;
+ authorFIO: string;
+ authorUserName: string;
+ originalAuthor?: null;
+ translator?: null;
+ reciter?: null;
+ coAuthorId?: null;
+ coAuthorFIO?: null;
+ coAuthorUserName?: null;
+ coAuthorConfirmed: boolean;
+ secondCoAuthorId?: null;
+ secondCoAuthorFIO?: null;
+ secondCoAuthorUserName?: null;
+ secondCoAuthorConfirmed: boolean;
+ isPurchased: boolean;
+ userLikeId?: null;
+ lastReadTime?: null;
+ lastChapterId?: null;
+ lastChapterProgress: number;
+ likeCount: number;
+ commentCount: number;
+ rewardCount: number;
+ rewardsEnabled: boolean;
+ inLibraryState: string;
+ addedToLibraryTime: string;
+ updateInLibraryTime: string;
+ privacyDisplay: string;
+ state: string;
+ isDraft: boolean;
+ enableRedLine: boolean;
+ enableTTS: boolean;
+ adultOnly: boolean;
+ seriesId: number;
+ seriesOrder: number;
+ seriesTitle: string;
+ afterword: string;
+ seriesNextWorkId?: null;
+ genreId: number;
+ firstSubGenreId: number;
+ secondSubGenreId: number;
+ format: string;
+ marks?: null;
+ purchaseTime?: null;
+ likeTime?: null;
+ markTime?: null;
+}
+interface ChaptersEntity {
+ id: number;
+ workId: number;
+ title: string;
+ isDraft: boolean;
+ sortOrder: number;
+ publishTime: string;
+ lastModificationTime: string;
+ textLength: number;
+ isAvailable: boolean;
+}
+
+interface GalleryImagesEntity {
+ id: string;
+ caption?: null;
+ url: string;
+ height: number;
+ width: number;
+}
+interface RecommendationsEntity {
+ title: string;
+ coverUrl: string;
+ authorId: number;
+ authorFIO: string;
+ authorUserName: string;
+ originalAuthor?: null;
+ coAuthorId?: null;
+ coAuthorFIO?: null;
+ coAuthorUserName?: null;
+ coAuthorConfirmed: boolean;
+ secondCoAuthorId?: null;
+ secondCoAuthorFIO?: null;
+ secondCoAuthorUserName?: null;
+ secondCoAuthorConfirmed: boolean;
+ discount?: null;
+ price?: number | null;
+ lastModificationTime: string;
+ finishTime: string;
+ finished: boolean;
+ isExclusive: boolean;
+ format: string;
+ status: string;
+ state: string;
+ removalReason?: null;
+ removalReasonComment?: null;
+ id: number;
+}
+
+interface encryptedСhapter {
+ id: number;
+ title: string;
+ isDraft: boolean;
+ publishTime: string;
+ lastModificationTime: string;
+ text: string;
+ key: string;
+ code?: string;
+ message?: string;
+}
diff --git a/plugins/russian/bookriver.ts b/plugins/russian/bookriver.ts
index ddf5209..32a733e 100644
--- a/plugins/russian/bookriver.ts
+++ b/plugins/russian/bookriver.ts
@@ -1,259 +1,258 @@
-import { Plugin } from "@typings/plugin";
-import { FilterTypes, Filters } from "@libs/filterInputs";
-import { fetchApi, fetchFile } from "@libs/fetch";
-import { NovelStatus } from "@libs/novelStatus";
-import { load as parseHTML } from "cheerio";
-import dayjs from "dayjs";
-
-class Bookriver implements Plugin.PluginBase {
- id = "bookriver";
- name = "Bookriver";
- site = "https://bookriver.ru";
- version = "1.0.0";
- icon = "src/ru/bookriver/icon.png";
- userAgent = "";
- cookieString = "";
-
- async popularNovels(
- pageNo: number,
- { showLatestNovels, filters }: Plugin.PopularNovelsOptions,
- ): Promise {
- let url = this.site + `/genre?page=${pageNo}&perPage=24&sortingType=`;
- url += showLatestNovels
- ? "last-update"
- : filters?.sort?.value || "bestseller";
-
- if (filters?.genres?.value instanceof Array && filters?.genres?.value.length) {
- url += "&g=" + filters.genres.value.join(",");
- }
-
- const result = await fetchApi(url);
- const body = await result.text();
-
- const loadedCheerio = parseHTML(body);
- const novels: Plugin.NovelItem[] = [];
-
- const jsonRaw = loadedCheerio("#__NEXT_DATA__").html();
- if (jsonRaw) {
- const json: response = JSON.parse(jsonRaw);
- json.props.pageProps.state.pagesFilter?.genre?.books?.forEach((novel) =>
- novels.push({
- name: novel.name,
- cover: novel.coverImages[0].url,
- url: this.site + "/book/" + novel.slug,
- }),
- );
- }
- return novels;
- }
-
- async parseNovelAndChapters(novelUrl: string): Promise {
- const result = await fetchApi(novelUrl);
- const body = await result.text();
-
- const loadedCheerio = parseHTML(body);
- const jsonRaw = loadedCheerio("#__NEXT_DATA__").html();
- const json: response = JSON.parse(jsonRaw || "{}");
- const book = json.props.pageProps.state.book?.bookPage;
- const novel: Plugin.SourceNovel = {
- url: novelUrl,
- name: book?.name,
- cover: book?.coverImages[0].url,
- summary: book?.annotation,
- author: book?.author?.name,
- genres: book?.tags?.map((item) => item.name).join(", "),
- status:
- book?.statusComplete === "writing"
- ? NovelStatus.Ongoing
- : NovelStatus.Completed,
- };
-
- const chapters: Plugin.ChapterItem[] = [];
- book?.ebook?.chapters?.forEach((chapter) => {
- if (chapter.available) {
- chapters.push({
- name: chapter.name,
- releaseTime: dayjs(
- chapter?.firstPublishedAt || chapter.createdAt,
- ).format("LLL"),
- url: this.site + "/reader/" + book?.slug + "/" + chapter.chapterId,
- });
- }
- });
- novel.chapters = chapters;
- return novel;
- }
-
- async parseChapter(chapterUrl: string): Promise {
- const url = "https://api.bookriver.ru/api/v1/books/chapter/text/";
- const result = await fetchApi(url + chapterUrl.split("/").pop());
- const json = (await result.json()) as responseChapter;
-
- let chapterText = json.data.content || "Конец произведения";
- if (json.data?.audio?.available) {
- chapterText += "\n" + json.data.audio.url;
- }
-
- return chapterText;
- }
-
- async searchNovels(
- searchTerm: string,
- pageNo: number | undefined = 1,
- ): Promise {
- const url = `https://api.bookriver.ru/api/v1/search/autocomplete?keyword=${searchTerm}&page=${pageNo}&perPage=10`;
- const result = await fetchApi(url);
- const json = (await result.json()) as responseSearch;
-
- const novels: Plugin.NovelItem[] = [];
- json?.data?.books?.forEach((novel) =>
- novels.push({
- name: novel.name,
- cover: novel.coverImages[0].url,
- url: this.site + "/book/" + novel.slug,
- }),
- );
-
- return novels;
- }
- fetchImage = fetchFile;
-
- filters = {
- sort: {
- label: "Сортировка",
- value: "",
- options: [
- { label: "Бестселлеры", value: "bestseller" },
- { label: "Дате добавления", value: "newest" },
- { label: "Дате обновления", value: "last-update" },
- ],
- type: FilterTypes.Picker,
- },
- genres: {
- label: "жанры",
- value: [],
- options: [
- { 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" },
- ],
- type: FilterTypes.CheckboxGroup,
- },
- } satisfies Filters;
-}
-export default new Bookriver();
-
-interface response {
- props: {
- pageProps: {
- state: {
- book?: {
- bookPage: BooksEntity;
- };
- pagesFilter?: {
- genre: {
- books: BooksEntity[];
- };
- };
- };
- };
- };
-}
-
-interface BooksEntity {
- name: string;
- coverImages: { url: string }[];
- slug: string;
- annotation?: string;
- author?: {
- name: string;
- };
- tags?: { name: string }[];
- ebook?: {
- chapters: Chapter[];
- };
- statusComplete: string;
-}
-
-interface Chapter {
- name: string;
- available: boolean;
- firstPublishedAt?: Date | null;
- createdAt?: Date | null;
- chapterId: number | string;
-}
-
-interface responseChapter {
- data: {
- id: number;
- bookId: number;
- name: string;
- content: string;
- symbols: number;
- number: number;
- authorPages: number;
- createdAt: string;
- updatedAt: string;
- firstPublishedAt: string;
- status: string;
- protected: boolean;
- free: boolean;
- audio?: {
- available: boolean;
- url: string;
- duration: number;
- };
- publicationScheduledFor?: null;
- };
-}
-
-interface responseSearch {
- data: Data;
- total: number;
-}
-interface Data {
- books?: BooksEntity[] | null;
-}
+import { Plugin } from "@typings/plugin";
+import { FilterTypes, Filters } from "@libs/filterInputs";
+import { fetchApi, fetchFile } from "@libs/fetch";
+import { NovelStatus } from "@libs/novelStatus";
+import { load as parseHTML } from "cheerio";
+import dayjs from "dayjs";
+
+class Bookriver implements Plugin.PluginBase {
+ id = "bookriver";
+ name = "Bookriver";
+ site = "https://bookriver.ru";
+ version = "1.0.0";
+ icon = "src/ru/bookriver/icon.png";
+ userAgent = "";
+
+ async popularNovels(
+ pageNo: number,
+ { showLatestNovels, filters }: Plugin.PopularNovelsOptions,
+ ): Promise {
+ let url = this.site + `/genre?page=${pageNo}&perPage=24&sortingType=`;
+ url += showLatestNovels
+ ? "last-update"
+ : filters?.sort?.value || "bestseller";
+
+ if (filters?.genres?.value instanceof Array && filters?.genres?.value.length) {
+ url += "&g=" + filters.genres.value.join(",");
+ }
+
+ const result = await fetchApi(url);
+ const body = await result.text();
+
+ const loadedCheerio = parseHTML(body);
+ const novels: Plugin.NovelItem[] = [];
+
+ const jsonRaw = loadedCheerio("#__NEXT_DATA__").html();
+ if (jsonRaw) {
+ const json: response = JSON.parse(jsonRaw);
+ json.props.pageProps.state.pagesFilter?.genre?.books?.forEach((novel) =>
+ novels.push({
+ name: novel.name,
+ cover: novel.coverImages[0].url,
+ url: this.site + "/book/" + novel.slug,
+ }),
+ );
+ }
+ return novels;
+ }
+
+ async parseNovelAndChapters(novelUrl: string): Promise {
+ const result = await fetchApi(novelUrl);
+ const body = await result.text();
+
+ const loadedCheerio = parseHTML(body);
+ const jsonRaw = loadedCheerio("#__NEXT_DATA__").html();
+ const json: response = JSON.parse(jsonRaw || "{}");
+ const book = json.props.pageProps.state.book?.bookPage;
+ const novel: Plugin.SourceNovel = {
+ url: novelUrl,
+ name: book?.name,
+ cover: book?.coverImages[0].url,
+ summary: book?.annotation,
+ author: book?.author?.name,
+ genres: book?.tags?.map((item) => item.name).join(", "),
+ status:
+ book?.statusComplete === "writing"
+ ? NovelStatus.Ongoing
+ : NovelStatus.Completed,
+ };
+
+ const chapters: Plugin.ChapterItem[] = [];
+ book?.ebook?.chapters?.forEach((chapter) => {
+ if (chapter.available) {
+ chapters.push({
+ name: chapter.name,
+ releaseTime: dayjs(
+ chapter?.firstPublishedAt || chapter.createdAt,
+ ).format("LLL"),
+ url: this.site + "/reader/" + book?.slug + "/" + chapter.chapterId,
+ });
+ }
+ });
+ novel.chapters = chapters;
+ return novel;
+ }
+
+ async parseChapter(chapterUrl: string): Promise {
+ const url = "https://api.bookriver.ru/api/v1/books/chapter/text/";
+ const result = await fetchApi(url + chapterUrl.split("/").pop());
+ const json = (await result.json()) as responseChapter;
+
+ let chapterText = json.data.content || "Конец произведения";
+ if (json.data?.audio?.available) {
+ chapterText += "\n" + json.data.audio.url;
+ }
+
+ return chapterText;
+ }
+
+ async searchNovels(
+ searchTerm: string,
+ pageNo: number | undefined = 1,
+ ): Promise {
+ const url = `https://api.bookriver.ru/api/v1/search/autocomplete?keyword=${searchTerm}&page=${pageNo}&perPage=10`;
+ const result = await fetchApi(url);
+ const json = (await result.json()) as responseSearch;
+
+ const novels: Plugin.NovelItem[] = [];
+ json?.data?.books?.forEach((novel) =>
+ novels.push({
+ name: novel.name,
+ cover: novel.coverImages[0].url,
+ url: this.site + "/book/" + novel.slug,
+ }),
+ );
+
+ return novels;
+ }
+ fetchImage = fetchFile;
+
+ filters = {
+ sort: {
+ label: "Сортировка",
+ value: "",
+ options: [
+ { label: "Бестселлеры", value: "bestseller" },
+ { label: "Дате добавления", value: "newest" },
+ { label: "Дате обновления", value: "last-update" },
+ ],
+ type: FilterTypes.Picker,
+ },
+ genres: {
+ label: "жанры",
+ value: [],
+ options: [
+ { 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" },
+ ],
+ type: FilterTypes.CheckboxGroup,
+ },
+ } satisfies Filters;
+}
+export default new Bookriver();
+
+interface response {
+ props: {
+ pageProps: {
+ state: {
+ book?: {
+ bookPage: BooksEntity;
+ };
+ pagesFilter?: {
+ genre: {
+ books: BooksEntity[];
+ };
+ };
+ };
+ };
+ };
+}
+
+interface BooksEntity {
+ name: string;
+ coverImages: { url: string }[];
+ slug: string;
+ annotation?: string;
+ author?: {
+ name: string;
+ };
+ tags?: { name: string }[];
+ ebook?: {
+ chapters: Chapter[];
+ };
+ statusComplete: string;
+}
+
+interface Chapter {
+ name: string;
+ available: boolean;
+ firstPublishedAt?: Date | null;
+ createdAt?: Date | null;
+ chapterId: number | string;
+}
+
+interface responseChapter {
+ data: {
+ id: number;
+ bookId: number;
+ name: string;
+ content: string;
+ symbols: number;
+ number: number;
+ authorPages: number;
+ createdAt: string;
+ updatedAt: string;
+ firstPublishedAt: string;
+ status: string;
+ protected: boolean;
+ free: boolean;
+ audio?: {
+ available: boolean;
+ url: string;
+ duration: number;
+ };
+ publicationScheduledFor?: null;
+ };
+}
+
+interface responseSearch {
+ data: Data;
+ total: number;
+}
+interface Data {
+ books?: BooksEntity[] | null;
+}
diff --git a/plugins/russian/ficbook.ts b/plugins/russian/ficbook.ts
index 3056e41..ab0fdd6 100644
--- a/plugins/russian/ficbook.ts
+++ b/plugins/russian/ficbook.ts
@@ -1,2644 +1,2643 @@
-import { Plugin } from "@typings/plugin";
-import { FilterTypes, Filters } from "@libs/filterInputs";
-import { fetchApi, fetchFile } from "@libs/fetch";
-import { NovelStatus } from "@libs/novelStatus";
-import { load as parseHTML } from "cheerio";
-import { defaultCover } from "@libs/defaultCover";
-
-class ficbook implements Plugin.PluginBase {
- id = "ficbook";
- name = "ficbook";
- site = "https://ficbook.net";
- version = "1.0.0";
- icon = "src/ru/ficbook/icon.png";
- userAgent = "";
- cookieString = "";
-
- async popularNovels(
- pageNo: number,
- { showLatestNovels, filters }: Plugin.PopularNovelsOptions,
- ): Promise {
- const baseUrl = this.site;
- let url = baseUrl;
-
- if (filters?.directions?.value) {
- url += "/popular-fanfics/" + filters.directions.value;
- } else if (filters?.tags?.value) {
- url += "/tags/" + filters.tags.value + "?p=" + pageNo;
- } else {
- url += "/" + (filters?.sort?.value || "fanfiction") + "?p=" + pageNo;
- }
-
- const result = await fetchApi(url);
- const body = await result.text();
- const loadedCheerio = parseHTML(body);
-
- const novels: Plugin.NovelItem[] = [];
-
- 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;
- if (!name || !url) return;
-
- novels.push({ name, cover, url: baseUrl + url.replace(/\?.*/g, "") });
- });
-
- return novels;
- }
-
- async parseNovelAndChapters(novelUrl: string): Promise {
- const result = await fetchApi(novelUrl);
- const body = await result.text();
-
- const loadedCheerio = parseHTML(body);
-
- const novel: Plugin.SourceNovel = {
- 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.Ongoing
- : 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 || novel.cover?.includes("/design/")) {
- novel.cover = defaultCover;
- } else {
- novel.cover = novel.cover.replace(/covers\/m_|covers\/d_/g, "covers/");
- }
-
- const chapters: Plugin.ChapterItem[] = [];
- const baseUrl = this.site;
-
- 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: baseUrl + url });
- });
- }
-
- novel.chapters = chapters;
- return novel;
- }
-
- async parseChapter(chapterUrl: string): Promise {
- const result = await fetchApi(chapterUrl);
- const body = await result.text();
-
- const loadedCheerio = parseHTML(body);
- let chapterText = "";
-
- loadedCheerio("#content")
- .html()
- ?.split("\n")
- ?.forEach((line) => {
- if (line.trim()) {
- //blank line skip
- if (line.includes("
")) {
- //new paragraph
- chapterText += line;
- } else {
- //plaintext
- chapterText += "" + line + "
";
- }
- }
- });
-
- return chapterText;
- }
-
- async searchNovels(
- searchTerm: string,
- pageNo: number | undefined = 1,
- ): Promise {
- const formData = new FormData();
- formData.append("term", searchTerm);
- formData.append("page", pageNo.toString());
-
- const result = await fetchApi(this.site + "/search/fanfic", {
- method: "POST",
- body: formData,
- });
- const json = (await result.json()) as { data: Data };
- const novels: Plugin.NovelItem[] = [];
-
- json.data?.data?.forEach((novel) => {
- const name = novel.title.trim();
- const url = this.site + "/readfic/" + novel.slug;
- const cover = novel.cover
- ? "https://images.ficbook.net/fanfic-covers/" + novel.cover
- : defaultCover;
-
- novels.push({ name, cover, url });
- });
-
- return novels;
- }
- fetchImage = fetchFile;
-
- filters = {
- sort: {
- label: "Сортировка:",
- value: "",
- options: [
- { label: "Горячие работы", value: "fanfiction" },
- { label: "Популярные ", value: "popular-fanfics" },
- ],
- type: FilterTypes.Picker,
- },
- directions: {
- label: "Направление:",
- value: "",
- options: [
- { label: "Все", value: "" },
- { 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" },
- ],
- type: FilterTypes.Picker,
- },
- tags: {
- label: "Тэги:",
- value: "",
- options: [
- { label: "Все", value: "" },
- { 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" },
- ],
- type: FilterTypes.Picker,
- },
- } satisfies Filters;
-}
-
-export default new ficbook();
-
-interface Data {
- data?: DataEntity[] | null;
- more: boolean;
-}
-interface DataEntity {
- id: string;
- slug: string;
- author_id: number;
- user_slug: string;
- author_username: string;
- real_author_id: string | null;
- direction: number;
- part_cnt: number;
- title: string;
- description: string;
- enable_marks: boolean;
- marks_plus: number;
- is_premium: boolean;
- status: number;
- last_updated: string;
- readedDate?: string | null;
- reward_cnt: number;
- cover?: string | null;
-}
+import { Plugin } from "@typings/plugin";
+import { FilterTypes, Filters } from "@libs/filterInputs";
+import { fetchApi, fetchFile } from "@libs/fetch";
+import { NovelStatus } from "@libs/novelStatus";
+import { load as parseHTML } from "cheerio";
+import { defaultCover } from "@libs/defaultCover";
+
+class ficbook implements Plugin.PluginBase {
+ id = "ficbook";
+ name = "ficbook";
+ site = "https://ficbook.net";
+ version = "1.0.0";
+ icon = "src/ru/ficbook/icon.png";
+ userAgent = "";
+
+ async popularNovels(
+ pageNo: number,
+ { showLatestNovels, filters }: Plugin.PopularNovelsOptions,
+ ): Promise {
+ const baseUrl = this.site;
+ let url = baseUrl;
+
+ if (filters?.directions?.value) {
+ url += "/popular-fanfics/" + filters.directions.value;
+ } else if (filters?.tags?.value) {
+ url += "/tags/" + filters.tags.value + "?p=" + pageNo;
+ } else {
+ url += "/" + (filters?.sort?.value || "fanfiction") + "?p=" + pageNo;
+ }
+
+ const result = await fetchApi(url);
+ const body = await result.text();
+ const loadedCheerio = parseHTML(body);
+
+ const novels: Plugin.NovelItem[] = [];
+
+ 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;
+ if (!name || !url) return;
+
+ novels.push({ name, cover, url: baseUrl + url.replace(/\?.*/g, "") });
+ });
+
+ return novels;
+ }
+
+ async parseNovelAndChapters(novelUrl: string): Promise {
+ const result = await fetchApi(novelUrl);
+ const body = await result.text();
+
+ const loadedCheerio = parseHTML(body);
+
+ const novel: Plugin.SourceNovel = {
+ 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.Ongoing
+ : 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 || novel.cover?.includes("/design/")) {
+ novel.cover = defaultCover;
+ } else {
+ novel.cover = novel.cover.replace(/covers\/m_|covers\/d_/g, "covers/");
+ }
+
+ const chapters: Plugin.ChapterItem[] = [];
+ const baseUrl = this.site;
+
+ 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: baseUrl + url });
+ });
+ }
+
+ novel.chapters = chapters;
+ return novel;
+ }
+
+ async parseChapter(chapterUrl: string): Promise {
+ const result = await fetchApi(chapterUrl);
+ const body = await result.text();
+
+ const loadedCheerio = parseHTML(body);
+ let chapterText = "";
+
+ loadedCheerio("#content")
+ .html()
+ ?.split("\n")
+ ?.forEach((line) => {
+ if (line.trim()) {
+ //blank line skip
+ if (line.includes("")) {
+ //new paragraph
+ chapterText += line;
+ } else {
+ //plaintext
+ chapterText += "" + line + "
";
+ }
+ }
+ });
+
+ return chapterText;
+ }
+
+ async searchNovels(
+ searchTerm: string,
+ pageNo: number | undefined = 1,
+ ): Promise {
+ const formData = new FormData();
+ formData.append("term", searchTerm);
+ formData.append("page", pageNo.toString());
+
+ const result = await fetchApi(this.site + "/search/fanfic", {
+ method: "POST",
+ body: formData,
+ });
+ const json = (await result.json()) as { data: Data };
+ const novels: Plugin.NovelItem[] = [];
+
+ json.data?.data?.forEach((novel) => {
+ const name = novel.title.trim();
+ const url = this.site + "/readfic/" + novel.slug;
+ const cover = novel.cover
+ ? "https://images.ficbook.net/fanfic-covers/" + novel.cover
+ : defaultCover;
+
+ novels.push({ name, cover, url });
+ });
+
+ return novels;
+ }
+ fetchImage = fetchFile;
+
+ filters = {
+ sort: {
+ label: "Сортировка:",
+ value: "",
+ options: [
+ { label: "Горячие работы", value: "fanfiction" },
+ { label: "Популярные ", value: "popular-fanfics" },
+ ],
+ type: FilterTypes.Picker,
+ },
+ directions: {
+ label: "Направление:",
+ value: "",
+ options: [
+ { label: "Все", value: "" },
+ { 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" },
+ ],
+ type: FilterTypes.Picker,
+ },
+ tags: {
+ label: "Тэги:",
+ value: "",
+ options: [
+ { label: "Все", value: "" },
+ { 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" },
+ ],
+ type: FilterTypes.Picker,
+ },
+ } satisfies Filters;
+}
+
+export default new ficbook();
+
+interface Data {
+ data?: DataEntity[] | null;
+ more: boolean;
+}
+interface DataEntity {
+ id: string;
+ slug: string;
+ author_id: number;
+ user_slug: string;
+ author_username: string;
+ real_author_id: string | null;
+ direction: number;
+ part_cnt: number;
+ title: string;
+ description: string;
+ enable_marks: boolean;
+ marks_plus: number;
+ is_premium: boolean;
+ status: number;
+ last_updated: string;
+ readedDate?: string | null;
+ reward_cnt: number;
+ cover?: string | null;
+}
diff --git a/plugins/russian/jaomix.ts b/plugins/russian/jaomix.ts
index 6d46e58..717b2be 100644
--- a/plugins/russian/jaomix.ts
+++ b/plugins/russian/jaomix.ts
@@ -1,265 +1,264 @@
-import { Plugin } from "@typings/plugin";
-import { FilterTypes, Filters } from "@libs/filterInputs";
-import { fetchApi, fetchFile } from "@libs/fetch";
-import { NovelStatus } from "@libs/novelStatus";
-import { load as parseHTML } from "cheerio";
-
-class Jaomix implements Plugin.PluginBase {
- id = "jaomix.ru";
- name = "Jaomix";
- site = "https://jaomix.ru";
- version = "1.0.0";
- icon = "src/ru/jaomix/icon.png";
- userAgent = "";
- cookieString = "";
-
- async popularNovels(
- pageNo: number,
- {
- showLatestNovels,
- filters,
- }: Plugin.PopularNovelsOptions,
- ): Promise {
- let url = this.site + "/?searchrn";
-
- if (filters?.lang?.value?.length) {
- url += filters.lang.value
- .map((lang, idx) => `&lang[${idx}]=${lang}`).join("");
- }
-
- if (filters?.genre?.value?.include?.length) {
- url += filters.genre.value.include
- .map((genre, idx) => `&genre[${idx}]=${genre}`).join("");
- }
-
- if (filters?.genre?.value?.exclude?.length) {
- url += filters.genre.value.exclude
- .map((genre, idx) => `&delgenre[${idx}]=del ${genre}`).join("");
- }
-
- url += "&sortcountchapt=" + (filters?.sortcountchapt?.value || "1");
- url += "&sortdaycreate=" + (filters?.sortdaycreate?.value || "1");
- url +=
- "&sortby=" + (showLatestNovels ? "upd" : filters?.sortby?.value || "topweek");
- url += "&gpage=" + pageNo;
-
- const body = await fetchApi(url).then((res) => res.text());
- const loadedCheerio = parseHTML(body);
-
- const novels: Plugin.NovelItem[] = [];
- loadedCheerio('div[class="block-home"] > div[class="one"]').each(
- function () {
- const name = loadedCheerio(this)
- .find('div[class="img-home"] > a')
- .attr("title");
- const cover = loadedCheerio(this)
- .find('div[class="img-home"] > a > img')
- .attr("src")
- ?.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;
- }
-
- async parseNovelAndChapters(novelUrl: string): Promise {
- const body = await fetchApi(novelUrl).then((res) => res.text());
- const loadedCheerio = parseHTML(body);
-
- const novel: Plugin.SourceNovel = {
- url: novelUrl,
- name: loadedCheerio('div[class="desc-book"] > h1').text().trim(),
- cover: loadedCheerio('div[class="img-book"] > img').attr("src"),
- 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.Ongoing
- : NovelStatus.Completed;
- }
- });
-
- const chapters: Plugin.ChapterItem[] = [];
-
- 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;
- }
-
- async parseChapter(chapterUrl: string): Promise {
- const body = await fetchApi(chapterUrl).then((res) => res.text());
- const loadedCheerio = parseHTML(body);
-
- loadedCheerio('div[class="adblock-service"]').remove();
- const chapterText = loadedCheerio('div[class="entry-content"]').html();
-
- return chapterText || "";
- }
-
- async searchNovels(
- searchTerm: string,
- pageNo: number | undefined = 1,
- ): Promise {
- const url = `${this.site}/?searchrn=${searchTerm}&but=Поиск по названию&sortby=upd&gpage=${pageNo}`;
- const body = await fetchApi(url).then((res) => res.text());
- const loadedCheerio = parseHTML(body);
-
- const novels: Plugin.NovelItem[] = [];
- loadedCheerio('div[class="block-home"] > div[class="one"]').each(
- function () {
- const name = loadedCheerio(this)
- .find('div[class="img-home"] > a')
- .attr("title");
- const cover = loadedCheerio(this)
- .find('div[class="img-home"] > a > img')
- .attr("src")
- ?.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;
- }
- fetchImage = fetchFile;
-
- filters = {
- sortby: {
- label: "Сортировка:",
- value: "topweek",
- options: [
- { 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" },
- ],
- type: FilterTypes.Picker,
- },
- sortdaycreate: {
- label: "Дата добавления:",
- value: "1",
- options: [
- { 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" },
- ],
- type: FilterTypes.Picker,
- },
- sortcountchapt: {
- label: "Количество глав:",
- value: "1",
- options: [
- { 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" },
- ],
- type: FilterTypes.Picker,
- },
- genre: {
- label: "Жанры:",
- value: { include: [], exclude: [] },
- options: [
- { 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" },
- ],
- type: FilterTypes.ExcludableCheckboxGroup,
- },
- lang: {
- label: "Выбрать языки:",
- value: [],
- options: [
- { label: "Английский", value: "Английский" },
- { label: "Китайский", value: "Китайский" },
- { label: "Корейский", value: "Корейский" },
- { label: "Японский", value: "Японский" },
- ],
- type: FilterTypes.CheckboxGroup,
- },
- } satisfies Filters;
-}
-
-export default new Jaomix();
+import { Plugin } from "@typings/plugin";
+import { FilterTypes, Filters } from "@libs/filterInputs";
+import { fetchApi, fetchFile } from "@libs/fetch";
+import { NovelStatus } from "@libs/novelStatus";
+import { load as parseHTML } from "cheerio";
+
+class Jaomix implements Plugin.PluginBase {
+ id = "jaomix.ru";
+ name = "Jaomix";
+ site = "https://jaomix.ru";
+ version = "1.0.0";
+ icon = "src/ru/jaomix/icon.png";
+ userAgent = "";
+
+ async popularNovels(
+ pageNo: number,
+ {
+ showLatestNovels,
+ filters,
+ }: Plugin.PopularNovelsOptions,
+ ): Promise {
+ let url = this.site + "/?searchrn";
+
+ if (filters?.lang?.value?.length) {
+ url += filters.lang.value
+ .map((lang, idx) => `&lang[${idx}]=${lang}`).join("");
+ }
+
+ if (filters?.genre?.value?.include?.length) {
+ url += filters.genre.value.include
+ .map((genre, idx) => `&genre[${idx}]=${genre}`).join("");
+ }
+
+ if (filters?.genre?.value?.exclude?.length) {
+ url += filters.genre.value.exclude
+ .map((genre, idx) => `&delgenre[${idx}]=del ${genre}`).join("");
+ }
+
+ url += "&sortcountchapt=" + (filters?.sortcountchapt?.value || "1");
+ url += "&sortdaycreate=" + (filters?.sortdaycreate?.value || "1");
+ url +=
+ "&sortby=" + (showLatestNovels ? "upd" : filters?.sortby?.value || "topweek");
+ url += "&gpage=" + pageNo;
+
+ const body = await fetchApi(url).then((res) => res.text());
+ const loadedCheerio = parseHTML(body);
+
+ const novels: Plugin.NovelItem[] = [];
+ loadedCheerio('div[class="block-home"] > div[class="one"]').each(
+ function () {
+ const name = loadedCheerio(this)
+ .find('div[class="img-home"] > a')
+ .attr("title");
+ const cover = loadedCheerio(this)
+ .find('div[class="img-home"] > a > img')
+ .attr("src")
+ ?.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;
+ }
+
+ async parseNovelAndChapters(novelUrl: string): Promise {
+ const body = await fetchApi(novelUrl).then((res) => res.text());
+ const loadedCheerio = parseHTML(body);
+
+ const novel: Plugin.SourceNovel = {
+ url: novelUrl,
+ name: loadedCheerio('div[class="desc-book"] > h1').text().trim(),
+ cover: loadedCheerio('div[class="img-book"] > img').attr("src"),
+ 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.Ongoing
+ : NovelStatus.Completed;
+ }
+ });
+
+ const chapters: Plugin.ChapterItem[] = [];
+
+ 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;
+ }
+
+ async parseChapter(chapterUrl: string): Promise {
+ const body = await fetchApi(chapterUrl).then((res) => res.text());
+ const loadedCheerio = parseHTML(body);
+
+ loadedCheerio('div[class="adblock-service"]').remove();
+ const chapterText = loadedCheerio('div[class="entry-content"]').html();
+
+ return chapterText || "";
+ }
+
+ async searchNovels(
+ searchTerm: string,
+ pageNo: number | undefined = 1,
+ ): Promise {
+ const url = `${this.site}/?searchrn=${searchTerm}&but=Поиск по названию&sortby=upd&gpage=${pageNo}`;
+ const body = await fetchApi(url).then((res) => res.text());
+ const loadedCheerio = parseHTML(body);
+
+ const novels: Plugin.NovelItem[] = [];
+ loadedCheerio('div[class="block-home"] > div[class="one"]').each(
+ function () {
+ const name = loadedCheerio(this)
+ .find('div[class="img-home"] > a')
+ .attr("title");
+ const cover = loadedCheerio(this)
+ .find('div[class="img-home"] > a > img')
+ .attr("src")
+ ?.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;
+ }
+ fetchImage = fetchFile;
+
+ filters = {
+ sortby: {
+ label: "Сортировка:",
+ value: "topweek",
+ options: [
+ { 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" },
+ ],
+ type: FilterTypes.Picker,
+ },
+ sortdaycreate: {
+ label: "Дата добавления:",
+ value: "1",
+ options: [
+ { 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" },
+ ],
+ type: FilterTypes.Picker,
+ },
+ sortcountchapt: {
+ label: "Количество глав:",
+ value: "1",
+ options: [
+ { 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" },
+ ],
+ type: FilterTypes.Picker,
+ },
+ genre: {
+ label: "Жанры:",
+ value: { include: [], exclude: [] },
+ options: [
+ { 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" },
+ ],
+ type: FilterTypes.ExcludableCheckboxGroup,
+ },
+ lang: {
+ label: "Выбрать языки:",
+ value: [],
+ options: [
+ { label: "Английский", value: "Английский" },
+ { label: "Китайский", value: "Китайский" },
+ { label: "Корейский", value: "Корейский" },
+ { label: "Японский", value: "Японский" },
+ ],
+ type: FilterTypes.CheckboxGroup,
+ },
+ } satisfies Filters;
+}
+
+export default new Jaomix();
diff --git a/plugins/russian/novelTL.ts b/plugins/russian/novelTL.ts
index 87a6548..05f51df 100644
--- a/plugins/russian/novelTL.ts
+++ b/plugins/russian/novelTL.ts
@@ -1,958 +1,957 @@
-import { Plugin } from "@typings/plugin";
-import { FilterTypes, Filters } from "@libs/filterInputs";
-import { defaultCover } from "@libs/defaultCover";
-import { fetchApi, fetchFile } from "@libs/fetch";
-import { NovelStatus } from "@libs/novelStatus";
-import { load as parseHTML } from "cheerio";
-import dayjs from "dayjs";
-
-class TL implements Plugin.PluginBase {
- id = "TL";
- name = "NovelTL";
- site = "https://novel.tl";
- version = "1.0.0";
- icon = "src/ru/noveltl/icon.png";
- userAgent = "";
- cookieString = "";
-
- async popularNovels(
- page: number,
- { showLatestNovels, filters }: Plugin.PopularNovelsOptions,
- ): Promise {
- const result = await fetchApi(this.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: this.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?.tags?.value || [],
- genres: filters?.genres?.value || [],
- },
- hostname: "novel.tl",
- limit: 40,
- page,
- },
- }),
- });
-
- const json = (await result.json()) as response;
- const novels: Plugin.NovelItem[] = [];
-
- json.data?.projects?.content?.forEach((novel) =>
- novels.push({
- name: novel.title,
- url: "https://" + novel.fullUrl,
- cover: novel?.covers?.[0]?.url
- ? this.site + novel.covers[0].url
- : defaultCover,
- }),
- );
-
- return novels;
- }
-
- async parseNovelAndChapters(novelUrl: string): Promise {
- const result = await fetchApi(this.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: this.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 = (await result.json()) as response;
- const novel: Plugin.SourceNovel = {
- url: novelUrl,
- name: json.data.project?.title,
- cover: json.data.project?.covers?.[0]?.url
- ? this.site + json.data.project.covers[0].url
- : defaultCover,
- summary: json.data.project?.annotation?.text,
- status:
- json.data.project?.translationStatus === "active"
- ? NovelStatus.Ongoing
- : NovelStatus.Completed,
- };
-
- const genres = [json.data.project?.tags, json.data.project?.genres]
- .flat()
- .map((item) => item?.nameRu || item?.nameEng)
- .filter((item) => item);
-
- if (genres?.length) {
- novel.genres = genres.join(", ");
- }
-
- json.data.project?.persons?.forEach((person) => {
- if (person.role == "author" && person.name.firstName) {
- novel.author =
- person.name.firstName + " " + (person.name?.lastName || "");
- }
- });
-
- const chapters: Plugin.ChapterItem[] = [];
- json.data.project?.subprojects?.content?.forEach((work) =>
- work.volumes.content.forEach((volume) =>
- volume.chapters.forEach(
- (chapter) =>
- chapter?.published &&
- chapters.push({
- name: volume.shortName + " " + chapter.title,
- url: "https://" + chapter.fullUrl,
- releaseTime: dayjs(chapter.publishDate).format("LLL"),
- }),
- ),
- ),
- );
-
- novel.chapters = chapters;
- return novel;
- }
-
- async parseChapter(chapterUrl: string): Promise {
- const result = await fetchApi(this.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: this.site,
- body: JSON.stringify({
- query:
- "query($url:String){chapter(chapter:{fullUrl:$url}){text{text}}}",
- variables: {
- url: chapterUrl,
- },
- }),
- });
- const json = (await result.json()) as response;
-
- const baseUrl = this.site;
- const loadedCheerio = parseHTML(json.data.chapter?.text?.text || "");
- loadedCheerio("p > a[href]").each(function () {
- let src = baseUrl + loadedCheerio(this).attr("href");
- if (!src.startsWith("http")) {
- src = baseUrl + src;
- }
- loadedCheerio(this).find("picture").remove();
- loadedCheerio(this).removeAttr("href");
- loadedCheerio(`
`).appendTo(this);
- });
-
- const chapterText = loadedCheerio.html();
- return chapterText;
- }
-
- async searchNovels(
- searchTerm: string,
- page: number | undefined = 1,
- ): Promise {
- const result = await fetchApi(this.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: this.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,
- },
- }),
- });
- const json = (await result.json()) as response;
- const novels: Plugin.NovelItem[] = [];
-
- json?.data?.projects?.content?.forEach((novel) =>
- novels.push({
- name: novel.title,
- url: "https://" + novel.fullUrl,
- cover: novel?.covers?.[0]?.url
- ? this.site + novel.covers[0].url
- : defaultCover,
- }),
- );
-
- return novels;
- }
-
- fetchImage = fetchFile;
-
- filters = {
- tags: {
- label: "Тэги",
- value: [],
- options: [
- { 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" },
- ],
- type: FilterTypes.CheckboxGroup,
- },
- genres: {
- label: "Жанры",
- value: [],
- options: [
- { 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" },
- ],
- type: FilterTypes.CheckboxGroup,
- },
- } satisfies Filters;
-}
-
-export default new TL();
-
-interface response {
- data: Data;
-}
-
-interface Data {
- projects?: Projects;
- project?: Project;
- chapter?: DataChapter;
-}
-
-interface DataChapter {
- text: Text;
-}
-
-interface Text {
- text: string;
-}
-
-interface Project {
- title: string;
- translationStatus: string;
- fullUrl: string;
- covers: Cover[];
- persons: Person[];
- genres: Genre[];
- tags: Genre[];
- annotation: Text;
- subprojects: Subprojects;
-}
-
-interface Cover {
- url: string;
-}
-
-interface Genre {
- nameRu: string;
- nameEng: string;
-}
-
-interface Person {
- role: string;
- name: Name;
-}
-
-interface Name {
- firstName: string;
- lastName: string;
-}
-
-interface Subprojects {
- content: SubprojectsContent[];
-}
-
-interface SubprojectsContent {
- title: null | string;
- volumes: Volumes;
-}
-
-interface Volumes {
- content: VolumesContent[];
-}
-
-interface VolumesContent {
- shortName: string;
- chapters: ChapterElement[];
-}
-
-interface ChapterElement {
- title: string;
- publishDate: Date;
- fullUrl: string;
- published: boolean;
-}
-
-interface Projects {
- content: ProjectsContent[];
-}
-
-interface ProjectsContent {
- title: string;
- fullUrl: string;
- covers: Cover[];
-}
+import { Plugin } from "@typings/plugin";
+import { FilterTypes, Filters } from "@libs/filterInputs";
+import { defaultCover } from "@libs/defaultCover";
+import { fetchApi, fetchFile } from "@libs/fetch";
+import { NovelStatus } from "@libs/novelStatus";
+import { load as parseHTML } from "cheerio";
+import dayjs from "dayjs";
+
+class TL implements Plugin.PluginBase {
+ id = "TL";
+ name = "NovelTL";
+ site = "https://novel.tl";
+ version = "1.0.0";
+ icon = "src/ru/noveltl/icon.png";
+ userAgent = "";
+
+ async popularNovels(
+ page: number,
+ { showLatestNovels, filters }: Plugin.PopularNovelsOptions,
+ ): Promise {
+ const result = await fetchApi(this.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: this.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?.tags?.value || [],
+ genres: filters?.genres?.value || [],
+ },
+ hostname: "novel.tl",
+ limit: 40,
+ page,
+ },
+ }),
+ });
+
+ const json = (await result.json()) as response;
+ const novels: Plugin.NovelItem[] = [];
+
+ json.data?.projects?.content?.forEach((novel) =>
+ novels.push({
+ name: novel.title,
+ url: "https://" + novel.fullUrl,
+ cover: novel?.covers?.[0]?.url
+ ? this.site + novel.covers[0].url
+ : defaultCover,
+ }),
+ );
+
+ return novels;
+ }
+
+ async parseNovelAndChapters(novelUrl: string): Promise {
+ const result = await fetchApi(this.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: this.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 = (await result.json()) as response;
+ const novel: Plugin.SourceNovel = {
+ url: novelUrl,
+ name: json.data.project?.title,
+ cover: json.data.project?.covers?.[0]?.url
+ ? this.site + json.data.project.covers[0].url
+ : defaultCover,
+ summary: json.data.project?.annotation?.text,
+ status:
+ json.data.project?.translationStatus === "active"
+ ? NovelStatus.Ongoing
+ : NovelStatus.Completed,
+ };
+
+ const genres = [json.data.project?.tags, json.data.project?.genres]
+ .flat()
+ .map((item) => item?.nameRu || item?.nameEng)
+ .filter((item) => item);
+
+ if (genres?.length) {
+ novel.genres = genres.join(", ");
+ }
+
+ json.data.project?.persons?.forEach((person) => {
+ if (person.role == "author" && person.name.firstName) {
+ novel.author =
+ person.name.firstName + " " + (person.name?.lastName || "");
+ }
+ });
+
+ const chapters: Plugin.ChapterItem[] = [];
+ json.data.project?.subprojects?.content?.forEach((work) =>
+ work.volumes.content.forEach((volume) =>
+ volume.chapters.forEach(
+ (chapter) =>
+ chapter?.published &&
+ chapters.push({
+ name: volume.shortName + " " + chapter.title,
+ url: "https://" + chapter.fullUrl,
+ releaseTime: dayjs(chapter.publishDate).format("LLL"),
+ }),
+ ),
+ ),
+ );
+
+ novel.chapters = chapters;
+ return novel;
+ }
+
+ async parseChapter(chapterUrl: string): Promise {
+ const result = await fetchApi(this.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: this.site,
+ body: JSON.stringify({
+ query:
+ "query($url:String){chapter(chapter:{fullUrl:$url}){text{text}}}",
+ variables: {
+ url: chapterUrl,
+ },
+ }),
+ });
+ const json = (await result.json()) as response;
+
+ const baseUrl = this.site;
+ const loadedCheerio = parseHTML(json.data.chapter?.text?.text || "");
+ loadedCheerio("p > a[href]").each(function () {
+ let src = baseUrl + loadedCheerio(this).attr("href");
+ if (!src.startsWith("http")) {
+ src = baseUrl + src;
+ }
+ loadedCheerio(this).find("picture").remove();
+ loadedCheerio(this).removeAttr("href");
+ loadedCheerio(`
`).appendTo(this);
+ });
+
+ const chapterText = loadedCheerio.html();
+ return chapterText;
+ }
+
+ async searchNovels(
+ searchTerm: string,
+ page: number | undefined = 1,
+ ): Promise {
+ const result = await fetchApi(this.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: this.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,
+ },
+ }),
+ });
+ const json = (await result.json()) as response;
+ const novels: Plugin.NovelItem[] = [];
+
+ json?.data?.projects?.content?.forEach((novel) =>
+ novels.push({
+ name: novel.title,
+ url: "https://" + novel.fullUrl,
+ cover: novel?.covers?.[0]?.url
+ ? this.site + novel.covers[0].url
+ : defaultCover,
+ }),
+ );
+
+ return novels;
+ }
+
+ fetchImage = fetchFile;
+
+ filters = {
+ tags: {
+ label: "Тэги",
+ value: [],
+ options: [
+ { 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" },
+ ],
+ type: FilterTypes.CheckboxGroup,
+ },
+ genres: {
+ label: "Жанры",
+ value: [],
+ options: [
+ { 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" },
+ ],
+ type: FilterTypes.CheckboxGroup,
+ },
+ } satisfies Filters;
+}
+
+export default new TL();
+
+interface response {
+ data: Data;
+}
+
+interface Data {
+ projects?: Projects;
+ project?: Project;
+ chapter?: DataChapter;
+}
+
+interface DataChapter {
+ text: Text;
+}
+
+interface Text {
+ text: string;
+}
+
+interface Project {
+ title: string;
+ translationStatus: string;
+ fullUrl: string;
+ covers: Cover[];
+ persons: Person[];
+ genres: Genre[];
+ tags: Genre[];
+ annotation: Text;
+ subprojects: Subprojects;
+}
+
+interface Cover {
+ url: string;
+}
+
+interface Genre {
+ nameRu: string;
+ nameEng: string;
+}
+
+interface Person {
+ role: string;
+ name: Name;
+}
+
+interface Name {
+ firstName: string;
+ lastName: string;
+}
+
+interface Subprojects {
+ content: SubprojectsContent[];
+}
+
+interface SubprojectsContent {
+ title: null | string;
+ volumes: Volumes;
+}
+
+interface Volumes {
+ content: VolumesContent[];
+}
+
+interface VolumesContent {
+ shortName: string;
+ chapters: ChapterElement[];
+}
+
+interface ChapterElement {
+ title: string;
+ publishDate: Date;
+ fullUrl: string;
+ published: boolean;
+}
+
+interface Projects {
+ content: ProjectsContent[];
+}
+
+interface ProjectsContent {
+ title: string;
+ fullUrl: string;
+ covers: Cover[];
+}
diff --git a/plugins/russian/ranobehub.ts b/plugins/russian/ranobehub.ts
index 38ee106..3323007 100644
--- a/plugins/russian/ranobehub.ts
+++ b/plugins/russian/ranobehub.ts
@@ -1,1285 +1,1284 @@
-import { Plugin } from "@typings/plugin";
-import { FilterTypes, Filters } from "@libs/filterInputs";
-import { fetchApi, fetchFile } from "@libs/fetch";
-import { NovelStatus } from "@libs/novelStatus";
-import { load as parseHTML } from "cheerio";
-import dayjs from "dayjs";
-
-class RNBH implements Plugin.PluginBase {
- id = "RNBH.org";
- name = "RanobeHub";
- version = "1.0.0";
- site = "https://ranobehub.org/";
- icon = "src/ru/ranobehub/icon.png";
- userAgent = "";
- cookieString = "";
-
- async popularNovels(
- pageNo: number,
- {
- showLatestNovels,
- filters,
- }: Plugin.PopularNovelsOptions,
- ): Promise {
- let url = this.site + `api/search?page=${pageNo}&sort=`;
- url += showLatestNovels
- ? "last_chapter_at"
- : filters?.sort || "computed_rating";
- url += "&status=" + (filters?.status?.value ? filters?.status?.value : "0");
-
- if (filters) {
- if (filters.country?.value?.length) {
- url += "&country=" + filters.country.value.join(",");
- }
- if (
- filters.tags?.value?.include?.length ||
- filters.events?.value?.include?.length
- ) {
- const tagsPositive = [
- filters.tags.value?.include,
- filters.events.value?.include,
- ]
- .flat()
- .filter((t) => t);
- url += "&tags:positive=" + tagsPositive.join(",");
- }
- if (
- filters?.tags?.value?.exclude?.length ||
- filters?.events?.value?.exclude?.length
- ) {
- const tagsNegative = [
- filters.tags.value?.exclude,
- filters.events.value?.exclude,
- ]
- .flat()
- .filter((t) => t);
- url += "&tags:negative=" + tagsNegative.join(",");
- }
- }
-
- url += "&take=40";
- const result = await fetchApi(url);
- const body = (await result.json()) as { resource: responseNovels[] };
-
- const novels: Plugin.NovelItem[] = [];
- body.resource.forEach((novel) =>
- novels.push({
- name: novel.names?.rus || novel.names.eng,
- cover: novel.poster.medium,
- url: novel.url,
- }),
- );
-
- return novels;
- }
-
- async parseNovelAndChapters(novelUrl: string): Promise {
- const novelId = novelUrl
- .substring("https://ranobehub.org/ranobe/".length)
- .split("-")[0];
- const result = await fetchApi(`${this.site}api/ranobe/${novelId}`);
- const json = (await result.json()) as { data: responseNovel };
-
- const novel: Plugin.SourceNovel = {
- url: json.data.url,
- name: json.data.names?.rus || json.data.names.eng,
- cover: json.data.posters.medium,
- summary: json.data.description,
- author: json.data?.authors?.[0]?.name_eng || "",
- status: json.data.status.title.includes("процессе")
- ? NovelStatus.Ongoing
- : NovelStatus.Completed,
- };
-
- const tags = [json.data.tags.events, json.data.tags.genres]
- .flat()
- .map((tags) => tags?.names?.rus || tags?.names?.eng || tags?.title)
- .filter((tags) => tags);
-
- if (tags.length) {
- novel.genres = tags.join(", ");
- }
-
- const chapters: Plugin.ChapterItem[] = [];
- const fetchChaptersUrl = `${this.site}api/ranobe/${novelId}/contents`;
-
- const chaptersRaw = await fetchApi(fetchChaptersUrl);
- const chaptersJSON = (await chaptersRaw.json()) as {
- volumes: VolumesEntity[];
- };
-
- chaptersJSON.volumes.forEach(
- (volume) =>
- volume.chapters?.forEach((chapter) =>
- chapters.push({
- name: chapter.name,
- url: chapter.url,
- releaseTime: dayjs(parseInt(chapter.changed_at, 10) * 1000).format(
- "LLL",
- ),
- }),
- ),
- );
-
- novel.chapters = chapters;
- return novel;
- }
-
- async parseChapter(chapterUrl: string): Promise {
- const result = await fetchApi(chapterUrl);
- const body = await result.text();
-
- const loadedCheerio = parseHTML(body);
-
- loadedCheerio(".chapter-hoticons").remove();
- const baseUrl = this.site;
- loadedCheerio("div.text:nth-child(1) img").each(function () {
- if (!loadedCheerio(this).attr("src")?.startsWith("http")) {
- const dataMediaId = loadedCheerio(this).attr("data-media-id");
- loadedCheerio(this).attr("src", baseUrl + "api/media/" + dataMediaId);
- }
- });
-
- let chapterText: string =
- loadedCheerio("div.text:nth-child(1)").html() || "";
-
- // Remove script tags
- chapterText = chapterText?.replace(
- /<\s*script[^>]*>[\s\S]*?<\/script>/gim,
- "",
- );
- return chapterText;
- }
-
- async searchNovels(
- searchTerm: string,
- //pageNo: number | undefined = 1,
- ): Promise {
- const url = `${this.site}api/fulltext/global?query=${searchTerm}&take=10`;
-
- const result = await fetchApi(url);
- const data = (await result.json()) as responseSearch[];
-
- const novels: Plugin.NovelItem[] = [];
-
- data
- ?.find((item) => item?.meta?.key === "ranobe")
- ?.data?.forEach((novel) =>
- novels.push({
- name: novel?.names?.rus || novel?.names?.eng || novel?.name || "",
- url:
- "https://ranobehub.org/ranobe/" +
- novel?.url?.match(
- /https:\/\/ranobehub\.org\/ranobe\/(.*?)\?utm_source=search_name&utm_medium=search&utm_campaign=search_using/,
- )?.[1],
- cover: novel?.image?.replace("/small", "/medium"),
- }),
- );
-
- return novels;
- }
-
- fetchImage = fetchFile;
-
- filters = {
- sort: {
- label: "Сортировка",
- value: "",
- options: [
- { 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" },
- ],
- type: FilterTypes.Picker,
- },
- status: {
- label: "Статус перевода",
- value: "",
- options: [
- { label: "Любой", value: "" },
- { label: "В процессе", value: "1" },
- { label: "Завершено", value: "2" },
- { label: "Заморожено", value: "3" },
- { label: "Неизвестно", value: "4" },
- ],
- type: FilterTypes.Picker,
- },
- country: {
- label: "Тип",
- value: [],
- options: [
- { label: "Китай", value: "2" },
- { label: "Корея", value: "3" },
- { label: "США", value: "4" },
- { label: "Япония", value: "1" },
- ],
- type: FilterTypes.CheckboxGroup,
- },
- events: {
- label: "События",
- value: { include: [], exclude: [] },
- options: [
- { 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" },
- ],
- type: FilterTypes.ExcludableCheckboxGroup,
- },
- tags: {
- label: "Жанры",
- value: { include: [], exclude: [] },
- options: [
- { 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" },
- ],
- type: FilterTypes.ExcludableCheckboxGroup,
- },
- } satisfies Filters;
-}
-
-export default new RNBH();
-
-interface responseNovels {
- id: number;
- names: Names;
- rating: number;
- synopsis: string;
- url: string;
- poster: Poster;
- created_at: number;
- status: string;
- user?: User;
- counts: Counts;
-}
-interface Names {
- eng: string;
- rus?: string;
- original?: string;
-}
-interface Poster {
- medium: string;
- small: string;
- color: string;
-}
-interface User {
- status?: null;
- liked: boolean;
-}
-interface Counts {
- volumes: string;
- chapters: string;
-}
-
-interface responseNovel {
- id: number;
- names: Names;
- rating: number;
- year: number;
- synopsis: string;
- url: string;
- posters: Posters;
- isSpecial: boolean;
- liked: boolean;
- authors?: AuthorsEntity[] | null;
- translators?: TranslatorsEntity[] | null;
- description: string;
- status: Status;
- start_reading_url: string;
- html: string;
- tags: Tags;
-}
-interface Posters {
- big: string;
- medium: string;
- small: string;
- tiny: string;
- color: string;
-}
-interface AuthorsEntity {
- name_eng: string;
- pivot: Pivot;
-}
-interface Pivot {
- ranobe_id: number;
- author_id?: number;
- translator_id?: number;
-}
-interface TranslatorsEntity {
- name: string;
- pivot: Pivot;
-}
-interface Status {
- id: number;
- title: string;
-}
-interface Tags {
- events?: GenresOrEntity[] | null;
- genres?: GenresOrEntity[] | null;
-}
-interface GenresOrEntity {
- id: number;
- names: Names;
- url: string;
- title: string;
- description?: string | null;
-}
-
-interface responseChapters {
- marked_chapters_ids?: null[] | null;
- volumes?: VolumesEntity[] | null;
-}
-interface VolumesEntity {
- id: number;
- num: number;
- name: string;
- status: Status;
- chapters?: ChaptersEntity[] | null;
-}
-interface Status {
- id: number;
- name: string;
-}
-interface ChaptersEntity {
- id: number;
- name: string;
- num: number;
- url: string;
- is_new: boolean;
- has_images: boolean;
- changed_at: string;
- comments_count: string;
-}
-
-interface responseSearch {
- meta: Meta;
- collections?: DataEntity[] | null;
- data?: DataEntity[] | null;
-}
-interface Meta {
- key: string;
- title: string;
-}
-interface DataEntity {
- id: number;
- names?: Names | null;
- description?: string | null;
- url: string;
- image?: string | null;
- name?: string | null;
- level?: number | null;
- evolution_scheme?: null;
- roles?: null[] | null;
- avatar?: Avatar | null;
- has_plus?: boolean | null;
-}
-interface Avatar {
- big: string;
- color: string;
- thumb: string;
- is_default: boolean;
-}
+import { Plugin } from "@typings/plugin";
+import { FilterTypes, Filters } from "@libs/filterInputs";
+import { fetchApi, fetchFile } from "@libs/fetch";
+import { NovelStatus } from "@libs/novelStatus";
+import { load as parseHTML } from "cheerio";
+import dayjs from "dayjs";
+
+class RNBH implements Plugin.PluginBase {
+ id = "RNBH.org";
+ name = "RanobeHub";
+ version = "1.0.0";
+ site = "https://ranobehub.org/";
+ icon = "src/ru/ranobehub/icon.png";
+ userAgent = "";
+
+ async popularNovels(
+ pageNo: number,
+ {
+ showLatestNovels,
+ filters,
+ }: Plugin.PopularNovelsOptions,
+ ): Promise {
+ let url = this.site + `api/search?page=${pageNo}&sort=`;
+ url += showLatestNovels
+ ? "last_chapter_at"
+ : filters?.sort || "computed_rating";
+ url += "&status=" + (filters?.status?.value ? filters?.status?.value : "0");
+
+ if (filters) {
+ if (filters.country?.value?.length) {
+ url += "&country=" + filters.country.value.join(",");
+ }
+ if (
+ filters.tags?.value?.include?.length ||
+ filters.events?.value?.include?.length
+ ) {
+ const tagsPositive = [
+ filters.tags.value?.include,
+ filters.events.value?.include,
+ ]
+ .flat()
+ .filter((t) => t);
+ url += "&tags:positive=" + tagsPositive.join(",");
+ }
+ if (
+ filters?.tags?.value?.exclude?.length ||
+ filters?.events?.value?.exclude?.length
+ ) {
+ const tagsNegative = [
+ filters.tags.value?.exclude,
+ filters.events.value?.exclude,
+ ]
+ .flat()
+ .filter((t) => t);
+ url += "&tags:negative=" + tagsNegative.join(",");
+ }
+ }
+
+ url += "&take=40";
+ const result = await fetchApi(url);
+ const body = (await result.json()) as { resource: responseNovels[] };
+
+ const novels: Plugin.NovelItem[] = [];
+ body.resource.forEach((novel) =>
+ novels.push({
+ name: novel.names?.rus || novel.names.eng,
+ cover: novel.poster.medium,
+ url: novel.url,
+ }),
+ );
+
+ return novels;
+ }
+
+ async parseNovelAndChapters(novelUrl: string): Promise {
+ const novelId = novelUrl
+ .substring("https://ranobehub.org/ranobe/".length)
+ .split("-")[0];
+ const result = await fetchApi(`${this.site}api/ranobe/${novelId}`);
+ const json = (await result.json()) as { data: responseNovel };
+
+ const novel: Plugin.SourceNovel = {
+ url: json.data.url,
+ name: json.data.names?.rus || json.data.names.eng,
+ cover: json.data.posters.medium,
+ summary: json.data.description,
+ author: json.data?.authors?.[0]?.name_eng || "",
+ status: json.data.status.title.includes("процессе")
+ ? NovelStatus.Ongoing
+ : NovelStatus.Completed,
+ };
+
+ const tags = [json.data.tags.events, json.data.tags.genres]
+ .flat()
+ .map((tags) => tags?.names?.rus || tags?.names?.eng || tags?.title)
+ .filter((tags) => tags);
+
+ if (tags.length) {
+ novel.genres = tags.join(", ");
+ }
+
+ const chapters: Plugin.ChapterItem[] = [];
+ const fetchChaptersUrl = `${this.site}api/ranobe/${novelId}/contents`;
+
+ const chaptersRaw = await fetchApi(fetchChaptersUrl);
+ const chaptersJSON = (await chaptersRaw.json()) as {
+ volumes: VolumesEntity[];
+ };
+
+ chaptersJSON.volumes.forEach(
+ (volume) =>
+ volume.chapters?.forEach((chapter) =>
+ chapters.push({
+ name: chapter.name,
+ url: chapter.url,
+ releaseTime: dayjs(parseInt(chapter.changed_at, 10) * 1000).format(
+ "LLL",
+ ),
+ }),
+ ),
+ );
+
+ novel.chapters = chapters;
+ return novel;
+ }
+
+ async parseChapter(chapterUrl: string): Promise {
+ const result = await fetchApi(chapterUrl);
+ const body = await result.text();
+
+ const loadedCheerio = parseHTML(body);
+
+ loadedCheerio(".chapter-hoticons").remove();
+ const baseUrl = this.site;
+ loadedCheerio("div.text:nth-child(1) img").each(function () {
+ if (!loadedCheerio(this).attr("src")?.startsWith("http")) {
+ const dataMediaId = loadedCheerio(this).attr("data-media-id");
+ loadedCheerio(this).attr("src", baseUrl + "api/media/" + dataMediaId);
+ }
+ });
+
+ let chapterText: string =
+ loadedCheerio("div.text:nth-child(1)").html() || "";
+
+ // Remove script tags
+ chapterText = chapterText?.replace(
+ /<\s*script[^>]*>[\s\S]*?<\/script>/gim,
+ "",
+ );
+ return chapterText;
+ }
+
+ async searchNovels(
+ searchTerm: string,
+ //pageNo: number | undefined = 1,
+ ): Promise {
+ const url = `${this.site}api/fulltext/global?query=${searchTerm}&take=10`;
+
+ const result = await fetchApi(url);
+ const data = (await result.json()) as responseSearch[];
+
+ const novels: Plugin.NovelItem[] = [];
+
+ data
+ ?.find((item) => item?.meta?.key === "ranobe")
+ ?.data?.forEach((novel) =>
+ novels.push({
+ name: novel?.names?.rus || novel?.names?.eng || novel?.name || "",
+ url:
+ "https://ranobehub.org/ranobe/" +
+ novel?.url?.match(
+ /https:\/\/ranobehub\.org\/ranobe\/(.*?)\?utm_source=search_name&utm_medium=search&utm_campaign=search_using/,
+ )?.[1],
+ cover: novel?.image?.replace("/small", "/medium"),
+ }),
+ );
+
+ return novels;
+ }
+
+ fetchImage = fetchFile;
+
+ filters = {
+ sort: {
+ label: "Сортировка",
+ value: "",
+ options: [
+ { 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" },
+ ],
+ type: FilterTypes.Picker,
+ },
+ status: {
+ label: "Статус перевода",
+ value: "",
+ options: [
+ { label: "Любой", value: "" },
+ { label: "В процессе", value: "1" },
+ { label: "Завершено", value: "2" },
+ { label: "Заморожено", value: "3" },
+ { label: "Неизвестно", value: "4" },
+ ],
+ type: FilterTypes.Picker,
+ },
+ country: {
+ label: "Тип",
+ value: [],
+ options: [
+ { label: "Китай", value: "2" },
+ { label: "Корея", value: "3" },
+ { label: "США", value: "4" },
+ { label: "Япония", value: "1" },
+ ],
+ type: FilterTypes.CheckboxGroup,
+ },
+ events: {
+ label: "События",
+ value: { include: [], exclude: [] },
+ options: [
+ { 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" },
+ ],
+ type: FilterTypes.ExcludableCheckboxGroup,
+ },
+ tags: {
+ label: "Жанры",
+ value: { include: [], exclude: [] },
+ options: [
+ { 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" },
+ ],
+ type: FilterTypes.ExcludableCheckboxGroup,
+ },
+ } satisfies Filters;
+}
+
+export default new RNBH();
+
+interface responseNovels {
+ id: number;
+ names: Names;
+ rating: number;
+ synopsis: string;
+ url: string;
+ poster: Poster;
+ created_at: number;
+ status: string;
+ user?: User;
+ counts: Counts;
+}
+interface Names {
+ eng: string;
+ rus?: string;
+ original?: string;
+}
+interface Poster {
+ medium: string;
+ small: string;
+ color: string;
+}
+interface User {
+ status?: null;
+ liked: boolean;
+}
+interface Counts {
+ volumes: string;
+ chapters: string;
+}
+
+interface responseNovel {
+ id: number;
+ names: Names;
+ rating: number;
+ year: number;
+ synopsis: string;
+ url: string;
+ posters: Posters;
+ isSpecial: boolean;
+ liked: boolean;
+ authors?: AuthorsEntity[] | null;
+ translators?: TranslatorsEntity[] | null;
+ description: string;
+ status: Status;
+ start_reading_url: string;
+ html: string;
+ tags: Tags;
+}
+interface Posters {
+ big: string;
+ medium: string;
+ small: string;
+ tiny: string;
+ color: string;
+}
+interface AuthorsEntity {
+ name_eng: string;
+ pivot: Pivot;
+}
+interface Pivot {
+ ranobe_id: number;
+ author_id?: number;
+ translator_id?: number;
+}
+interface TranslatorsEntity {
+ name: string;
+ pivot: Pivot;
+}
+interface Status {
+ id: number;
+ title: string;
+}
+interface Tags {
+ events?: GenresOrEntity[] | null;
+ genres?: GenresOrEntity[] | null;
+}
+interface GenresOrEntity {
+ id: number;
+ names: Names;
+ url: string;
+ title: string;
+ description?: string | null;
+}
+
+interface responseChapters {
+ marked_chapters_ids?: null[] | null;
+ volumes?: VolumesEntity[] | null;
+}
+interface VolumesEntity {
+ id: number;
+ num: number;
+ name: string;
+ status: Status;
+ chapters?: ChaptersEntity[] | null;
+}
+interface Status {
+ id: number;
+ name: string;
+}
+interface ChaptersEntity {
+ id: number;
+ name: string;
+ num: number;
+ url: string;
+ is_new: boolean;
+ has_images: boolean;
+ changed_at: string;
+ comments_count: string;
+}
+
+interface responseSearch {
+ meta: Meta;
+ collections?: DataEntity[] | null;
+ data?: DataEntity[] | null;
+}
+interface Meta {
+ key: string;
+ title: string;
+}
+interface DataEntity {
+ id: number;
+ names?: Names | null;
+ description?: string | null;
+ url: string;
+ image?: string | null;
+ name?: string | null;
+ level?: number | null;
+ evolution_scheme?: null;
+ roles?: null[] | null;
+ avatar?: Avatar | null;
+ has_plus?: boolean | null;
+}
+interface Avatar {
+ big: string;
+ color: string;
+ thumb: string;
+ is_default: boolean;
+}
diff --git a/plugins/russian/ranobelib.ts b/plugins/russian/ranobelib.ts
index 47d4c2c..6077877 100644
--- a/plugins/russian/ranobelib.ts
+++ b/plugins/russian/ranobelib.ts
@@ -1,513 +1,512 @@
-import { Plugin } from "@typings/plugin";
-import { FilterTypes, Filters } from "@libs/filterInputs";
-import { fetchApi, fetchFile } from "@libs/fetch";
-import { NovelStatus } from "@libs/novelStatus";
-import { load as parseHTML } from "cheerio";
-import dayjs from "dayjs";
-
-class RLIB implements Plugin.PluginBase {
- id = "RLIB";
- name = "RanobeLib";
- site = "https://ranobelib.me";
- version = "1.0.0";
- icon = "src/ru/ranobelib/icon.png";
- ui: string | number | undefined = undefined;
- userAgent = "";
- cookieString = "";
-
- async popularNovels(
- pageNo: number,
- {
- showLatestNovels,
- filters,
- }: Plugin.PopularNovelsOptions,
- ): Promise {
- let url = `${this.site}/manga-list?sort=`;
- url += showLatestNovels
- ? "last_chapter_at"
- : filters?.sort?.value || "rate";
- url += "&dir=" + (filters?.order?.value || "desc");
-
- if (filters.type?.value?.length) {
- url += filters.type.value.map((i) => "&types[]=" + i).join("");
- }
-
- if (filters.format?.value?.include?.length) {
- url += filters.format.value.include
- .map((i) => "&format[include][]=" + i).join("");
- }
-
- if (filters.format?.value?.exclude?.length) {
- url += filters.format.value.exclude
- .map((i) => "&format[exclude][]=" + i).join("");
- }
-
- if (filters.status?.value?.length) {
- url += filters.status.value.map((i) => "&status[]=" + i).join("");
- }
-
- if (filters.statuss?.value?.length) {
- url += filters.statuss.value.map((i) => "&manga_status[]=" + i).join("");
- }
-
- if (filters.genres?.value?.include?.length) {
- url += filters.genres.value.include
- .map((i) => "&genres[include][]=" + i).join("");
- }
-
- if (filters.genres?.value?.exclude?.length) {
- url += filters.genres.value.exclude
- .map((i) => "&genres[exclude][]=" + i).join("");
- }
-
- if (filters.tags?.value?.include?.length) {
- url += filters.tags.value.include
- .map((i) => "&tags[include][]=" + i).join("");
- }
-
- if (filters.tags?.value?.exclude?.length) {
- url += filters.tags.value.exclude
- .map((i) => "&tags[exclude][]=" + i).join("");
- }
-
- url += "&page=" + pageNo;
-
- const result = await fetchApi(url);
- const body = await result.text();
-
- const loadedCheerio = parseHTML(body);
- this.ui = loadedCheerio("a.header-right-menu__item")
- .attr("href")
- ?.replace?.(/[^0-9]/g, "");
-
- const novels: Plugin.NovelItem[] = [];
- 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;
- }
-
- async parseNovelAndChapters(novelUrl: string): Promise {
- const result = await fetchApi(novelUrl);
- const body = await result.text();
-
- const loadedCheerio = parseHTML(body);
-
- const novel: Plugin.SourceNovel = {
- 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.Ongoing
- : NovelStatus.Completed;
- } else if (name === "Автор") {
- novel.author = loadedCheerio(this)
- .find("div:nth-child(2)")
- .text()
- .trim();
- }
- });
-
- const chapters: Plugin.ChapterItem[] = [];
-
- let chaptersRaw: any = body.match(
- /window.__DATA__ = [\s\S]*?window._SITE_COLOR_/gm,
- );
-
- chaptersRaw = chaptersRaw?.[0]
- ?.replace("window.__DATA__ = ", "")
- ?.replace("window._SITE_COLOR_", "")
- ?.trim()
- ?.slice(0, -1);
-
- let chaptersJson: responseBook = JSON.parse(chaptersRaw);
- this.ui = chaptersJson?.user?.id;
-
- chaptersJson.chapters?.list?.forEach((chapter) =>
- chapters.push({
- name: `Том ${chapter.chapter_volume} Глава ${chapter.chapter_number} ${chapter.chapter_name}`?.trim(),
- releaseTime: dayjs(chapter.chapter_created_at).format("LLL"),
- url:
- `${this.site}/${chaptersJson.manga.slug}/v${chapter.chapter_volume}/c${chapter.chapter_number}?bid=` +
- (chapter?.branch_id || ""),
- }),
- );
-
- novel.chapters = chapters.reverse();
- return novel;
- }
-
- async parseChapter(chapterUrl: string): Promise {
- const result = await fetchApi(
- chapterUrl + (this.ui ? "&ui=" + this.ui : ""),
- );
- const body = await result.text();
-
- const loadedCheerio = parseHTML(body);
-
- const baseUrl = this.site;
- loadedCheerio(".reader-container img").each(function () {
- const src =
- loadedCheerio(this).attr("data-src") || loadedCheerio(this).attr("src");
- if (!src?.startsWith("http")) {
- loadedCheerio(this).attr("src", baseUrl + src);
- } else {
- loadedCheerio(this).attr("src", src);
- }
- loadedCheerio(this).removeAttr("data-src");
- });
-
- const chapterText = loadedCheerio(".reader-container").html();
-
- return chapterText || "";
- }
-
- async searchNovels(
- searchTerm: string,
- //pageNo: number | undefined = 1,
- ): Promise {
- const result = await fetchApi(
- `${this.site}/search?q=${searchTerm}&type=manga`,
- );
- const body = (await result.json()) as Manga[];
- const novels: Plugin.NovelItem[] = [];
-
- body.forEach((novel) =>
- novels.push({
- name: novel?.rus_name || novel.name,
- cover: novel?.coverImage,
- url: novel?.href || this.site + "/" + novel.slug,
- }),
- );
-
- return novels;
- }
-
- fetchImage = fetchFile;
-
- filters = {
- sort: {
- label: "Сортировка",
- value: "",
- options: [
- { label: "Рейтинг", value: "rate" },
- { label: "Имя", value: "name" },
- { label: "Просмотры", value: "views" },
- { label: "Дате добавления", value: "created_at" },
- { label: "Дате обновления", value: "last_chapter_at" },
- { label: "Количество глав", value: "chap_count" },
- ],
- type: FilterTypes.Picker,
- },
- order: {
- label: "Порядок",
- value: "",
- options: [
- { label: "По убыванию", value: "desc" },
- { label: "По возрастанию", value: "asc" },
- ],
- type: FilterTypes.Picker,
- },
- type: {
- label: "Тип",
- value: [],
- options: [
- { label: "Авторский", value: "14" },
- { label: "Английский", value: "13" },
- { label: "Китай", value: "12" },
- { label: "Корея", value: "11" },
- { label: "Фанфик", value: "15" },
- { label: "Япония", value: "10" },
- ],
- type: FilterTypes.CheckboxGroup,
- },
- format: {
- label: "Формат выпуска",
- value: { include: [], exclude: [] },
- options: [
- { label: "4-кома (Ёнкома)", value: "1" },
- { label: "В цвете", value: "4" },
- { label: "Веб", value: "6" },
- { label: "Вебтун", value: "7" },
- { label: "Додзинси", value: "3" },
- { label: "Сборник", value: "2" },
- { label: "Сингл", value: "5" },
- ],
- type: FilterTypes.ExcludableCheckboxGroup,
- },
- status: {
- label: "Статус перевода",
- value: [],
- options: [
- { label: "Продолжается", value: "1" },
- { label: "Завершен", value: "2" },
- { label: "Заморожен", value: "3" },
- { label: "Заброшен", value: "4" },
- ],
- type: FilterTypes.CheckboxGroup,
- },
- statuss: {
- label: "Статус тайтла",
- value: [],
- options: [
- { label: "Онгоинг", value: "1" },
- { label: "Завершён", value: "2" },
- { label: "Анонс", value: "3" },
- { label: "Приостановлен", value: "4" },
- { label: "Выпуск прекращён", value: "5" },
- ],
- type: FilterTypes.CheckboxGroup,
- },
- genres: {
- label: "Жанры",
- value: { include: [], exclude: [] },
- options: [
- { 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" },
- ],
- type: FilterTypes.ExcludableCheckboxGroup,
- },
- tags: {
- label: "Теги",
- value: { include: [], exclude: [] },
- options: [
- { 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" },
- ],
- type: FilterTypes.ExcludableCheckboxGroup,
- },
- } satisfies Filters;
-}
-
-export default new RLIB();
-
-interface responseBook {
- hasStickyPermission: boolean;
- bookmark?: null;
- auth: boolean;
- comments_version: string;
- manga: Manga;
- chapters: Chapters;
- user?: User;
-}
-interface Manga {
- id: number;
- name: string;
- rusName?: string;
- rus_name?: string;
- engName?: string;
- slug: string;
- status: number;
- chapters_count: number;
- altNames?: string[] | null;
- coverImage?: string;
- href?: string;
-}
-interface Chapters {
- list?: ListEntity[] | null;
- teams?: TeamsEntity[] | null;
- branches?: BranchesEntity[] | null;
- is_paid?: null[] | null;
-}
-interface ListEntity {
- chapter_id: number;
- chapter_slug: string;
- chapter_name: string;
- chapter_number: string;
- chapter_volume: number;
- chapter_moderated: number;
- chapter_user_id: number;
- chapter_expired_at: string;
- chapter_scanlator_id: number;
- chapter_created_at: string;
- status?: null;
- price: number;
- branch_id: number;
- username: string;
-}
-interface TeamsEntity {
- name: string;
- alt_name: string;
- cover: string;
- slug: string;
- id: number;
- branch_id: number;
- sale: number;
- href: string;
- pivot: Pivot;
-}
-interface Pivot {
- manga_id: number;
- team_id: number;
-}
-interface BranchesEntity {
- id: number;
- manga_id: number;
- name: string;
- teams?: TeamsEntity1[] | null;
- is_subscribed: boolean;
-}
-interface TeamsEntity1 {
- id: number;
- name: string;
- slug: string;
- cover: string;
- branch_id: number;
- is_active: number;
-}
-interface User {
- id: number;
- avatar: string;
- access: boolean;
- isAdmin: boolean;
- paid: boolean;
-}
+import { Plugin } from "@typings/plugin";
+import { FilterTypes, Filters } from "@libs/filterInputs";
+import { fetchApi, fetchFile } from "@libs/fetch";
+import { NovelStatus } from "@libs/novelStatus";
+import { load as parseHTML } from "cheerio";
+import dayjs from "dayjs";
+
+class RLIB implements Plugin.PluginBase {
+ id = "RLIB";
+ name = "RanobeLib";
+ site = "https://ranobelib.me";
+ version = "1.0.0";
+ icon = "src/ru/ranobelib/icon.png";
+ ui: string | number | undefined = undefined;
+ userAgent = "";
+
+ async popularNovels(
+ pageNo: number,
+ {
+ showLatestNovels,
+ filters,
+ }: Plugin.PopularNovelsOptions,
+ ): Promise {
+ let url = `${this.site}/manga-list?sort=`;
+ url += showLatestNovels
+ ? "last_chapter_at"
+ : filters?.sort?.value || "rate";
+ url += "&dir=" + (filters?.order?.value || "desc");
+
+ if (filters.type?.value?.length) {
+ url += filters.type.value.map((i) => "&types[]=" + i).join("");
+ }
+
+ if (filters.format?.value?.include?.length) {
+ url += filters.format.value.include
+ .map((i) => "&format[include][]=" + i).join("");
+ }
+
+ if (filters.format?.value?.exclude?.length) {
+ url += filters.format.value.exclude
+ .map((i) => "&format[exclude][]=" + i).join("");
+ }
+
+ if (filters.status?.value?.length) {
+ url += filters.status.value.map((i) => "&status[]=" + i).join("");
+ }
+
+ if (filters.statuss?.value?.length) {
+ url += filters.statuss.value.map((i) => "&manga_status[]=" + i).join("");
+ }
+
+ if (filters.genres?.value?.include?.length) {
+ url += filters.genres.value.include
+ .map((i) => "&genres[include][]=" + i).join("");
+ }
+
+ if (filters.genres?.value?.exclude?.length) {
+ url += filters.genres.value.exclude
+ .map((i) => "&genres[exclude][]=" + i).join("");
+ }
+
+ if (filters.tags?.value?.include?.length) {
+ url += filters.tags.value.include
+ .map((i) => "&tags[include][]=" + i).join("");
+ }
+
+ if (filters.tags?.value?.exclude?.length) {
+ url += filters.tags.value.exclude
+ .map((i) => "&tags[exclude][]=" + i).join("");
+ }
+
+ url += "&page=" + pageNo;
+
+ const result = await fetchApi(url);
+ const body = await result.text();
+
+ const loadedCheerio = parseHTML(body);
+ this.ui = loadedCheerio("a.header-right-menu__item")
+ .attr("href")
+ ?.replace?.(/[^0-9]/g, "");
+
+ const novels: Plugin.NovelItem[] = [];
+ 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;
+ }
+
+ async parseNovelAndChapters(novelUrl: string): Promise {
+ const result = await fetchApi(novelUrl);
+ const body = await result.text();
+
+ const loadedCheerio = parseHTML(body);
+
+ const novel: Plugin.SourceNovel = {
+ 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.Ongoing
+ : NovelStatus.Completed;
+ } else if (name === "Автор") {
+ novel.author = loadedCheerio(this)
+ .find("div:nth-child(2)")
+ .text()
+ .trim();
+ }
+ });
+
+ const chapters: Plugin.ChapterItem[] = [];
+
+ let chaptersRaw: any = body.match(
+ /window.__DATA__ = [\s\S]*?window._SITE_COLOR_/gm,
+ );
+
+ chaptersRaw = chaptersRaw?.[0]
+ ?.replace("window.__DATA__ = ", "")
+ ?.replace("window._SITE_COLOR_", "")
+ ?.trim()
+ ?.slice(0, -1);
+
+ let chaptersJson: responseBook = JSON.parse(chaptersRaw);
+ this.ui = chaptersJson?.user?.id;
+
+ chaptersJson.chapters?.list?.forEach((chapter) =>
+ chapters.push({
+ name: `Том ${chapter.chapter_volume} Глава ${chapter.chapter_number} ${chapter.chapter_name}`?.trim(),
+ releaseTime: dayjs(chapter.chapter_created_at).format("LLL"),
+ url:
+ `${this.site}/${chaptersJson.manga.slug}/v${chapter.chapter_volume}/c${chapter.chapter_number}?bid=` +
+ (chapter?.branch_id || ""),
+ }),
+ );
+
+ novel.chapters = chapters.reverse();
+ return novel;
+ }
+
+ async parseChapter(chapterUrl: string): Promise {
+ const result = await fetchApi(
+ chapterUrl + (this.ui ? "&ui=" + this.ui : ""),
+ );
+ const body = await result.text();
+
+ const loadedCheerio = parseHTML(body);
+
+ const baseUrl = this.site;
+ loadedCheerio(".reader-container img").each(function () {
+ const src =
+ loadedCheerio(this).attr("data-src") || loadedCheerio(this).attr("src");
+ if (!src?.startsWith("http")) {
+ loadedCheerio(this).attr("src", baseUrl + src);
+ } else {
+ loadedCheerio(this).attr("src", src);
+ }
+ loadedCheerio(this).removeAttr("data-src");
+ });
+
+ const chapterText = loadedCheerio(".reader-container").html();
+
+ return chapterText || "";
+ }
+
+ async searchNovels(
+ searchTerm: string,
+ //pageNo: number | undefined = 1,
+ ): Promise {
+ const result = await fetchApi(
+ `${this.site}/search?q=${searchTerm}&type=manga`,
+ );
+ const body = (await result.json()) as Manga[];
+ const novels: Plugin.NovelItem[] = [];
+
+ body.forEach((novel) =>
+ novels.push({
+ name: novel?.rus_name || novel.name,
+ cover: novel?.coverImage,
+ url: novel?.href || this.site + "/" + novel.slug,
+ }),
+ );
+
+ return novels;
+ }
+
+ fetchImage = fetchFile;
+
+ filters = {
+ sort: {
+ label: "Сортировка",
+ value: "",
+ options: [
+ { label: "Рейтинг", value: "rate" },
+ { label: "Имя", value: "name" },
+ { label: "Просмотры", value: "views" },
+ { label: "Дате добавления", value: "created_at" },
+ { label: "Дате обновления", value: "last_chapter_at" },
+ { label: "Количество глав", value: "chap_count" },
+ ],
+ type: FilterTypes.Picker,
+ },
+ order: {
+ label: "Порядок",
+ value: "",
+ options: [
+ { label: "По убыванию", value: "desc" },
+ { label: "По возрастанию", value: "asc" },
+ ],
+ type: FilterTypes.Picker,
+ },
+ type: {
+ label: "Тип",
+ value: [],
+ options: [
+ { label: "Авторский", value: "14" },
+ { label: "Английский", value: "13" },
+ { label: "Китай", value: "12" },
+ { label: "Корея", value: "11" },
+ { label: "Фанфик", value: "15" },
+ { label: "Япония", value: "10" },
+ ],
+ type: FilterTypes.CheckboxGroup,
+ },
+ format: {
+ label: "Формат выпуска",
+ value: { include: [], exclude: [] },
+ options: [
+ { label: "4-кома (Ёнкома)", value: "1" },
+ { label: "В цвете", value: "4" },
+ { label: "Веб", value: "6" },
+ { label: "Вебтун", value: "7" },
+ { label: "Додзинси", value: "3" },
+ { label: "Сборник", value: "2" },
+ { label: "Сингл", value: "5" },
+ ],
+ type: FilterTypes.ExcludableCheckboxGroup,
+ },
+ status: {
+ label: "Статус перевода",
+ value: [],
+ options: [
+ { label: "Продолжается", value: "1" },
+ { label: "Завершен", value: "2" },
+ { label: "Заморожен", value: "3" },
+ { label: "Заброшен", value: "4" },
+ ],
+ type: FilterTypes.CheckboxGroup,
+ },
+ statuss: {
+ label: "Статус тайтла",
+ value: [],
+ options: [
+ { label: "Онгоинг", value: "1" },
+ { label: "Завершён", value: "2" },
+ { label: "Анонс", value: "3" },
+ { label: "Приостановлен", value: "4" },
+ { label: "Выпуск прекращён", value: "5" },
+ ],
+ type: FilterTypes.CheckboxGroup,
+ },
+ genres: {
+ label: "Жанры",
+ value: { include: [], exclude: [] },
+ options: [
+ { 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" },
+ ],
+ type: FilterTypes.ExcludableCheckboxGroup,
+ },
+ tags: {
+ label: "Теги",
+ value: { include: [], exclude: [] },
+ options: [
+ { 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" },
+ ],
+ type: FilterTypes.ExcludableCheckboxGroup,
+ },
+ } satisfies Filters;
+}
+
+export default new RLIB();
+
+interface responseBook {
+ hasStickyPermission: boolean;
+ bookmark?: null;
+ auth: boolean;
+ comments_version: string;
+ manga: Manga;
+ chapters: Chapters;
+ user?: User;
+}
+interface Manga {
+ id: number;
+ name: string;
+ rusName?: string;
+ rus_name?: string;
+ engName?: string;
+ slug: string;
+ status: number;
+ chapters_count: number;
+ altNames?: string[] | null;
+ coverImage?: string;
+ href?: string;
+}
+interface Chapters {
+ list?: ListEntity[] | null;
+ teams?: TeamsEntity[] | null;
+ branches?: BranchesEntity[] | null;
+ is_paid?: null[] | null;
+}
+interface ListEntity {
+ chapter_id: number;
+ chapter_slug: string;
+ chapter_name: string;
+ chapter_number: string;
+ chapter_volume: number;
+ chapter_moderated: number;
+ chapter_user_id: number;
+ chapter_expired_at: string;
+ chapter_scanlator_id: number;
+ chapter_created_at: string;
+ status?: null;
+ price: number;
+ branch_id: number;
+ username: string;
+}
+interface TeamsEntity {
+ name: string;
+ alt_name: string;
+ cover: string;
+ slug: string;
+ id: number;
+ branch_id: number;
+ sale: number;
+ href: string;
+ pivot: Pivot;
+}
+interface Pivot {
+ manga_id: number;
+ team_id: number;
+}
+interface BranchesEntity {
+ id: number;
+ manga_id: number;
+ name: string;
+ teams?: TeamsEntity1[] | null;
+ is_subscribed: boolean;
+}
+interface TeamsEntity1 {
+ id: number;
+ name: string;
+ slug: string;
+ cover: string;
+ branch_id: number;
+ is_active: number;
+}
+interface User {
+ id: number;
+ avatar: string;
+ access: boolean;
+ isAdmin: boolean;
+ paid: boolean;
+}
diff --git a/plugins/russian/ranoberf.ts b/plugins/russian/ranoberf.ts
index cdfa58c..504dda7 100644
--- a/plugins/russian/ranoberf.ts
+++ b/plugins/russian/ranoberf.ts
@@ -1,409 +1,408 @@
-import { Plugin } from "@typings/plugin";
-import { FilterTypes, Filters } from "@libs/filterInputs";
-import { defaultCover } from "@libs/defaultCover";
-import { fetchApi, fetchFile } from "@libs/fetch";
-import { NovelStatus } from "@libs/novelStatus";
-import { load as parseHTML } from "cheerio";
-import dayjs from "dayjs";
-
-class RNRF implements Plugin.PluginBase {
- id = "RNRF";
- name = "РанобэРФ";
- site = "https://ранобэ.рф";
- version = "1.0.0";
- icon = "src/ru/ranoberf/icon.png";
- userAgent = "";
- cookieString = "";
-
- async popularNovels(
- pageNo: number,
- { showLatestNovels, filters }: Plugin.PopularNovelsOptions,
- ): Promise {
- let url = this.site + "/books?order=";
- url += showLatestNovels
- ? "lastPublishedChapter"
- : filters?.sort?.value || "popular";
- url += "&page=" + pageNo;
-
- const result = await fetchApi(url);
- const body = await result.text();
-
- const loadedCheerio = parseHTML(body);
- const jsonRaw = loadedCheerio("#__NEXT_DATA__").html();
- const json: response = JSON.parse(jsonRaw || "{}");
-
- const novels: Plugin.NovelItem[] = [];
- json.props.pageProps?.totalData?.items?.forEach((novel) =>
- novels.push({
- name: novel.title,
- cover: novel?.verticalImage?.url
- ? this.site + novel.verticalImage.url
- : defaultCover,
- url: this.site + "/" + novel.slug,
- }),
- );
-
- return novels;
- }
-
- async parseNovelAndChapters(novelUrl: string): Promise {
- const result = await fetchApi(novelUrl);
- const body = await result.text();
-
- const loadedCheerio = parseHTML(body);
- const jsonRaw = loadedCheerio("#__NEXT_DATA__").html();
- const book = (JSON.parse(jsonRaw || "{}") as response).props.pageProps.book;
-
- const novel: Plugin.SourceNovel = {
- url: novelUrl,
- name: book?.title,
- cover: book?.verticalImage?.url
- ? this.site + book.verticalImage.url
- : defaultCover,
- summary: book?.description,
- author: book?.author || "",
- genres: book?.genres.map((item) => item.title).join(", "),
- status: book?.additionalInfo.includes("Активен")
- ? NovelStatus.Ongoing
- : NovelStatus.Completed,
- };
-
- const chapters: Plugin.ChapterItem[] = [];
-
- book?.chapters?.forEach((chapter) => {
- if (!chapter.isDonate || chapter.isUserPaid) {
- chapters.push({
- name: chapter.title,
- releaseTime: dayjs(chapter.publishedAt).format("LLL"),
- url: this.site + chapter.url,
- });
- }
- });
-
- novel.chapters = chapters.reverse();
- return novel;
- }
-
- async parseChapter(chapterUrl: string): Promise {
- const result = await fetchApi(chapterUrl);
- const body = await result.text();
-
- let loadedCheerio = parseHTML(body);
- const jsonRaw = loadedCheerio("#__NEXT_DATA__").html();
- const json: response = JSON.parse(jsonRaw || "{}");
-
- loadedCheerio = parseHTML(
- json.props.pageProps?.chapter?.content?.text || "",
- );
-
- const baseUrl = this.site;
- loadedCheerio("img").each(function () {
- if (!loadedCheerio(this).attr("src")?.startsWith("http")) {
- const src = loadedCheerio(this).attr("src");
- loadedCheerio(this).attr("src", baseUrl + src);
- }
- });
-
- const chapterText = loadedCheerio.html();
- return chapterText;
- }
-
- async searchNovels(
- searchTerm: string,
- //pageNo: number | undefined = 1,
- ): Promise {
- const url = `${this.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 = await fetchApi(url);
- const body = (await result.json()) as { items: Item[] };
- const novels: Plugin.NovelItem[] = [];
-
- body.items.forEach((novel) =>
- novels.push({
- name: novel.title,
- cover: novel?.verticalImage?.url
- ? this.site + novel.verticalImage.url
- : defaultCover,
- url: this.site + "/" + novel.slug,
- }),
- );
-
- return novels;
- }
- fetchImage = fetchFile;
-
- filters = {
- sort: {
- label: "Сортировка",
- value: "",
- options: [
- { label: "Рейтинг", value: "popular" },
- { label: "Дате добавления", value: "new" },
- { label: "Дате обновления", value: "lastPublishedChapter" },
- { label: "Законченные", value: "completed" },
- ],
- type: FilterTypes.Picker,
- },
- } satisfies Filters;
-}
-export default new RNRF();
-
-interface response {
- props: Props;
- page: string;
- query: Query;
- buildId: string;
- isFallback: boolean;
- gssp: boolean;
- appGip: boolean;
- dynamicIds?: string[];
-}
-
-interface Props {
- pageProps: PageProps;
- isMobile: boolean;
- theme: string;
- __N_SSP: boolean;
-}
-
-interface PageProps {
- initialReduxState: InitialReduxState;
- book?: PagePropsBook;
- totalData?: TotalData;
- layoutViewCookies?: string;
- displayBanner?: boolean;
- chapter?: PagePropsChapter;
-}
-
-interface PagePropsBook {
- id: number;
- countryId: number;
- creatorId: number;
- lastChapterId: number;
- sourceId: number;
- imgVerticalId: number;
- imgHorizontalId: number;
- imgSquareId: number;
- imageVerticalId: number;
- imageHorizontalId: number;
- title: string;
- titleEn: string;
- fullTitle: string;
- fullTitleEn: string;
- description: string;
- slug: string;
- author: string;
- additionalInfo: string;
- importantInfo: string;
- status: string;
- views: number;
- likes: number;
- dislikes: number;
- intervalSec: number;
- intervalForNextFreeChapterSec: number;
- chapterCost: number;
- chapterPrice: number;
- chapterPriceCollected: number;
- maxSubscriptionChapters: number;
- maxDonateChapters: number;
- isDisplayOnMainPage: boolean;
- withoutSchedule: boolean;
- nextFreeChapterPublishedAt: null;
- createdAt: Date;
- updatedAt: Date;
- userRating: null;
- userBookmark: null;
- country: Country;
- genres: Genre[];
- timer: Timer;
- chapters: ChapterElement[];
- verticalImage: Image;
- horizontalImage: Image;
- squareImage: Image;
-}
-
-interface ChapterElement {
- id: number;
- bookId: number;
- title: string;
- url: string;
- numberChapter: string;
- tom: number | null;
- chapterShortNumber: number | null;
- isDonate: boolean;
- isSponsored: boolean;
- isSubscription: boolean;
- isEdited: boolean;
- publishedAt: Date;
- price: number;
- views: number;
- isUserPaid?: boolean;
-}
-
-interface Country {
- id: number;
- title: string;
- code: string;
-}
-
-interface Genre {
- id: number;
- title: string;
- slug: string;
-}
-
-interface Image {
- id: number;
- alt: string;
- path: string;
- name: string;
- url: string;
-}
-
-interface Timer {
- value: null;
- for: null;
- message: string;
-}
-
-interface PagePropsChapter {
- id: number;
- bookId: number;
- editorId: null;
- translatorId: number;
- parserChapterId: null;
- title: string;
- slug: string;
- status: string;
- tom: null;
- views: number;
- isSponsored: boolean;
- isSubscription: boolean;
- isDonate: boolean;
- isIndexing: boolean;
- publishedAt: Date;
- changeAvailabilityAt: null;
- createdAt: Date;
- updatedAt: Date;
- numberChapter: string;
- price: number;
- content: Content;
- book: ChapterBook;
- userBookmark: null;
- isUserPaid: boolean;
- nextChapter: null;
- previousChapter: PreviousChapter;
- corrections: null;
-}
-
-interface ChapterBook {
- id: number;
- title: string;
- titleEn: string;
- url: string;
-}
-
-interface Content {
- id: number;
- text: string;
- symbolsCount: number;
-}
-
-interface PreviousChapter {
- id: number;
- title: string;
- views: number;
- publishedAt: Date;
- url: string;
- numberChapter: string;
-}
-
-interface InitialReduxState {
- data?: Data;
- auth: Auth;
- banners?: Banners;
- corrections?: Corrections;
- readerSettings?: ReaderSettings;
-}
-
-interface Auth {
- isAuth: boolean;
- user: null;
-}
-
-interface Banners {
- displaySale: boolean;
-}
-
-interface Corrections {
- items: null;
- data: null;
-}
-
-interface Data {
- bookPage: BookPage | null;
- chapterPage: ChapterPage | null;
-}
-
-interface BookPage {
- bookId: number;
- bookmark: null;
-}
-
-interface ChapterPage {
- chapterId: number;
- bookId: number;
- bookmark: null;
-}
-
-interface ReaderSettings {
- fontSize: number;
- lineHeight: number;
- textIndent: number;
- sidebarHide: number;
- textAlign: string;
-}
-
-interface TotalData {
- items: Item[];
- _links: Links;
- pagesData: PagesData;
-}
-
-interface Links {
- self: First;
- first: First;
- last: First;
- next: First;
-}
-
-interface First {
- href: string;
-}
-
-interface Item {
- id: number;
- title: string;
- description: string;
- slug: string;
- url: string;
- status: string;
- dislikes: number;
- likes: number;
- userRating: null;
- lastChapter: ChapterElement;
- verticalImage: Image;
- horizontalImage: Image;
- squareImage: Image;
-}
-
-interface PagesData {
- totalCount: number;
- pageCount: number;
- currentPage: number;
- perPage: number;
-}
-
-interface Query {
- book?: string;
- chapter?: string;
-}
+import { Plugin } from "@typings/plugin";
+import { FilterTypes, Filters } from "@libs/filterInputs";
+import { defaultCover } from "@libs/defaultCover";
+import { fetchApi, fetchFile } from "@libs/fetch";
+import { NovelStatus } from "@libs/novelStatus";
+import { load as parseHTML } from "cheerio";
+import dayjs from "dayjs";
+
+class RNRF implements Plugin.PluginBase {
+ id = "RNRF";
+ name = "РанобэРФ";
+ site = "https://ранобэ.рф";
+ version = "1.0.0";
+ icon = "src/ru/ranoberf/icon.png";
+ userAgent = "";
+
+ async popularNovels(
+ pageNo: number,
+ { showLatestNovels, filters }: Plugin.PopularNovelsOptions,
+ ): Promise {
+ let url = this.site + "/books?order=";
+ url += showLatestNovels
+ ? "lastPublishedChapter"
+ : filters?.sort?.value || "popular";
+ url += "&page=" + pageNo;
+
+ const result = await fetchApi(url);
+ const body = await result.text();
+
+ const loadedCheerio = parseHTML(body);
+ const jsonRaw = loadedCheerio("#__NEXT_DATA__").html();
+ const json: response = JSON.parse(jsonRaw || "{}");
+
+ const novels: Plugin.NovelItem[] = [];
+ json.props.pageProps?.totalData?.items?.forEach((novel) =>
+ novels.push({
+ name: novel.title,
+ cover: novel?.verticalImage?.url
+ ? this.site + novel.verticalImage.url
+ : defaultCover,
+ url: this.site + "/" + novel.slug,
+ }),
+ );
+
+ return novels;
+ }
+
+ async parseNovelAndChapters(novelUrl: string): Promise {
+ const result = await fetchApi(novelUrl);
+ const body = await result.text();
+
+ const loadedCheerio = parseHTML(body);
+ const jsonRaw = loadedCheerio("#__NEXT_DATA__").html();
+ const book = (JSON.parse(jsonRaw || "{}") as response).props.pageProps.book;
+
+ const novel: Plugin.SourceNovel = {
+ url: novelUrl,
+ name: book?.title,
+ cover: book?.verticalImage?.url
+ ? this.site + book.verticalImage.url
+ : defaultCover,
+ summary: book?.description,
+ author: book?.author || "",
+ genres: book?.genres.map((item) => item.title).join(", "),
+ status: book?.additionalInfo.includes("Активен")
+ ? NovelStatus.Ongoing
+ : NovelStatus.Completed,
+ };
+
+ const chapters: Plugin.ChapterItem[] = [];
+
+ book?.chapters?.forEach((chapter) => {
+ if (!chapter.isDonate || chapter.isUserPaid) {
+ chapters.push({
+ name: chapter.title,
+ releaseTime: dayjs(chapter.publishedAt).format("LLL"),
+ url: this.site + chapter.url,
+ });
+ }
+ });
+
+ novel.chapters = chapters.reverse();
+ return novel;
+ }
+
+ async parseChapter(chapterUrl: string): Promise {
+ const result = await fetchApi(chapterUrl);
+ const body = await result.text();
+
+ let loadedCheerio = parseHTML(body);
+ const jsonRaw = loadedCheerio("#__NEXT_DATA__").html();
+ const json: response = JSON.parse(jsonRaw || "{}");
+
+ loadedCheerio = parseHTML(
+ json.props.pageProps?.chapter?.content?.text || "",
+ );
+
+ const baseUrl = this.site;
+ loadedCheerio("img").each(function () {
+ if (!loadedCheerio(this).attr("src")?.startsWith("http")) {
+ const src = loadedCheerio(this).attr("src");
+ loadedCheerio(this).attr("src", baseUrl + src);
+ }
+ });
+
+ const chapterText = loadedCheerio.html();
+ return chapterText;
+ }
+
+ async searchNovels(
+ searchTerm: string,
+ //pageNo: number | undefined = 1,
+ ): Promise {
+ const url = `${this.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 = await fetchApi(url);
+ const body = (await result.json()) as { items: Item[] };
+ const novels: Plugin.NovelItem[] = [];
+
+ body.items.forEach((novel) =>
+ novels.push({
+ name: novel.title,
+ cover: novel?.verticalImage?.url
+ ? this.site + novel.verticalImage.url
+ : defaultCover,
+ url: this.site + "/" + novel.slug,
+ }),
+ );
+
+ return novels;
+ }
+ fetchImage = fetchFile;
+
+ filters = {
+ sort: {
+ label: "Сортировка",
+ value: "",
+ options: [
+ { label: "Рейтинг", value: "popular" },
+ { label: "Дате добавления", value: "new" },
+ { label: "Дате обновления", value: "lastPublishedChapter" },
+ { label: "Законченные", value: "completed" },
+ ],
+ type: FilterTypes.Picker,
+ },
+ } satisfies Filters;
+}
+export default new RNRF();
+
+interface response {
+ props: Props;
+ page: string;
+ query: Query;
+ buildId: string;
+ isFallback: boolean;
+ gssp: boolean;
+ appGip: boolean;
+ dynamicIds?: string[];
+}
+
+interface Props {
+ pageProps: PageProps;
+ isMobile: boolean;
+ theme: string;
+ __N_SSP: boolean;
+}
+
+interface PageProps {
+ initialReduxState: InitialReduxState;
+ book?: PagePropsBook;
+ totalData?: TotalData;
+ layoutViewCookies?: string;
+ displayBanner?: boolean;
+ chapter?: PagePropsChapter;
+}
+
+interface PagePropsBook {
+ id: number;
+ countryId: number;
+ creatorId: number;
+ lastChapterId: number;
+ sourceId: number;
+ imgVerticalId: number;
+ imgHorizontalId: number;
+ imgSquareId: number;
+ imageVerticalId: number;
+ imageHorizontalId: number;
+ title: string;
+ titleEn: string;
+ fullTitle: string;
+ fullTitleEn: string;
+ description: string;
+ slug: string;
+ author: string;
+ additionalInfo: string;
+ importantInfo: string;
+ status: string;
+ views: number;
+ likes: number;
+ dislikes: number;
+ intervalSec: number;
+ intervalForNextFreeChapterSec: number;
+ chapterCost: number;
+ chapterPrice: number;
+ chapterPriceCollected: number;
+ maxSubscriptionChapters: number;
+ maxDonateChapters: number;
+ isDisplayOnMainPage: boolean;
+ withoutSchedule: boolean;
+ nextFreeChapterPublishedAt: null;
+ createdAt: Date;
+ updatedAt: Date;
+ userRating: null;
+ userBookmark: null;
+ country: Country;
+ genres: Genre[];
+ timer: Timer;
+ chapters: ChapterElement[];
+ verticalImage: Image;
+ horizontalImage: Image;
+ squareImage: Image;
+}
+
+interface ChapterElement {
+ id: number;
+ bookId: number;
+ title: string;
+ url: string;
+ numberChapter: string;
+ tom: number | null;
+ chapterShortNumber: number | null;
+ isDonate: boolean;
+ isSponsored: boolean;
+ isSubscription: boolean;
+ isEdited: boolean;
+ publishedAt: Date;
+ price: number;
+ views: number;
+ isUserPaid?: boolean;
+}
+
+interface Country {
+ id: number;
+ title: string;
+ code: string;
+}
+
+interface Genre {
+ id: number;
+ title: string;
+ slug: string;
+}
+
+interface Image {
+ id: number;
+ alt: string;
+ path: string;
+ name: string;
+ url: string;
+}
+
+interface Timer {
+ value: null;
+ for: null;
+ message: string;
+}
+
+interface PagePropsChapter {
+ id: number;
+ bookId: number;
+ editorId: null;
+ translatorId: number;
+ parserChapterId: null;
+ title: string;
+ slug: string;
+ status: string;
+ tom: null;
+ views: number;
+ isSponsored: boolean;
+ isSubscription: boolean;
+ isDonate: boolean;
+ isIndexing: boolean;
+ publishedAt: Date;
+ changeAvailabilityAt: null;
+ createdAt: Date;
+ updatedAt: Date;
+ numberChapter: string;
+ price: number;
+ content: Content;
+ book: ChapterBook;
+ userBookmark: null;
+ isUserPaid: boolean;
+ nextChapter: null;
+ previousChapter: PreviousChapter;
+ corrections: null;
+}
+
+interface ChapterBook {
+ id: number;
+ title: string;
+ titleEn: string;
+ url: string;
+}
+
+interface Content {
+ id: number;
+ text: string;
+ symbolsCount: number;
+}
+
+interface PreviousChapter {
+ id: number;
+ title: string;
+ views: number;
+ publishedAt: Date;
+ url: string;
+ numberChapter: string;
+}
+
+interface InitialReduxState {
+ data?: Data;
+ auth: Auth;
+ banners?: Banners;
+ corrections?: Corrections;
+ readerSettings?: ReaderSettings;
+}
+
+interface Auth {
+ isAuth: boolean;
+ user: null;
+}
+
+interface Banners {
+ displaySale: boolean;
+}
+
+interface Corrections {
+ items: null;
+ data: null;
+}
+
+interface Data {
+ bookPage: BookPage | null;
+ chapterPage: ChapterPage | null;
+}
+
+interface BookPage {
+ bookId: number;
+ bookmark: null;
+}
+
+interface ChapterPage {
+ chapterId: number;
+ bookId: number;
+ bookmark: null;
+}
+
+interface ReaderSettings {
+ fontSize: number;
+ lineHeight: number;
+ textIndent: number;
+ sidebarHide: number;
+ textAlign: string;
+}
+
+interface TotalData {
+ items: Item[];
+ _links: Links;
+ pagesData: PagesData;
+}
+
+interface Links {
+ self: First;
+ first: First;
+ last: First;
+ next: First;
+}
+
+interface First {
+ href: string;
+}
+
+interface Item {
+ id: number;
+ title: string;
+ description: string;
+ slug: string;
+ url: string;
+ status: string;
+ dislikes: number;
+ likes: number;
+ userRating: null;
+ lastChapter: ChapterElement;
+ verticalImage: Image;
+ horizontalImage: Image;
+ squareImage: Image;
+}
+
+interface PagesData {
+ totalCount: number;
+ pageCount: number;
+ currentPage: number;
+ perPage: number;
+}
+
+interface Query {
+ book?: string;
+ chapter?: string;
+}
diff --git a/plugins/russian/renovels.ts b/plugins/russian/renovels.ts
index bb156cf..83b070a 100644
--- a/plugins/russian/renovels.ts
+++ b/plugins/russian/renovels.ts
@@ -1,1106 +1,1105 @@
-import { Plugin } from "@typings/plugin";
-import { FilterTypes, Filters } from "@libs/filterInputs";
-import { fetchApi, fetchFile } from "@libs/fetch";
-import { NovelStatus } from "@libs/novelStatus";
-import dayjs from "dayjs";
-
-class ReN implements Plugin.PluginBase {
- id = "ReN";
- name = "Renovels";
- site = "https://renovels.org";
- version = "1.0.0";
- icon = "src/ru/renovels/icon.png";
- userAgent = "";
- cookieString = "";
-
- async popularNovels(
- pageNo: number,
- {
- showLatestNovels,
- filters,
- }: Plugin.PopularNovelsOptions,
- ): Promise {
- let url = this.site + "/api/search/catalog/?count=30&ordering=";
- url += filters?.order?.value
- ? (filters.order.value as string).replace("+", "")
- : "-";
- url += showLatestNovels ? "chapter_date" : filters?.sort?.value || "rating";
-
- if (filters?.genres?.value?.include?.length) {
- url += filters.genres.value.include.map((i) => "&genres=" + i).join("");
- }
-
- if (filters?.genres?.value?.exclude?.length) {
- url += filters.genres.value.exclude
- .map((i) => "&exclude_genres=" + i).join("");
- }
-
- if (filters?.status?.value?.length) {
- url += filters.status.value.map((i) => "&status=" + i).join("");
- }
-
- if (filters?.types?.value?.length) {
- url += filters.types.value.map((i) => "&types=" + i).join("");
- }
-
- if (filters?.categories?.value?.include?.length) {
- url += filters.categories.value.include
- .map((i) => "&categories=" + i).join("");
- }
-
- if (filters?.categories?.value?.exclude?.length) {
- url += filters.categories.value.exclude
- .map((i) => "&exclude_categories=" + i).join("");
- }
-
- if (filters?.age_limit?.value?.length) {
- url += filters.age_limit.value.map((i) => "&age_limit=" + i).join("");
- }
-
- url += "&page=" + pageNo;
-
- const result = await fetchApi(url);
- const body = (await result.json()) as { content: responseNovels[] };
-
- const novels: Plugin.NovelItem[] = [];
-
- body.content.forEach((novel) =>
- novels.push({
- name: novel.main_name || novel.secondary_name,
- cover: this.site + (novel.img?.high || novel.img?.mid || novel.img.low),
- url: this.site + "/novel/" + novel.dir,
- }),
- );
-
- return novels;
- }
-
- async parseNovelAndChapters(novelUrl: string): Promise {
- const novelID = novelUrl.split("/")[4];
- const result = await fetchApi(this.site + "/api/titles/" + novelID);
- const body = (await result.json()) as { content: responseNovel };
-
- const novel: Plugin.SourceNovel = {
- url: novelUrl,
- name: body.content.main_name || body.content.secondary_name,
- summary: body.content.description,
- cover:
- this.site +
- (body.content.img?.high ||
- body.content.img?.mid ||
- body.content.img.low),
- status:
- body.content.status.name === "Продолжается"
- ? NovelStatus.Ongoing
- : NovelStatus.Completed,
- };
-
- const tags = [body.content?.genres, body.content?.categories]
- .flat()
- .map((tags) => tags?.name)
- .filter((tags) => tags);
-
- if (tags.length) {
- novel.genres = tags.join(",");
- }
-
- const all = Math.floor(body.content.count_chapters / 100 + 1);
- const branch_id = body.content.branches?.[0]?.id || body.content.id;
- const chapters: Plugin.ChapterItem[] = [];
-
- for (let i = 0; i < all; i++) {
- const chapterResult = await fetchApi(
- this.site +
- "/api/titles/chapters/?branch_id=" +
- branch_id +
- "&count=100&page=" +
- (i + 1),
- );
- const volumes = (await chapterResult.json()) as {
- content: responseСhapters[];
- };
-
- volumes.content.forEach((chapter) => {
- if (!chapter.is_paid || chapter.is_bought) {
- chapters.push({
- name: `Том ${chapter.tome} Глава ${chapter.chapter} ${chapter.name}`?.trim(),
- releaseTime: dayjs(chapter.upload_date).format("LLL"),
- url: `${this.site}/novel/${novelID}/${chapter.id}/`,
- });
- }
- });
- }
-
- novel.chapters = chapters.reverse();
- return novel;
- }
-
- async parseChapter(chapterUrl: string): Promise {
- const url = this.site + "/api/titles/chapters/" + chapterUrl.split("/")[5];
- const result = await fetchApi(url);
- const body = (await result.json()) as { content: responseСhapter };
-
- return body.content.content;
- }
-
- async searchNovels(
- searchTerm: string,
- pageNo: number | undefined = 1,
- ): Promise {
- const url = `${this.site}/api/search/?query=${searchTerm}&count=100&field=titles&page=${pageNo}`;
- const result = await fetchApi(url);
- const body = (await result.json()) as { content: responseNovels[] };
- const novels: Plugin.NovelItem[] = [];
-
- body.content.forEach((novel) =>
- novels.push({
- name: novel.main_name || novel.secondary_name,
- cover: this.site + (novel.img?.high || novel.img?.mid || novel.img.low),
- url: this.site + "/novel/" + novel.dir,
- }),
- );
-
- return novels;
- }
-
- fetchImage = fetchFile;
-
- filters = {
- sort: {
- label: "Сортировка",
- value: "",
- options: [
- { label: "Рейтинг", value: "rating" },
- { label: "Просмотры", value: "views" },
- { label: "Лайкам", value: "votes" },
- { label: "Дате добавления", value: "id" },
- { label: "Дате обновления", value: "chapter_date" },
- { label: "Количество глав", value: "count_chapters" },
- ],
- type: FilterTypes.Picker,
- },
- order: {
- label: "Порядок",
- value: "",
- options: [
- { label: "По убыванию", value: "-" },
- { label: "По возрастанию", value: "+" },
- ],
- type: FilterTypes.Picker,
- },
- genres: {
- label: "Жанры:",
- value: { include: [], exclude: [] },
- options: [
- { 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" },
- ],
- type: FilterTypes.ExcludableCheckboxGroup,
- },
- categories: {
- label: "Тэги:",
- value: { include: [], exclude: [] },
- options: [
- { 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" },
- ],
- type: FilterTypes.ExcludableCheckboxGroup,
- },
- types: {
- label: "Типы:",
- value: [],
- options: [
- { label: "Авторское", value: "1" },
- { label: "Другое", value: "7" },
- { label: "Запад", value: "5" },
- { label: "Китай", value: "4" },
- { label: "Корея", value: "3" },
- { label: "Фанфики", value: "6" },
- { label: "Япония", value: "2" },
- ],
- type: FilterTypes.CheckboxGroup,
- },
- status: {
- label: "Статус проекта:",
- value: [],
- options: [
- { label: "Анонс", value: "4" },
- { label: "Закончен", value: "0" },
- { label: "Заморожен", value: "2" },
- { label: "Лицензировано", value: "5" },
- { label: "Нет переводчика", value: "3" },
- { label: "Продолжается", value: "1" },
- ],
- type: FilterTypes.CheckboxGroup,
- },
- age_limit: {
- label: "Возрастной рейтинг:",
- value: [],
- options: [
- { label: "16+", value: "1" },
- { label: "18+", value: "2" },
- { label: "Для всех", value: "0" },
- ],
- type: FilterTypes.CheckboxGroup,
- },
- } satisfies Filters;
-}
-
-export default new ReN();
-
-interface responseNovels {
- id: number;
- secondary_name: string;
- main_name: string;
- dir: string;
- is_licensed: boolean;
- issue_year: number;
- avg_rating: string;
- admin_rating: string;
- type: string;
- total_views: number;
- total_votes: number;
- cover_high: string;
- cover_mid: string;
- cover_low: string;
- is_yaoi: boolean;
- is_erotic: boolean;
- bookmark_type?: null;
- genres?: ItemEntity[] | null;
- img: Img;
- categories?: ItemEntity[] | null;
- rus_name?: string;
- en_name?: string;
-}
-
-interface Img {
- high?: string;
- mid?: string;
- low: string;
-}
-
-interface responseNovel {
- id: number;
- img: Img;
- secondary_name: string;
- main_name: string;
- another_name: string;
- dir: string;
- description: string;
- issue_year: number;
- avg_rating: string;
- admin_rating: string;
- count_rating: number;
- age_limit: number;
- status: ItemEntity;
- count_bookmarks: number;
- total_votes: number;
- total_views: number;
- type: ItemEntity;
- genres?: ItemEntity[] | null;
- categories?: ItemEntity[] | null;
- publishers?: PublishersEntity[] | null;
- bookmark_type?: null;
- branches?: BranchesEntity[] | null;
- count_chapters: number;
- first_chapter: FirstChapter;
- continue_reading?: null;
- is_licensed: boolean;
- newlate_id?: null;
- newlate_title?: null;
- related?: null;
- uploaded: number;
- can_post_comments: boolean;
- adaptation: Adaptation | null;
-}
-
-interface Adaptation {
- main_name: string;
- secondary_name: string;
- dir: string;
- img: string;
-}
-
-interface ItemEntity {
- id: number;
- name: string;
-}
-interface PublishersEntity {
- id: number;
- name: string;
- img: string;
- dir: string;
- tagline: string;
- type: string;
-}
-interface BranchesEntity {
- id: number;
- img: string;
- publishers?: PublishersEntity[] | null;
- subscribed: boolean;
- total_votes: number;
- count_chapters: number;
-}
-interface FirstChapter {
- id: number;
- tome: number;
- chapter: string;
-}
-
-interface responseСhapters {
- id: number;
- rated?: null;
- viewed?: null;
- is_bought?: boolean | null;
- publishers?: PublishersEntity[] | null;
- tome: number;
- index: number;
- chapter: string;
- name: string;
- price?: null | number;
- score: number;
- pub_date?: null;
- upload_date: string;
- is_paid: boolean;
-}
-
-interface responseСhapter {
- id: number;
- chapter: string;
- name: string;
- content: string;
- score: number;
- upload_date: string;
- is_paid: boolean;
- title_id: number;
- volume_id: number;
- branch_id: number;
- price?: null;
- pub_date?: null;
- index: number;
- publishers?: PublishersEntity[] | null;
- tome: number;
-}
+import { Plugin } from "@typings/plugin";
+import { FilterTypes, Filters } from "@libs/filterInputs";
+import { fetchApi, fetchFile } from "@libs/fetch";
+import { NovelStatus } from "@libs/novelStatus";
+import dayjs from "dayjs";
+
+class ReN implements Plugin.PluginBase {
+ id = "ReN";
+ name = "Renovels";
+ site = "https://renovels.org";
+ version = "1.0.0";
+ icon = "src/ru/renovels/icon.png";
+ userAgent = "";
+
+ async popularNovels(
+ pageNo: number,
+ {
+ showLatestNovels,
+ filters,
+ }: Plugin.PopularNovelsOptions,
+ ): Promise {
+ let url = this.site + "/api/search/catalog/?count=30&ordering=";
+ url += filters?.order?.value
+ ? (filters.order.value as string).replace("+", "")
+ : "-";
+ url += showLatestNovels ? "chapter_date" : filters?.sort?.value || "rating";
+
+ if (filters?.genres?.value?.include?.length) {
+ url += filters.genres.value.include.map((i) => "&genres=" + i).join("");
+ }
+
+ if (filters?.genres?.value?.exclude?.length) {
+ url += filters.genres.value.exclude
+ .map((i) => "&exclude_genres=" + i).join("");
+ }
+
+ if (filters?.status?.value?.length) {
+ url += filters.status.value.map((i) => "&status=" + i).join("");
+ }
+
+ if (filters?.types?.value?.length) {
+ url += filters.types.value.map((i) => "&types=" + i).join("");
+ }
+
+ if (filters?.categories?.value?.include?.length) {
+ url += filters.categories.value.include
+ .map((i) => "&categories=" + i).join("");
+ }
+
+ if (filters?.categories?.value?.exclude?.length) {
+ url += filters.categories.value.exclude
+ .map((i) => "&exclude_categories=" + i).join("");
+ }
+
+ if (filters?.age_limit?.value?.length) {
+ url += filters.age_limit.value.map((i) => "&age_limit=" + i).join("");
+ }
+
+ url += "&page=" + pageNo;
+
+ const result = await fetchApi(url);
+ const body = (await result.json()) as { content: responseNovels[] };
+
+ const novels: Plugin.NovelItem[] = [];
+
+ body.content.forEach((novel) =>
+ novels.push({
+ name: novel.main_name || novel.secondary_name,
+ cover: this.site + (novel.img?.high || novel.img?.mid || novel.img.low),
+ url: this.site + "/novel/" + novel.dir,
+ }),
+ );
+
+ return novels;
+ }
+
+ async parseNovelAndChapters(novelUrl: string): Promise {
+ const novelID = novelUrl.split("/")[4];
+ const result = await fetchApi(this.site + "/api/titles/" + novelID);
+ const body = (await result.json()) as { content: responseNovel };
+
+ const novel: Plugin.SourceNovel = {
+ url: novelUrl,
+ name: body.content.main_name || body.content.secondary_name,
+ summary: body.content.description,
+ cover:
+ this.site +
+ (body.content.img?.high ||
+ body.content.img?.mid ||
+ body.content.img.low),
+ status:
+ body.content.status.name === "Продолжается"
+ ? NovelStatus.Ongoing
+ : NovelStatus.Completed,
+ };
+
+ const tags = [body.content?.genres, body.content?.categories]
+ .flat()
+ .map((tags) => tags?.name)
+ .filter((tags) => tags);
+
+ if (tags.length) {
+ novel.genres = tags.join(",");
+ }
+
+ const all = Math.floor(body.content.count_chapters / 100 + 1);
+ const branch_id = body.content.branches?.[0]?.id || body.content.id;
+ const chapters: Plugin.ChapterItem[] = [];
+
+ for (let i = 0; i < all; i++) {
+ const chapterResult = await fetchApi(
+ this.site +
+ "/api/titles/chapters/?branch_id=" +
+ branch_id +
+ "&count=100&page=" +
+ (i + 1),
+ );
+ const volumes = (await chapterResult.json()) as {
+ content: responseСhapters[];
+ };
+
+ volumes.content.forEach((chapter) => {
+ if (!chapter.is_paid || chapter.is_bought) {
+ chapters.push({
+ name: `Том ${chapter.tome} Глава ${chapter.chapter} ${chapter.name}`?.trim(),
+ releaseTime: dayjs(chapter.upload_date).format("LLL"),
+ url: `${this.site}/novel/${novelID}/${chapter.id}/`,
+ });
+ }
+ });
+ }
+
+ novel.chapters = chapters.reverse();
+ return novel;
+ }
+
+ async parseChapter(chapterUrl: string): Promise {
+ const url = this.site + "/api/titles/chapters/" + chapterUrl.split("/")[5];
+ const result = await fetchApi(url);
+ const body = (await result.json()) as { content: responseСhapter };
+
+ return body.content.content;
+ }
+
+ async searchNovels(
+ searchTerm: string,
+ pageNo: number | undefined = 1,
+ ): Promise {
+ const url = `${this.site}/api/search/?query=${searchTerm}&count=100&field=titles&page=${pageNo}`;
+ const result = await fetchApi(url);
+ const body = (await result.json()) as { content: responseNovels[] };
+ const novels: Plugin.NovelItem[] = [];
+
+ body.content.forEach((novel) =>
+ novels.push({
+ name: novel.main_name || novel.secondary_name,
+ cover: this.site + (novel.img?.high || novel.img?.mid || novel.img.low),
+ url: this.site + "/novel/" + novel.dir,
+ }),
+ );
+
+ return novels;
+ }
+
+ fetchImage = fetchFile;
+
+ filters = {
+ sort: {
+ label: "Сортировка",
+ value: "",
+ options: [
+ { label: "Рейтинг", value: "rating" },
+ { label: "Просмотры", value: "views" },
+ { label: "Лайкам", value: "votes" },
+ { label: "Дате добавления", value: "id" },
+ { label: "Дате обновления", value: "chapter_date" },
+ { label: "Количество глав", value: "count_chapters" },
+ ],
+ type: FilterTypes.Picker,
+ },
+ order: {
+ label: "Порядок",
+ value: "",
+ options: [
+ { label: "По убыванию", value: "-" },
+ { label: "По возрастанию", value: "+" },
+ ],
+ type: FilterTypes.Picker,
+ },
+ genres: {
+ label: "Жанры:",
+ value: { include: [], exclude: [] },
+ options: [
+ { 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" },
+ ],
+ type: FilterTypes.ExcludableCheckboxGroup,
+ },
+ categories: {
+ label: "Тэги:",
+ value: { include: [], exclude: [] },
+ options: [
+ { 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" },
+ ],
+ type: FilterTypes.ExcludableCheckboxGroup,
+ },
+ types: {
+ label: "Типы:",
+ value: [],
+ options: [
+ { label: "Авторское", value: "1" },
+ { label: "Другое", value: "7" },
+ { label: "Запад", value: "5" },
+ { label: "Китай", value: "4" },
+ { label: "Корея", value: "3" },
+ { label: "Фанфики", value: "6" },
+ { label: "Япония", value: "2" },
+ ],
+ type: FilterTypes.CheckboxGroup,
+ },
+ status: {
+ label: "Статус проекта:",
+ value: [],
+ options: [
+ { label: "Анонс", value: "4" },
+ { label: "Закончен", value: "0" },
+ { label: "Заморожен", value: "2" },
+ { label: "Лицензировано", value: "5" },
+ { label: "Нет переводчика", value: "3" },
+ { label: "Продолжается", value: "1" },
+ ],
+ type: FilterTypes.CheckboxGroup,
+ },
+ age_limit: {
+ label: "Возрастной рейтинг:",
+ value: [],
+ options: [
+ { label: "16+", value: "1" },
+ { label: "18+", value: "2" },
+ { label: "Для всех", value: "0" },
+ ],
+ type: FilterTypes.CheckboxGroup,
+ },
+ } satisfies Filters;
+}
+
+export default new ReN();
+
+interface responseNovels {
+ id: number;
+ secondary_name: string;
+ main_name: string;
+ dir: string;
+ is_licensed: boolean;
+ issue_year: number;
+ avg_rating: string;
+ admin_rating: string;
+ type: string;
+ total_views: number;
+ total_votes: number;
+ cover_high: string;
+ cover_mid: string;
+ cover_low: string;
+ is_yaoi: boolean;
+ is_erotic: boolean;
+ bookmark_type?: null;
+ genres?: ItemEntity[] | null;
+ img: Img;
+ categories?: ItemEntity[] | null;
+ rus_name?: string;
+ en_name?: string;
+}
+
+interface Img {
+ high?: string;
+ mid?: string;
+ low: string;
+}
+
+interface responseNovel {
+ id: number;
+ img: Img;
+ secondary_name: string;
+ main_name: string;
+ another_name: string;
+ dir: string;
+ description: string;
+ issue_year: number;
+ avg_rating: string;
+ admin_rating: string;
+ count_rating: number;
+ age_limit: number;
+ status: ItemEntity;
+ count_bookmarks: number;
+ total_votes: number;
+ total_views: number;
+ type: ItemEntity;
+ genres?: ItemEntity[] | null;
+ categories?: ItemEntity[] | null;
+ publishers?: PublishersEntity[] | null;
+ bookmark_type?: null;
+ branches?: BranchesEntity[] | null;
+ count_chapters: number;
+ first_chapter: FirstChapter;
+ continue_reading?: null;
+ is_licensed: boolean;
+ newlate_id?: null;
+ newlate_title?: null;
+ related?: null;
+ uploaded: number;
+ can_post_comments: boolean;
+ adaptation: Adaptation | null;
+}
+
+interface Adaptation {
+ main_name: string;
+ secondary_name: string;
+ dir: string;
+ img: string;
+}
+
+interface ItemEntity {
+ id: number;
+ name: string;
+}
+interface PublishersEntity {
+ id: number;
+ name: string;
+ img: string;
+ dir: string;
+ tagline: string;
+ type: string;
+}
+interface BranchesEntity {
+ id: number;
+ img: string;
+ publishers?: PublishersEntity[] | null;
+ subscribed: boolean;
+ total_votes: number;
+ count_chapters: number;
+}
+interface FirstChapter {
+ id: number;
+ tome: number;
+ chapter: string;
+}
+
+interface responseСhapters {
+ id: number;
+ rated?: null;
+ viewed?: null;
+ is_bought?: boolean | null;
+ publishers?: PublishersEntity[] | null;
+ tome: number;
+ index: number;
+ chapter: string;
+ name: string;
+ price?: null | number;
+ score: number;
+ pub_date?: null;
+ upload_date: string;
+ is_paid: boolean;
+}
+
+interface responseСhapter {
+ id: number;
+ chapter: string;
+ name: string;
+ content: string;
+ score: number;
+ upload_date: string;
+ is_paid: boolean;
+ title_id: number;
+ volume_id: number;
+ branch_id: number;
+ price?: null;
+ pub_date?: null;
+ index: number;
+ publishers?: PublishersEntity[] | null;
+ tome: number;
+}
diff --git a/plugins/spanish/tunovelaligera.ts b/plugins/spanish/tunovelaligera.ts
index 0e0b98a..cc87f56 100644
--- a/plugins/spanish/tunovelaligera.ts
+++ b/plugins/spanish/tunovelaligera.ts
@@ -1,385 +1,375 @@
-import { CheerioAPI, load as parseHTML } from "cheerio";
-import { fetchApi, fetchFile } from "@libs/fetch";
-import { FilterTypes, Filters } from "@libs/filterInputs";
-import { Plugin } from "@typings/plugin";
-import { showToast } from "@libs/showToast";
-import { defaultCover } from "@libs/defaultCover";
-import { NovelStatus } from "@libs/novelStatus";
-
-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 = "";
-
- async popularNovels(
- pageNo: number,
- { filters }: Plugin.PopularNovelsOptions
- ): Promise {
- let link = `${this.site}`;
-
- link += filters.genres ? `genero/` + filters.genres : "novelas";
-
- link += `/page/${pageNo}`;
-
- link += filters.order;
-
- const headers = new Headers();
- if (this.cookieString) {
- headers.append("cookie", this.cookieString);
- }
- const result = await fetchApi(link, { headers });
- const body = await result.text();
-
- const loadedCheerio = parseHTML(body);
-
- const novels: Plugin.NovelItem[] = [];
-
- 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");
-
- if (!novelUrl) 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: [],
- };
-
- 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") ||
- novelCover.attr("data-cfsrc") ||
- 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.Ongoing
- : NovelStatus.Completed;
- break;
- }
- });
-
- novel.summary = loadedCheerio("div.summary__content > p").text().trim();
-
- let chapter: Plugin.ChapterItem[] = [];
-
- const delay = (ms: number) => new Promise((res) => setTimeout(res, ms));
- let lastPage = 1;
- lastPage = +loadedCheerio(".lcp_paginator li:last").prev().text();
-
- const getChapters = async () => {
- const n = url.split("/");
- const novelName = n[4];
- showToast("Cargando desde Archivo...");
-
- 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();
-
- 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;
- }
-
- 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 loadedCheerio = parseHTML(body);
-
- const novels: Plugin.NovelItem[] = [];
-
- 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,
- });
- });
-
- return novels;
- }
-
- async fetchImage(url: string): Promise {
- return await fetchFile(url);
- }
-
- filters = {
- order: {
- value: "?m_orderby=rating",
- label: "Ordenado por",
- options: [
- { 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" },
- ],
- type: FilterTypes.Picker,
- },
- genres: {
- value: "",
- label: "Generos",
- options: [
- { label: "None", value: "" },
- { 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" },
- ],
- type: FilterTypes.Picker,
- },
- } satisfies Filters;
-}
-
-export default new TuNovelaLigera();
+import { CheerioAPI, load as parseHTML } from "cheerio";
+import { fetchApi, fetchFile } from "@libs/fetch";
+import { FilterTypes, Filters } from "@libs/filterInputs";
+import { Plugin } from "@typings/plugin";
+import { showToast } from "@libs/showToast";
+import { defaultCover } from "@libs/defaultCover";
+import { NovelStatus } from "@libs/novelStatus";
+
+class TuNovelaLigera implements Plugin.PluginBase {
+ id = "tunovelaligera";
+ name = "TuNovelaLigera";
+ icon = "src/es/tunovelaligera/icon.png";
+ site = "https://tunovelaligera.com/";
+ version = "1.0.0";
+ userAgent = "";
+
+ async popularNovels(
+ pageNo: number,
+ { filters }: Plugin.PopularNovelsOptions
+ ): Promise {
+ let link = `${this.site}`;
+
+ link += filters.genres ? `genero/` + filters.genres : "novelas";
+
+ link += `/page/${pageNo}`;
+
+ link += filters.order;
+
+ const headers = new Headers();
+ const result = await fetchApi(link, { headers });
+ const body = await result.text();
+
+ const loadedCheerio = parseHTML(body);
+
+ const novels: Plugin.NovelItem[] = [];
+
+ 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");
+
+ if (!novelUrl) 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();
+ const result = await fetchApi(url, { headers });
+ const body = await result.text();
+
+ let loadedCheerio = parseHTML(body);
+
+ const novel: Plugin.SourceNovel = {
+ url,
+ chapters: [],
+ };
+
+ 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") ||
+ novelCover.attr("data-cfsrc") ||
+ 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.Ongoing
+ : NovelStatus.Completed;
+ break;
+ }
+ });
+
+ novel.summary = loadedCheerio("div.summary__content > p").text().trim();
+
+ let chapter: Plugin.ChapterItem[] = [];
+
+ const delay = (ms: number) => new Promise((res) => setTimeout(res, ms));
+ let lastPage = 1;
+ lastPage = +loadedCheerio(".lcp_paginator li:last").prev().text();
+
+ const getChapters = async () => {
+ const n = url.split("/");
+ const novelName = n[4];
+ showToast("Cargando desde Archivo...");
+
+ 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();
+
+ 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();
+ 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;
+ }
+
+ 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 loadedCheerio = parseHTML(body);
+
+ const novels: Plugin.NovelItem[] = [];
+
+ 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,
+ });
+ });
+
+ return novels;
+ }
+
+ async fetchImage(url: string): Promise {
+ return await fetchFile(url);
+ }
+
+ filters = {
+ order: {
+ value: "?m_orderby=rating",
+ label: "Ordenado por",
+ options: [
+ { 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" },
+ ],
+ type: FilterTypes.Picker,
+ },
+ genres: {
+ value: "",
+ label: "Generos",
+ options: [
+ { label: "None", value: "" },
+ { 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" },
+ ],
+ type: FilterTypes.Picker,
+ },
+ } satisfies Filters;
+}
+
+export default new TuNovelaLigera();
diff --git a/plugins/turkish/lshnovel.ts b/plugins/turkish/lshnovel.ts
index 36a2d5c..a4ba337 100644
--- a/plugins/turkish/lshnovel.ts
+++ b/plugins/turkish/lshnovel.ts
@@ -1,323 +1,310 @@
-import { load as parseHTML } from "cheerio";
-import { fetchApi, fetchFile } from "@libs/fetch";
-import { FilterTypes, Filters } from "@libs/filterInputs";
-import { Plugin } from "@typings/plugin";
-
-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.genres.value.length) {
- link += filters.genres.value.map((i) => `&genre[]=${i}`).join("");
- }
-
- if (filters.type.value.length)
- link += filters.type.value.map((i) => `&lang[]=${i}`).join("");
-
- link += "&status=" + filters.status;
-
- link += "&order=" + filters.order;
-
- 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.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;
- }
-
- 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(".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 "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();
-
- let chapter: Plugin.ChapterItem[] = [];
-
- 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;
- }
- 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();
-
- 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();
-
- const loadedCheerio = parseHTML(body);
-
- const novels: Plugin.NovelItem[] = [];
-
- 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;
- }
- async fetchImage(url: string): Promise {
- return await fetchFile(url);
- }
-
- filters = {
- order: {
- value: "popular",
- label: "Önerilen",
- options: [
- { 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" },
- ],
- type: FilterTypes.Picker,
- },
- status: {
- label: "Statü",
- value: "",
- options: [
- { label: "Tümü", value: "" },
-
- { label: "Ongoing", value: "ongoing" },
-
- { label: "Hiatus", value: "hiatus" },
-
- { label: "Completed", value: "completed" },
- ],
- type: FilterTypes.Picker,
- },
- type: {
- value: [],
- label: "Tür",
- options: [
- { 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" },
- ],
- type: FilterTypes.CheckboxGroup,
- },
- genres: {
- value: [],
- label: "Kategori",
- options: [
- { 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" },
- ],
- type: FilterTypes.CheckboxGroup,
- },
- } satisfies Filters;
-}
-
-export default new LSHNovel();
+import { load as parseHTML } from "cheerio";
+import { fetchApi, fetchFile } from "@libs/fetch";
+import { FilterTypes, Filters } from "@libs/filterInputs";
+import { Plugin } from "@typings/plugin";
+
+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 = "";
+ async popularNovels(
+ pageNo: number,
+ { filters }: Plugin.PopularNovelsOptions
+ ): Promise {
+ let link = `${this.site}series/?page=${pageNo}`;
+
+ if (filters.genres.value.length) {
+ link += filters.genres.value.map((i) => `&genre[]=${i}`).join("");
+ }
+
+ if (filters.type.value.length)
+ link += filters.type.value.map((i) => `&lang[]=${i}`).join("");
+
+ link += "&status=" + filters.status;
+
+ link += "&order=" + filters.order;
+
+ const headers = new Headers();
+ const body = await fetchApi(link, { headers }).then((result) =>
+ result.text()
+ );
+
+ const loadedCheerio = parseHTML(body);
+
+ const novels: Plugin.NovelItem[] = [];
+
+ 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;
+ }
+
+ async parseNovelAndChapters(novelUrl: string): Promise {
+ const url = novelUrl;
+ const headers = new Headers();
+ const result = await fetchApi(url, { headers });
+ const body = await result.text();
+
+ let loadedCheerio = parseHTML(body);
+
+ const novel: Plugin.SourceNovel = {
+ 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 "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();
+
+ let chapter: Plugin.ChapterItem[] = [];
+
+ 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;
+ }
+ async parseChapter(chapterUrl: string): Promise {
+ const headers = new Headers();
+ const result = await fetchApi(chapterUrl, { headers });
+ const body = await result.text();
+
+ 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();
+ const result = await fetchApi(url, { headers });
+ const body = await result.text();
+
+ const loadedCheerio = parseHTML(body);
+
+ const novels: Plugin.NovelItem[] = [];
+
+ 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;
+ }
+ async fetchImage(url: string): Promise {
+ return await fetchFile(url);
+ }
+
+ filters = {
+ order: {
+ value: "popular",
+ label: "Önerilen",
+ options: [
+ { 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" },
+ ],
+ type: FilterTypes.Picker,
+ },
+ status: {
+ label: "Statü",
+ value: "",
+ options: [
+ { label: "Tümü", value: "" },
+
+ { label: "Ongoing", value: "ongoing" },
+
+ { label: "Hiatus", value: "hiatus" },
+
+ { label: "Completed", value: "completed" },
+ ],
+ type: FilterTypes.Picker,
+ },
+ type: {
+ value: [],
+ label: "Tür",
+ options: [
+ { 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" },
+ ],
+ type: FilterTypes.CheckboxGroup,
+ },
+ genres: {
+ value: [],
+ label: "Kategori",
+ options: [
+ { 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" },
+ ],
+ type: FilterTypes.CheckboxGroup,
+ },
+ } satisfies Filters;
+}
+
+export default new LSHNovel();
diff --git a/plugins/ukraine/smakolykytl.ts b/plugins/ukraine/smakolykytl.ts
index e096934..de05261 100644
--- a/plugins/ukraine/smakolykytl.ts
+++ b/plugins/ukraine/smakolykytl.ts
@@ -1,256 +1,255 @@
-import { Plugin } from "@typings/plugin";
-import { fetchApi, fetchFile } from "@libs/fetch";
-import { NovelStatus } from "@libs/novelStatus";
-import dayjs from "dayjs";
-
-class Smakolykytl implements Plugin.PluginBase {
- id = "smakolykytl";
- name = "Смаколики";
- site = "https://smakolykytl.site/";
- version = "1.0.0";
- icon = "src/ua/smakolykytl/icon.png";
- userAgent = "";
- cookieString = "";
-
- async popularNovels(
- pageNo: number,
- { showLatestNovels, filters }: Plugin.PopularNovelsOptions,
- ): Promise {
- const url = showLatestNovels
- ? "https://api.smakolykytl.site/api/user/updates"
- : "https://api.smakolykytl.site/api/user/projects";
-
- const result = await fetchApi(url);
- const json = (await result.json()) as response;
-
- const novels: Plugin.NovelItem[] = [];
- (json?.projects || json?.updates)?.forEach((novel) =>
- novels.push({
- name: novel.title,
- cover: novel.image.url,
- url: this.site + "titles/" + novel.id,
- }),
- );
-
- return novels;
- }
-
- async parseNovelAndChapters(novelUrl: string): Promise {
- const id = novelUrl.split("/").pop();
- const result = await fetchApi(
- "https://api.smakolykytl.site/api/user/projects/" + id,
- );
- const book = (await result.json()) as response;
-
- const novel: Plugin.SourceNovel = {
- url: novelUrl,
- name: book?.project?.title,
- cover: book?.project?.image?.url,
- summary: book?.project?.description,
- author: book?.project?.author,
- status: book?.project?.status_translate.includes("Триває")
- ? NovelStatus.Ongoing
- : NovelStatus.Completed,
- };
- const tags = [book?.project?.genres, book?.project?.tags]
- .flat()
- .map((tags) => tags?.title)
- .filter((tags) => tags);
-
- if (tags.length) {
- novel.genres = tags.join(", ");
- }
-
- const chapters: Plugin.ChapterItem[] = [];
- const res = await fetchApi(
- "https://api.smakolykytl.site/api/user/projects/" + id + "/books",
- );
- const data = (await res.json()) as response;
- data?.books?.forEach(
- (volume) =>
- volume?.chapters?.map((chapter) =>
- chapters.push({
- name: volume.title + " " + chapter.title,
- releaseTime: dayjs(chapter.modifiedAt).format("LLL"),
- url: this.site + "read/" + chapter.id,
- }),
- ),
- );
-
- novel.chapters = chapters;
- return novel;
- }
-
- async parseChapter(chapterUrl: string): Promise {
- const id = chapterUrl.split("/").pop();
- const result = await fetchApi(
- "https://api.smakolykytl.site/api/user/chapters/" + id,
- );
- const json = (await result.json()) as response;
- const chapterRaw: HTML[] = JSON.parse(json?.chapter?.content || "[]");
-
- const chapterText = jsonToHtml(chapterRaw);
- return chapterText;
- }
-
- async searchNovels(
- searchTerm: string,
- //pageNo: number | undefined = 1,
- ): Promise {
- const result = await fetchApi(
- "https://api.smakolykytl.site/api/user/projects",
- );
- const json = (await result.json()) as response;
- const novels: Plugin.NovelItem[] = [];
-
- json?.projects
- ?.filter(
- (novel) =>
- novel.title.includes(searchTerm) || String(novel.id) === searchTerm,
- )
- ?.forEach((novel) =>
- novels.push({
- name: novel.title,
- cover: novel.image.url,
- url: this.site + "titles/" + novel.id,
- }),
- );
- return novels;
- }
-
- fetchImage = fetchFile;
-}
-
-export default new Smakolykytl();
-
-function jsonToHtml(json: HTML[], html: string = "") {
- 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?.[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;
-}
-
-interface response {
- projects?: TopLevelProject[];
- updates?: Update[];
- project?: TopLevelProject;
- books?: BookElement[];
- chapter?: TopLevelChapter;
-}
-
-interface BookElement {
- id: number;
- rank: number;
- title: string;
- chapters: PurpleChapter[];
-}
-
-interface PurpleChapter {
- id: number;
- title: string;
- rank: string;
- modifiedAt: Date;
-}
-
-interface TopLevelChapter {
- id: number;
- title: string;
- rank: string;
- content: string;
- modifiedAt: Date;
- book: ChapterBook;
-}
-
-interface ChapterBook {
- id: number;
- rank: number;
- title: string;
- chapters: FluffyChapter[];
- project: BookProject;
-}
-
-interface FluffyChapter {
- id: number;
- rank: string;
-}
-
-interface BookProject {
- id: number;
-}
-
-interface TopLevelProject {
- id: number;
- title: string;
- description: string;
- author: string;
- translator: string;
- modifiedAt: Date;
- alternatives: string;
- release: string;
- nation: string;
- status: string;
- status_translate: string;
- image: Image;
- tags?: Genre[];
- genres?: Genre[];
-}
-
-interface Genre {
- id: number;
- title: string;
-}
-
-interface Image {
- id: number;
- url: string;
- name: string;
-}
-
-interface Update {
- id: number;
- title: string;
- author: string;
- translator: string;
- modifiedAt: Date;
- image: Image;
-}
-
-interface HTML {
- type: string;
- content?: HTML[];
- attrs?: Attrs;
- text?: string;
-}
-
-interface Attrs {
- src: string;
- alt: string | null;
- title: string | null;
-}
+import { Plugin } from "@typings/plugin";
+import { fetchApi, fetchFile } from "@libs/fetch";
+import { NovelStatus } from "@libs/novelStatus";
+import dayjs from "dayjs";
+
+class Smakolykytl implements Plugin.PluginBase {
+ id = "smakolykytl";
+ name = "Смаколики";
+ site = "https://smakolykytl.site/";
+ version = "1.0.0";
+ icon = "src/ua/smakolykytl/icon.png";
+ userAgent = "";
+
+ async popularNovels(
+ pageNo: number,
+ { showLatestNovels, filters }: Plugin.PopularNovelsOptions,
+ ): Promise {
+ const url = showLatestNovels
+ ? "https://api.smakolykytl.site/api/user/updates"
+ : "https://api.smakolykytl.site/api/user/projects";
+
+ const result = await fetchApi(url);
+ const json = (await result.json()) as response;
+
+ const novels: Plugin.NovelItem[] = [];
+ (json?.projects || json?.updates)?.forEach((novel) =>
+ novels.push({
+ name: novel.title,
+ cover: novel.image.url,
+ url: this.site + "titles/" + novel.id,
+ }),
+ );
+
+ return novels;
+ }
+
+ async parseNovelAndChapters(novelUrl: string): Promise {
+ const id = novelUrl.split("/").pop();
+ const result = await fetchApi(
+ "https://api.smakolykytl.site/api/user/projects/" + id,
+ );
+ const book = (await result.json()) as response;
+
+ const novel: Plugin.SourceNovel = {
+ url: novelUrl,
+ name: book?.project?.title,
+ cover: book?.project?.image?.url,
+ summary: book?.project?.description,
+ author: book?.project?.author,
+ status: book?.project?.status_translate.includes("Триває")
+ ? NovelStatus.Ongoing
+ : NovelStatus.Completed,
+ };
+ const tags = [book?.project?.genres, book?.project?.tags]
+ .flat()
+ .map((tags) => tags?.title)
+ .filter((tags) => tags);
+
+ if (tags.length) {
+ novel.genres = tags.join(", ");
+ }
+
+ const chapters: Plugin.ChapterItem[] = [];
+ const res = await fetchApi(
+ "https://api.smakolykytl.site/api/user/projects/" + id + "/books",
+ );
+ const data = (await res.json()) as response;
+ data?.books?.forEach(
+ (volume) =>
+ volume?.chapters?.map((chapter) =>
+ chapters.push({
+ name: volume.title + " " + chapter.title,
+ releaseTime: dayjs(chapter.modifiedAt).format("LLL"),
+ url: this.site + "read/" + chapter.id,
+ }),
+ ),
+ );
+
+ novel.chapters = chapters;
+ return novel;
+ }
+
+ async parseChapter(chapterUrl: string): Promise {
+ const id = chapterUrl.split("/").pop();
+ const result = await fetchApi(
+ "https://api.smakolykytl.site/api/user/chapters/" + id,
+ );
+ const json = (await result.json()) as response;
+ const chapterRaw: HTML[] = JSON.parse(json?.chapter?.content || "[]");
+
+ const chapterText = jsonToHtml(chapterRaw);
+ return chapterText;
+ }
+
+ async searchNovels(
+ searchTerm: string,
+ //pageNo: number | undefined = 1,
+ ): Promise {
+ const result = await fetchApi(
+ "https://api.smakolykytl.site/api/user/projects",
+ );
+ const json = (await result.json()) as response;
+ const novels: Plugin.NovelItem[] = [];
+
+ json?.projects
+ ?.filter(
+ (novel) =>
+ novel.title.includes(searchTerm) || String(novel.id) === searchTerm,
+ )
+ ?.forEach((novel) =>
+ novels.push({
+ name: novel.title,
+ cover: novel.image.url,
+ url: this.site + "titles/" + novel.id,
+ }),
+ );
+ return novels;
+ }
+
+ fetchImage = fetchFile;
+}
+
+export default new Smakolykytl();
+
+function jsonToHtml(json: HTML[], html: string = "") {
+ 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?.[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;
+}
+
+interface response {
+ projects?: TopLevelProject[];
+ updates?: Update[];
+ project?: TopLevelProject;
+ books?: BookElement[];
+ chapter?: TopLevelChapter;
+}
+
+interface BookElement {
+ id: number;
+ rank: number;
+ title: string;
+ chapters: PurpleChapter[];
+}
+
+interface PurpleChapter {
+ id: number;
+ title: string;
+ rank: string;
+ modifiedAt: Date;
+}
+
+interface TopLevelChapter {
+ id: number;
+ title: string;
+ rank: string;
+ content: string;
+ modifiedAt: Date;
+ book: ChapterBook;
+}
+
+interface ChapterBook {
+ id: number;
+ rank: number;
+ title: string;
+ chapters: FluffyChapter[];
+ project: BookProject;
+}
+
+interface FluffyChapter {
+ id: number;
+ rank: string;
+}
+
+interface BookProject {
+ id: number;
+}
+
+interface TopLevelProject {
+ id: number;
+ title: string;
+ description: string;
+ author: string;
+ translator: string;
+ modifiedAt: Date;
+ alternatives: string;
+ release: string;
+ nation: string;
+ status: string;
+ status_translate: string;
+ image: Image;
+ tags?: Genre[];
+ genres?: Genre[];
+}
+
+interface Genre {
+ id: number;
+ title: string;
+}
+
+interface Image {
+ id: number;
+ url: string;
+ name: string;
+}
+
+interface Update {
+ id: number;
+ title: string;
+ author: string;
+ translator: string;
+ modifiedAt: Date;
+ image: Image;
+}
+
+interface HTML {
+ type: string;
+ content?: HTML[];
+ attrs?: Attrs;
+ text?: string;
+}
+
+interface Attrs {
+ src: string;
+ alt: string | null;
+ title: string | null;
+}
diff --git a/plugins/vietnamese/LNHako.ts b/plugins/vietnamese/LNHako.ts
index 9cb5697..f2f96eb 100644
--- a/plugins/vietnamese/LNHako.ts
+++ b/plugins/vietnamese/LNHako.ts
@@ -9,7 +9,7 @@ class HakoPlugin implements Plugin.PluginBase {
site: string;
version: string;
userAgent: string;
- cookieString: string;
+
constructor() {
this.id = "ln.hako";
this.name = "Hako";
@@ -17,7 +17,6 @@ class HakoPlugin implements Plugin.PluginBase {
this.site = "https://ln.hako.vn";
this.version = "1.0.0";
this.userAgent = "";
- this.cookieString = "";
}
parseNovels(loadedCheerio: CheerioAPI) {
const novels: Plugin.NovelItem[] = [];
diff --git a/scripts/multisrc/ifreedom/template.ts b/scripts/multisrc/ifreedom/template.ts
index bf58549..2adf137 100644
--- a/scripts/multisrc/ifreedom/template.ts
+++ b/scripts/multisrc/ifreedom/template.ts
@@ -19,7 +19,6 @@ class IfreedomPlugin implements Plugin.PluginBase {
site: string;
version: string;
userAgent: string;
- cookieString: string;
filters?: Filters;
constructor(metadata: IfreedomMetadata) {
@@ -29,7 +28,6 @@ class IfreedomPlugin implements Plugin.PluginBase {
this.site = metadata.sourceSite;
this.version = "1.0.0";
this.userAgent = "";
- this.cookieString = "";
this.filters = metadata.filters;
}
diff --git a/scripts/multisrc/madara/template.ts b/scripts/multisrc/madara/template.ts
index b72a315..8d40961 100644
--- a/scripts/multisrc/madara/template.ts
+++ b/scripts/multisrc/madara/template.ts
@@ -42,7 +42,6 @@ class MadaraPlugin implements Plugin.PluginBase {
site: string;
version: string;
userAgent: string;
- cookieString: string;
options?: MadaraOptions;
filters?: Filters | undefined;
@@ -56,7 +55,6 @@ class MadaraPlugin implements Plugin.PluginBase {
this.site = metadata.sourceSite;
this.version = "1.0.0";
this.userAgent = "";
- this.cookieString = "";
this.options = metadata.options;
this.filters = metadata.filters;
}
diff --git a/scripts/multisrc/readwn/template.ts b/scripts/multisrc/readwn/template.ts
index 8d6e411..18a84cd 100644
--- a/scripts/multisrc/readwn/template.ts
+++ b/scripts/multisrc/readwn/template.ts
@@ -20,7 +20,6 @@ class ReadwnPlugin implements Plugin.PluginBase {
site: string;
version: string;
userAgent: string;
- cookieString: string;
filters?: Filters;
constructor(metadata: ReadwnMetadata) {
@@ -31,7 +30,6 @@ class ReadwnPlugin implements Plugin.PluginBase {
this.site = metadata.sourceSite;
this.version = "1.0.0";
this.userAgent = "";
- this.cookieString = "";
this.filters = metadata.filters;
}
diff --git a/scripts/multisrc/rulate/template.ts b/scripts/multisrc/rulate/template.ts
index a474d1f..49b89bb 100644
--- a/scripts/multisrc/rulate/template.ts
+++ b/scripts/multisrc/rulate/template.ts
@@ -19,7 +19,6 @@ class RulatePlugin implements Plugin.PluginBase {
site: string;
version: string;
userAgent: string;
- cookieString: string;
filters?: Filters | undefined;
constructor(metadata: RulateMetadata) {
@@ -30,7 +29,6 @@ class RulatePlugin implements Plugin.PluginBase {
this.site = metadata.sourceSite;
this.version = "1.0.0";
this.userAgent = "";
- this.cookieString = "";
this.filters = metadata.filters;
}
diff --git a/scripts/multisrc/wpmangastream/template.ts b/scripts/multisrc/wpmangastream/template.ts
index abd9330..1caecf4 100644
--- a/scripts/multisrc/wpmangastream/template.ts
+++ b/scripts/multisrc/wpmangastream/template.ts
@@ -22,7 +22,6 @@ class WPmangaStreamPlugin implements Plugin.PluginBase {
site: string;
version: string;
userAgent: string;
- cookieString: string;
options?: WPmangaStreamOptions;
constructor(metadata: WPmangaStreamMetadata) {
@@ -32,7 +31,6 @@ class WPmangaStreamPlugin implements Plugin.PluginBase {
this.site = metadata.sourceSite;
this.version = "1.0.0";
this.userAgent = "";
- this.cookieString = "";
this.options = metadata.options;
}
diff --git a/test_web/index.html b/test_web/index.html
index 8784008..509f552 100644
--- a/test_web/index.html
+++ b/test_web/index.html
@@ -50,6 +50,14 @@
+
+
+
+
+ Add cookie into headers to bypass cloudflare
+
+
+