diff --git a/multisrc/overrides/libgroup/yaoilib/AndroidManifest.xml b/multisrc/overrides/libgroup/yaoilib/AndroidManifest.xml
new file mode 100644
index 000000000..439c0f592
--- /dev/null
+++ b/multisrc/overrides/libgroup/yaoilib/AndroidManifest.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/multisrc/overrides/libgroup/yaoilib/res/mipmap-hdpi/ic_launcher.png b/multisrc/overrides/libgroup/yaoilib/res/mipmap-hdpi/ic_launcher.png
new file mode 100644
index 000000000..6ec189440
Binary files /dev/null and b/multisrc/overrides/libgroup/yaoilib/res/mipmap-hdpi/ic_launcher.png differ
diff --git a/multisrc/overrides/libgroup/yaoilib/res/mipmap-mdpi/ic_launcher.png b/multisrc/overrides/libgroup/yaoilib/res/mipmap-mdpi/ic_launcher.png
new file mode 100644
index 000000000..716693c4a
Binary files /dev/null and b/multisrc/overrides/libgroup/yaoilib/res/mipmap-mdpi/ic_launcher.png differ
diff --git a/multisrc/overrides/libgroup/yaoilib/res/mipmap-xhdpi/ic_launcher.png b/multisrc/overrides/libgroup/yaoilib/res/mipmap-xhdpi/ic_launcher.png
new file mode 100644
index 000000000..7f6f6ce53
Binary files /dev/null and b/multisrc/overrides/libgroup/yaoilib/res/mipmap-xhdpi/ic_launcher.png differ
diff --git a/multisrc/overrides/libgroup/yaoilib/res/mipmap-xxhdpi/ic_launcher.png b/multisrc/overrides/libgroup/yaoilib/res/mipmap-xxhdpi/ic_launcher.png
new file mode 100644
index 000000000..9e921fb64
Binary files /dev/null and b/multisrc/overrides/libgroup/yaoilib/res/mipmap-xxhdpi/ic_launcher.png differ
diff --git a/multisrc/overrides/libgroup/yaoilib/res/mipmap-xxxhdpi/ic_launcher.png b/multisrc/overrides/libgroup/yaoilib/res/mipmap-xxxhdpi/ic_launcher.png
new file mode 100644
index 000000000..6dd288d16
Binary files /dev/null and b/multisrc/overrides/libgroup/yaoilib/res/mipmap-xxxhdpi/ic_launcher.png differ
diff --git a/multisrc/overrides/libgroup/yaoilib/res/web_hi_res_512.png b/multisrc/overrides/libgroup/yaoilib/res/web_hi_res_512.png
new file mode 100644
index 000000000..6b6759355
Binary files /dev/null and b/multisrc/overrides/libgroup/yaoilib/res/web_hi_res_512.png differ
diff --git a/multisrc/overrides/libgroup/yaoilib/src/YaoiLib.kt b/multisrc/overrides/libgroup/yaoilib/src/YaoiLib.kt
new file mode 100644
index 000000000..899d3b307
--- /dev/null
+++ b/multisrc/overrides/libgroup/yaoilib/src/YaoiLib.kt
@@ -0,0 +1,179 @@
+package eu.kanade.tachiyomi.extension.ru.yaoilib
+
+import eu.kanade.tachiyomi.multisrc.libgroup.LibGroup
+import eu.kanade.tachiyomi.network.POST
+import eu.kanade.tachiyomi.source.model.Filter
+import eu.kanade.tachiyomi.source.model.FilterList
+import okhttp3.Headers
+import okhttp3.OkHttpClient
+import okhttp3.Request
+
+class YaoiLib : LibGroup("YaoiLib", "https://yaoilib.me", "ru") {
+
+ override val client: OkHttpClient = super.client.newBuilder()
+ .addInterceptor(::imageContentTypeIntercept)
+ .build()
+
+ private var csrfToken: String = ""
+
+ private fun catalogHeaders() = Headers.Builder()
+ .apply {
+ add("Accept", "application/json, text/plain, */*")
+ add("X-Requested-With", "XMLHttpRequest")
+ add("x-csrf-token", csrfToken)
+ }
+ .build()
+
+ override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
+ if (csrfToken.isEmpty()) {
+ val tokenResponse = client.newCall(popularMangaRequest(page)).execute()
+ val resBody = tokenResponse.body!!.string()
+ csrfToken = "_token\" content=\"(.*)\"".toRegex().find(resBody)!!.groups[1]!!.value
+ }
+ val url = super.searchMangaRequest(page, query, filters).url.newBuilder()
+ (if (filters.isEmpty()) getFilterList() else filters).forEach { filter ->
+ when (filter) {
+ is AgeList -> filter.state.forEach { age ->
+ if (age.state) {
+ url.addQueryParameter("caution[]", age.id)
+ }
+ }
+ is TagList -> filter.state.forEach { tag ->
+ if (tag.state != Filter.TriState.STATE_IGNORE) {
+ url.addQueryParameter(
+ if (tag.isIncluded()) "tags[include][]" else "tags[exclude][]",
+ tag.id
+ )
+ }
+ }
+ }
+ }
+ return POST(url.toString(), catalogHeaders())
+ }
+
+
+ // Filters
+ private class SearchFilter(name: String, val id: String) : Filter.TriState(name)
+ private class CheckFilter(name: String, val id: String) : Filter.CheckBox(name)
+
+ private class TagList(tags: List) : Filter.Group("Теги", tags)
+ private class AgeList(ages: List) : Filter.Group("Возрастное ограничение", ages)
+
+ override fun getFilterList(): FilterList {
+ val filters = super.getFilterList().toMutableList()
+ filters.add(4, TagList(getTagList()))
+ filters.add(7, AgeList(getAgeList()))
+ return FilterList(filters)
+ }
+
+ private fun getTagList() = listOf(
+ SearchFilter("Азартные игры", "304"),
+ SearchFilter("Алхимия", "225"),
+ SearchFilter("Ангелы", "226"),
+ SearchFilter("Антигерой", "175"),
+ SearchFilter("Антиутопия", "227"),
+ SearchFilter("Апокалипсис", "228"),
+ SearchFilter("Армия", "229"),
+ SearchFilter("Артефакты", "230"),
+ SearchFilter("Боги", "215"),
+ SearchFilter("Бои на мечах", "231"),
+ SearchFilter("Борьба за власть", "231"),
+ SearchFilter("Брат и сестра", "233"),
+ SearchFilter("Будущее", "234"),
+ SearchFilter("Ведьма", "338"),
+ SearchFilter("Вестерн", "235"),
+ SearchFilter("Видеоигры", "185"),
+ SearchFilter("Виртуальная реальность", "195"),
+ SearchFilter("Владыка демонов", "236"),
+ SearchFilter("Военные", "179"),
+ SearchFilter("Война", "237"),
+ SearchFilter("Волшебники / маги", "281"),
+ SearchFilter("Волшебные существа", "239"),
+ SearchFilter("Воспоминания из другого мира", "240"),
+ SearchFilter("Выживание", "193"),
+ SearchFilter("ГГ женщина", "243"),
+ SearchFilter("ГГ имба", "291"),
+ SearchFilter("ГГ мужчина", "244"),
+ SearchFilter("Геймеры", "241"),
+ SearchFilter("Гильдии", "242"),
+ SearchFilter("Глупый ГГ", "297"),
+ SearchFilter("Гоблины", "245"),
+ SearchFilter("Горничные", "169"),
+ SearchFilter("Гяру", "178"),
+ SearchFilter("Демоны", "151"),
+ SearchFilter("Драконы", "246"),
+ SearchFilter("Дружба", "247"),
+ SearchFilter("Жестокий мир", "249"),
+ SearchFilter("Животные компаньоны", "250"),
+ SearchFilter("Завоевание мира", "251"),
+ SearchFilter("Зверолюди", "162"),
+ SearchFilter("Злые духи", "252"),
+ SearchFilter("Зомби", "149"),
+ SearchFilter("Игровые элементы", "253"),
+ SearchFilter("Империи", "254"),
+ SearchFilter("Квесты", "255"),
+ SearchFilter("Космос", "256"),
+ SearchFilter("Кулинария", "152"),
+ SearchFilter("Культивация", "160"),
+ SearchFilter("Легендарное оружие", "257"),
+ SearchFilter("Лоли", "187"),
+ SearchFilter("Магическая академия", "258"),
+ SearchFilter("Магия", "168"),
+ SearchFilter("Мафия", "172"),
+ SearchFilter("Медицина", "153"),
+ SearchFilter("Месть", "259"),
+ SearchFilter("Монстр Девушки", "188"),
+ SearchFilter("Монстры", "189"),
+ SearchFilter("Музыка", "190"),
+ SearchFilter("Навыки / способности", "260"),
+ SearchFilter("Насилие / жестокость", "262"),
+ SearchFilter("Наёмники", "261"),
+ SearchFilter("Нежить", "263"),
+ SearchFilter("Ниндая", "180"),
+ SearchFilter("Обратный Гарем", "191"),
+ SearchFilter("Огнестрельное оружие", "264"),
+ SearchFilter("Офисные Работники", "181"),
+ SearchFilter("Пародия", "265"),
+ SearchFilter("Пираты", "340"),
+ SearchFilter("Подземелья", "266"),
+ SearchFilter("Политика", "267"),
+ SearchFilter("Полиция", "182"),
+ SearchFilter("Преступники / Криминал", "186"),
+ SearchFilter("Призраки / Духи", "177"),
+ SearchFilter("Путешествие во времени", "194"),
+ SearchFilter("Разумные расы", "268"),
+ SearchFilter("Ранги силы", "248"),
+ SearchFilter("Реинкарнация", "148"),
+ SearchFilter("Роботы", "269"),
+ SearchFilter("Рыцари", "270"),
+ SearchFilter("Самураи", "183"),
+ SearchFilter("Система", "271"),
+ SearchFilter("Скрытие личности", "273"),
+ SearchFilter("Спасение мира", "274"),
+ SearchFilter("Спортивное тело", "334"),
+ SearchFilter("Средневековье", "173"),
+ SearchFilter("Стимпанк", "272"),
+ SearchFilter("Супергерои", "275"),
+ SearchFilter("Традиционные игры", "184"),
+ SearchFilter("Умный ГГ", "302"),
+ SearchFilter("Учитель / ученик", "276"),
+ SearchFilter("Философия", "277"),
+ SearchFilter("Хикикомори", "166"),
+ SearchFilter("Холодное оружие", "278"),
+ SearchFilter("Шантаж", "279"),
+ SearchFilter("Эльфы", "216"),
+ SearchFilter("Якудза", "164"),
+ SearchFilter("Япония", "280")
+
+ )
+
+ private fun getAgeList() = listOf(
+ CheckFilter("Отсутствует", "0"),
+ CheckFilter("16+", "1"),
+ CheckFilter("18+", "2")
+ )
+
+ companion object {
+ const val PREFIX_SLUG_SEARCH = "slug:"
+ }
+}
diff --git a/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/libgroup/LibGenerator.kt b/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/libgroup/LibGenerator.kt
index b0cfd2d57..853d632e5 100644
--- a/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/libgroup/LibGenerator.kt
+++ b/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/libgroup/LibGenerator.kt
@@ -13,7 +13,8 @@ class LibGenerator: ThemeSourceGenerator {
override val sources = listOf(
SingleLang("MangaLib", "https://mangalib.me", "ru", overrideVersionCode = 74),
- SingleLang("HentaiLib", "https://hentailib.me", "ru",isNsfw = true, overrideVersionCode = 19)
+ SingleLang("HentaiLib", "https://hentailib.me", "ru",isNsfw = true, overrideVersionCode = 19),
+ SingleLang("YaoiLib", "https://yaoilib.me", "ru",isNsfw = true, overrideVersionCode = 1)
)
companion object {