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[]; }