diff --git a/src/all/lmanime/AndroidManifest.xml b/src/all/lmanime/AndroidManifest.xml
new file mode 100644
index 000000000..3cc5b53de
--- /dev/null
+++ b/src/all/lmanime/AndroidManifest.xml
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/all/lmanime/build.gradle b/src/all/lmanime/build.gradle
new file mode 100644
index 000000000..faaa5c33e
--- /dev/null
+++ b/src/all/lmanime/build.gradle
@@ -0,0 +1,19 @@
+plugins {
+ alias(libs.plugins.android.application)
+ alias(libs.plugins.kotlin.android)
+ alias(libs.plugins.kotlin.serialization)
+}
+
+ext {
+ extName = 'LMAnime'
+ pkgNameSuffix = 'all.lmanime'
+ extClass = '.LMAnime'
+ extVersionCode = 1
+}
+
+dependencies {
+ implementation(project(":lib-fembed-extractor"))
+ implementation(project(":lib-okru-extractor"))
+}
+
+apply from: "$rootDir/common.gradle"
diff --git a/src/all/lmanime/res/mipmap-hdpi/ic_launcher.png b/src/all/lmanime/res/mipmap-hdpi/ic_launcher.png
new file mode 100644
index 000000000..436816e4e
Binary files /dev/null and b/src/all/lmanime/res/mipmap-hdpi/ic_launcher.png differ
diff --git a/src/all/lmanime/res/mipmap-mdpi/ic_launcher.png b/src/all/lmanime/res/mipmap-mdpi/ic_launcher.png
new file mode 100644
index 000000000..33d8ec8af
Binary files /dev/null and b/src/all/lmanime/res/mipmap-mdpi/ic_launcher.png differ
diff --git a/src/all/lmanime/res/mipmap-xhdpi/ic_launcher.png b/src/all/lmanime/res/mipmap-xhdpi/ic_launcher.png
new file mode 100644
index 000000000..983ced376
Binary files /dev/null and b/src/all/lmanime/res/mipmap-xhdpi/ic_launcher.png differ
diff --git a/src/all/lmanime/res/mipmap-xxhdpi/ic_launcher.png b/src/all/lmanime/res/mipmap-xxhdpi/ic_launcher.png
new file mode 100644
index 000000000..ca11fcebb
Binary files /dev/null and b/src/all/lmanime/res/mipmap-xxhdpi/ic_launcher.png differ
diff --git a/src/all/lmanime/res/mipmap-xxxhdpi/ic_launcher.png b/src/all/lmanime/res/mipmap-xxxhdpi/ic_launcher.png
new file mode 100644
index 000000000..ff058cdbd
Binary files /dev/null and b/src/all/lmanime/res/mipmap-xxxhdpi/ic_launcher.png differ
diff --git a/src/all/lmanime/src/eu/kanade/tachiyomi/animeextension/all/lmanime/LMAnime.kt b/src/all/lmanime/src/eu/kanade/tachiyomi/animeextension/all/lmanime/LMAnime.kt
new file mode 100644
index 000000000..73d0cbb04
--- /dev/null
+++ b/src/all/lmanime/src/eu/kanade/tachiyomi/animeextension/all/lmanime/LMAnime.kt
@@ -0,0 +1,344 @@
+package eu.kanade.tachiyomi.animeextension.all.lmanime
+
+import android.app.Application
+import android.content.SharedPreferences
+import android.util.Base64
+import androidx.preference.ListPreference
+import androidx.preference.MultiSelectListPreference
+import androidx.preference.PreferenceScreen
+import eu.kanade.tachiyomi.animeextension.all.lmanime.extractors.DailymotionExtractor
+import eu.kanade.tachiyomi.animesource.ConfigurableAnimeSource
+import eu.kanade.tachiyomi.animesource.model.AnimeFilterList
+import eu.kanade.tachiyomi.animesource.model.AnimesPage
+import eu.kanade.tachiyomi.animesource.model.SAnime
+import eu.kanade.tachiyomi.animesource.model.SEpisode
+import eu.kanade.tachiyomi.animesource.model.Video
+import eu.kanade.tachiyomi.animesource.online.ParsedAnimeHttpSource
+import eu.kanade.tachiyomi.lib.fembedextractor.FembedExtractor
+import eu.kanade.tachiyomi.lib.okruextractor.OkruExtractor
+import eu.kanade.tachiyomi.network.GET
+import eu.kanade.tachiyomi.network.asObservableSuccess
+import eu.kanade.tachiyomi.util.asJsoup
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.async
+import kotlinx.coroutines.awaitAll
+import kotlinx.coroutines.runBlocking
+import okhttp3.Request
+import okhttp3.Response
+import org.jsoup.nodes.Document
+import org.jsoup.nodes.Element
+import rx.Observable
+import uy.kohesive.injekt.Injekt
+import uy.kohesive.injekt.api.get
+import java.text.SimpleDateFormat
+import java.util.Locale
+
+class LMAnime : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
+
+ override val name = "LMAnime"
+
+ override val baseUrl = "https://lmanime.com"
+
+ override val lang = "all"
+
+ override val supportsLatest = true
+
+ private val preferences: SharedPreferences by lazy {
+ Injekt.get().getSharedPreferences("source_$id", 0x0000)
+ }
+
+ // ============================== Popular ===============================
+ override fun popularAnimeFromElement(element: Element): SAnime {
+ return SAnime.create().apply {
+ val ahref = element.selectFirst("h4 > a.series")!!
+ setUrlWithoutDomain(ahref.attr("href"))
+ title = ahref.text()
+ thumbnail_url = element.selectFirst("img")!!.attr("src")
+ }
+ }
+
+ override fun popularAnimeNextPageSelector() = null
+
+ override fun popularAnimeRequest(page: Int) = GET(baseUrl)
+
+ override fun popularAnimeSelector() = "div.serieslist.wpop-alltime li"
+
+ // ============================== Episodes ==============================
+ override fun episodeListParse(response: Response): List {
+ val doc = getRealDoc(response.asJsoup())
+ return doc.select(episodeListSelector()).map(::episodeFromElement)
+ }
+
+ override fun episodeFromElement(element: Element): SEpisode {
+ return SEpisode.create().apply {
+ setUrlWithoutDomain(element.attr("href"))
+ element.selectFirst("div.epl-title")!!.text().let {
+ name = it
+ episode_number = it.substringBefore(" (")
+ .substringAfterLast(" ")
+ .toFloatOrNull() ?: 0F
+ }
+
+ date_upload = element.selectFirst("div.epl-date")?.text().toDate()
+ }
+ }
+
+ override fun episodeListSelector() = "div.eplister > ul > li > a"
+
+ // =========================== Anime Details ============================
+ override fun animeDetailsParse(document: Document): SAnime {
+ val doc = getRealDoc(document)
+ return SAnime.create().apply {
+ setUrlWithoutDomain(doc.location())
+ title = doc.selectFirst("h1.entry-title")!!.text()
+ thumbnail_url = doc.selectFirst("div.thumb > img")!!.attr("src")
+
+ val infos = doc.selectFirst("div.info-content")!!
+ genre = infos.select("div.genxed > a").eachText().joinToString()
+ status = parseStatus(infos.getInfo("Status"))
+ artist = infos.getInfo("Studio")
+ author = infos.getInfo("Fansub")
+
+ description = buildString {
+ doc.selectFirst("div.entry-content")?.text()?.let {
+ append("$it\n\n")
+ }
+
+ infos.select("div.spe > span").eachText().forEach {
+ append("$it\n")
+ }
+ }
+ }
+ }
+
+ // ============================ Video Links =============================
+ override fun videoListSelector() = "select.mirror > option[data-index]"
+
+ override fun videoListParse(response: Response): List