diff --git a/multisrc/overrides/mangasar/default/additional.gradle.kts b/multisrc/overrides/mangasar/default/additional.gradle.kts
new file mode 100644
index 000000000..10beb8157
--- /dev/null
+++ b/multisrc/overrides/mangasar/default/additional.gradle.kts
@@ -0,0 +1,4 @@
+
+dependencies {
+    implementation project(':lib-ratelimit')
+}
diff --git a/src/pt/mangatube/res/mipmap-hdpi/ic_launcher.png b/multisrc/overrides/mangasar/default/res/mipmap-hdpi/ic_launcher.png
similarity index 100%
rename from src/pt/mangatube/res/mipmap-hdpi/ic_launcher.png
rename to multisrc/overrides/mangasar/default/res/mipmap-hdpi/ic_launcher.png
diff --git a/multisrc/overrides/mangasar/default/res/mipmap-mdpi/ic_launcher.png b/multisrc/overrides/mangasar/default/res/mipmap-mdpi/ic_launcher.png
new file mode 100644
index 000000000..aa7edff85
Binary files /dev/null and b/multisrc/overrides/mangasar/default/res/mipmap-mdpi/ic_launcher.png differ
diff --git a/multisrc/overrides/mangasar/default/res/mipmap-xhdpi/ic_launcher.png b/multisrc/overrides/mangasar/default/res/mipmap-xhdpi/ic_launcher.png
new file mode 100644
index 000000000..0dfe9e075
Binary files /dev/null and b/multisrc/overrides/mangasar/default/res/mipmap-xhdpi/ic_launcher.png differ
diff --git a/multisrc/overrides/mangasar/default/res/mipmap-xxhdpi/ic_launcher.png b/multisrc/overrides/mangasar/default/res/mipmap-xxhdpi/ic_launcher.png
new file mode 100644
index 000000000..1690d709e
Binary files /dev/null and b/multisrc/overrides/mangasar/default/res/mipmap-xxhdpi/ic_launcher.png differ
diff --git a/multisrc/overrides/mangasar/default/res/mipmap-xxxhdpi/ic_launcher.png b/multisrc/overrides/mangasar/default/res/mipmap-xxxhdpi/ic_launcher.png
new file mode 100644
index 000000000..39f7dda6a
Binary files /dev/null and b/multisrc/overrides/mangasar/default/res/mipmap-xxxhdpi/ic_launcher.png differ
diff --git a/multisrc/overrides/mangasar/default/res/web_hi_res_512.png b/multisrc/overrides/mangasar/default/res/web_hi_res_512.png
new file mode 100644
index 000000000..5b26d20e5
Binary files /dev/null and b/multisrc/overrides/mangasar/default/res/web_hi_res_512.png differ
diff --git a/multisrc/overrides/mangasar/mangatube/res/mipmap-hdpi/ic_launcher.png b/multisrc/overrides/mangasar/mangatube/res/mipmap-hdpi/ic_launcher.png
new file mode 100644
index 000000000..5f3c83a4c
Binary files /dev/null and b/multisrc/overrides/mangasar/mangatube/res/mipmap-hdpi/ic_launcher.png differ
diff --git a/src/pt/mangatube/res/mipmap-mdpi/ic_launcher.png b/multisrc/overrides/mangasar/mangatube/res/mipmap-mdpi/ic_launcher.png
similarity index 100%
rename from src/pt/mangatube/res/mipmap-mdpi/ic_launcher.png
rename to multisrc/overrides/mangasar/mangatube/res/mipmap-mdpi/ic_launcher.png
diff --git a/src/pt/mangatube/res/mipmap-xhdpi/ic_launcher.png b/multisrc/overrides/mangasar/mangatube/res/mipmap-xhdpi/ic_launcher.png
similarity index 100%
rename from src/pt/mangatube/res/mipmap-xhdpi/ic_launcher.png
rename to multisrc/overrides/mangasar/mangatube/res/mipmap-xhdpi/ic_launcher.png
diff --git a/src/pt/mangatube/res/mipmap-xxhdpi/ic_launcher.png b/multisrc/overrides/mangasar/mangatube/res/mipmap-xxhdpi/ic_launcher.png
similarity index 100%
rename from src/pt/mangatube/res/mipmap-xxhdpi/ic_launcher.png
rename to multisrc/overrides/mangasar/mangatube/res/mipmap-xxhdpi/ic_launcher.png
diff --git a/src/pt/mangatube/res/mipmap-xxxhdpi/ic_launcher.png b/multisrc/overrides/mangasar/mangatube/res/mipmap-xxxhdpi/ic_launcher.png
similarity index 100%
rename from src/pt/mangatube/res/mipmap-xxxhdpi/ic_launcher.png
rename to multisrc/overrides/mangasar/mangatube/res/mipmap-xxxhdpi/ic_launcher.png
diff --git a/src/pt/mangatube/res/web_hi_res_512.png b/multisrc/overrides/mangasar/mangatube/res/web_hi_res_512.png
similarity index 100%
rename from src/pt/mangatube/res/web_hi_res_512.png
rename to multisrc/overrides/mangasar/mangatube/res/web_hi_res_512.png
diff --git a/multisrc/overrides/mangasar/mangatube/src/MangaTube.kt b/multisrc/overrides/mangasar/mangatube/src/MangaTube.kt
new file mode 100644
index 000000000..876dc3952
--- /dev/null
+++ b/multisrc/overrides/mangasar/mangatube/src/MangaTube.kt
@@ -0,0 +1,18 @@
+package eu.kanade.tachiyomi.extension.pt.mangatube
+
+import eu.kanade.tachiyomi.lib.ratelimit.RateLimitInterceptor
+import eu.kanade.tachiyomi.multisrc.mangasar.MangaSar
+import okhttp3.OkHttpClient
+import java.util.concurrent.TimeUnit
+
+class MangaTube : MangaSar(
+    "MangaTube",
+    "https://mangatube.site",
+    "pt-BR"
+) {
+
+    override val client: OkHttpClient = super.client.newBuilder()
+        .addInterceptor(::searchIntercept)
+        .addInterceptor(RateLimitInterceptor(1, 2, TimeUnit.SECONDS))
+        .build()
+}
diff --git a/multisrc/overrides/mangasar/meusmangas/src/MeusMangas.kt b/multisrc/overrides/mangasar/meusmangas/src/MeusMangas.kt
new file mode 100644
index 000000000..8c443ff53
--- /dev/null
+++ b/multisrc/overrides/mangasar/meusmangas/src/MeusMangas.kt
@@ -0,0 +1,52 @@
+package eu.kanade.tachiyomi.extension.pt.meusmangas
+
+import eu.kanade.tachiyomi.annotations.Nsfw
+import eu.kanade.tachiyomi.lib.ratelimit.RateLimitInterceptor
+import eu.kanade.tachiyomi.multisrc.mangasar.MangaSar
+import eu.kanade.tachiyomi.source.model.SManga
+import eu.kanade.tachiyomi.util.asJsoup
+import okhttp3.OkHttpClient
+import okhttp3.Response
+import org.jsoup.nodes.Element
+import java.util.concurrent.TimeUnit
+
+@Nsfw
+class MeusMangas : MangaSar(
+    "Meus Mangás",
+    "https://meusmangas.net",
+    "pt-BR"
+) {
+
+    override val client: OkHttpClient = super.client.newBuilder()
+        .addInterceptor(::searchIntercept)
+        .addInterceptor(RateLimitInterceptor(1, 2, TimeUnit.SECONDS))
+        .build()
+
+    override fun popularMangaSelector() = "ul.sidebar-popular li.popular-treending"
+
+    override fun popularMangaFromElement(element: Element): SManga = SManga.create().apply {
+        title = element.selectFirst("h4.title").text()
+        thumbnail_url = element.selectFirst("div.tumbl img").attr("src")
+        setUrlWithoutDomain(element.selectFirst("a").attr("abs:href"))
+    }
+
+    override fun mangaDetailsParse(response: Response): SManga {
+        val document = response.asJsoup()
+        val infoElement = document.selectFirst("div.box-single:has(div.mangapage)")
+
+        return SManga.create().apply {
+            title = infoElement.selectFirst("h1.kw-title").text()
+            author = infoElement.selectFirst("div.mdq.author").text().trim()
+            description = infoElement.selectFirst("div.sinopse-page").text()
+            genre = infoElement.select("div.touchcarousel a.widget-btn").joinToString { it.text() }
+            status = infoElement.selectFirst("span.mdq").text().toStatus()
+            thumbnail_url = infoElement.selectFirst("div.thumb img").attr("abs:src")
+        }
+    }
+
+    private fun String.toStatus(): Int = when (this) {
+        "Em andamento" -> SManga.ONGOING
+        "Completo" -> SManga.COMPLETED
+        else -> SManga.UNKNOWN
+    }
+}
diff --git a/src/pt/mangatube/src/eu/kanade/tachiyomi/extension/pt/mangatube/MangaTube.kt b/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/mangasar/MangaSar.kt
similarity index 87%
rename from src/pt/mangatube/src/eu/kanade/tachiyomi/extension/pt/mangatube/MangaTube.kt
rename to multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/mangasar/MangaSar.kt
index 4440e5bd6..960b8b25b 100644
--- a/src/pt/mangatube/src/eu/kanade/tachiyomi/extension/pt/mangatube/MangaTube.kt
+++ b/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/mangasar/MangaSar.kt
@@ -1,6 +1,5 @@
-package eu.kanade.tachiyomi.extension.pt.mangatube
+package eu.kanade.tachiyomi.multisrc.mangasar
 
-import eu.kanade.tachiyomi.lib.ratelimit.RateLimitInterceptor
 import eu.kanade.tachiyomi.network.GET
 import eu.kanade.tachiyomi.network.POST
 import eu.kanade.tachiyomi.source.model.FilterList
@@ -24,27 +23,22 @@ import okhttp3.OkHttpClient
 import okhttp3.Request
 import okhttp3.Response
 import org.jsoup.nodes.Element
+import org.jsoup.parser.Parser
 import rx.Observable
 import uy.kohesive.injekt.injectLazy
 import java.text.ParseException
 import java.text.SimpleDateFormat
 import java.util.Locale
-import java.util.concurrent.TimeUnit
 
-class MangaTube : HttpSource() {
-
-    override val name = "MangaTube"
-
-    override val baseUrl = "https://mangatube.site"
-
-    override val lang = "pt-BR"
+abstract class MangaSar(
+    override val name: String,
+    override val baseUrl: String,
+    override val lang: String
+) : HttpSource() {
 
     override val supportsLatest = true
 
-    override val client: OkHttpClient = network.cloudflareClient.newBuilder()
-        .addInterceptor(RateLimitInterceptor(1, 2, TimeUnit.SECONDS))
-        .addInterceptor(::searchIntercept)
-        .build()
+    override val client: OkHttpClient = network.cloudflareClient
 
     override fun headersBuilder(): Headers.Builder = Headers.Builder()
         .add("Accept", ACCEPT_HTML)
@@ -66,13 +60,16 @@ class MangaTube : HttpSource() {
     override fun popularMangaParse(response: Response): MangasPage {
         val document = response.asJsoup()
 
-        val mangas = document.select("div:contains(Populares) ~ ul.mangasList li div.gridbox")
+        val mangas = document.select(popularMangaSelector())
             .map(::popularMangaFromElement)
 
         return MangasPage(mangas, hasNextPage = false)
     }
 
-    private fun popularMangaFromElement(element: Element): SManga = SManga.create().apply {
+    protected open fun popularMangaSelector(): String =
+        "div:contains(Populares) ~ ul.mangasList li div.gridbox"
+
+    protected open fun popularMangaFromElement(element: Element): SManga = SManga.create().apply {
         title = element.select("div.title a").first()!!.text()
         thumbnail_url = element.select("div.thumb img").first()!!.attr("abs:src")
         setUrlWithoutDomain(element.select("a").first()!!.attr("href"))
@@ -92,18 +89,19 @@ class MangaTube : HttpSource() {
     }
 
     override fun latestUpdatesParse(response: Response): MangasPage {
-        val result = json.decodeFromString<MangaTubeLatestDto>(response.body!!.string())
+        val result = json.decodeFromString<MangaSarLatestDto>(response.body!!.string())
 
         val latestMangas = result.releases
             .map(::latestUpdatesFromObject)
+            .distinctBy { it.url }
 
         val hasNextPage = result.page.toInt() < result.totalPage
 
         return MangasPage(latestMangas, hasNextPage)
     }
 
-    private fun latestUpdatesFromObject(release: MangaTubeReleaseDto) = SManga.create().apply {
-        title = release.name
+    private fun latestUpdatesFromObject(release: MangaSarReleaseDto) = SManga.create().apply {
+        title = release.name.withoutEntities()
         thumbnail_url = release.image
         url = release.link
     }
@@ -118,14 +116,14 @@ class MangaTube : HttpSource() {
     }
 
     override fun searchMangaParse(response: Response): MangasPage {
-        val result = json.decodeFromString<Map<String, MangaTubeTitleDto>>(response.body!!.string())
+        val result = json.decodeFromString<Map<String, MangaSarTitleDto>>(response.body!!.string())
 
         val searchResults = result.values.map(::searchMangaFromObject)
 
         return MangasPage(searchResults, hasNextPage = false)
     }
 
-    private fun searchMangaFromObject(manga: MangaTubeTitleDto) = SManga.create().apply {
+    private fun searchMangaFromObject(manga: MangaSarTitleDto) = SManga.create().apply {
         title = manga.title
         thumbnail_url = manga.image
         setUrlWithoutDomain(manga.url)
@@ -164,7 +162,7 @@ class MangaTube : HttpSource() {
     override fun chapterListParse(response: Response): List<SChapter> {
         val mangaUrl = response.request.header("Referer")!!.substringAfter(baseUrl)
 
-        var result = json.decodeFromString<MangaTubePaginatedChaptersDto>(response.body!!.string())
+        var result = json.decodeFromString<MangaSarPaginatedChaptersDto>(response.body!!.string())
 
         if (result.chapters.isNullOrEmpty()) {
             return emptyList()
@@ -191,7 +189,7 @@ class MangaTube : HttpSource() {
         return chapters
     }
 
-    private fun chapterFromObject(chapter: MangaTubeChapterDto): SChapter = SChapter.create().apply {
+    private fun chapterFromObject(chapter: MangaSarChapterDto): SChapter = SChapter.create().apply {
         name = "Cap. " + (if (chapter.number.booleanOrNull != null) "0" else chapter.number.content) +
             (if (chapter.name.isString) " - " + chapter.name.content else "")
         chapter_number = chapter.number.floatOrNull ?: -1f
@@ -224,7 +222,7 @@ class MangaTube : HttpSource() {
 
         val apiRequest = pageListApiRequest(chapterUrl, serieId, token)
         val apiResponse = client.newCall(apiRequest).execute().let {
-            json.decodeFromString<MangaTubeReaderDto>(it.body!!.string())
+            json.decodeFromString<MangaSarReaderDto>(it.body!!.string())
         }
 
         return apiResponse.images
@@ -245,7 +243,7 @@ class MangaTube : HttpSource() {
         return GET(page.imageUrl!!, newHeaders)
     }
 
-    private fun searchIntercept(chain: Interceptor.Chain): Response {
+    protected fun searchIntercept(chain: Interceptor.Chain): Response {
         if (chain.request().url.toString().contains("/search/")) {
             val homeRequest = popularMangaRequest(1)
             val document = chain.proceed(homeRequest).asJsoup()
@@ -278,6 +276,10 @@ class MangaTube : HttpSource() {
         }
     }
 
+    private fun String.withoutEntities(): String {
+        return Parser.unescapeEntities(this, true)
+    }
+
     companion object {
         private const val ACCEPT = "application/json, text/plain, */*"
         private const val ACCEPT_HTML = "text/html,application/xhtml+xml,application/xml;q=0.9," +
diff --git a/src/pt/mangatube/src/eu/kanade/tachiyomi/extension/pt/mangatube/MangaTubeDto.kt b/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/mangasar/MangaSarDto.kt
similarity index 62%
rename from src/pt/mangatube/src/eu/kanade/tachiyomi/extension/pt/mangatube/MangaTubeDto.kt
rename to multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/mangasar/MangaSarDto.kt
index 9e9e678d1..3974adb19 100644
--- a/src/pt/mangatube/src/eu/kanade/tachiyomi/extension/pt/mangatube/MangaTubeDto.kt
+++ b/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/mangasar/MangaSarDto.kt
@@ -1,39 +1,39 @@
-package eu.kanade.tachiyomi.extension.pt.mangatube
+package eu.kanade.tachiyomi.multisrc.mangasar
 
 import kotlinx.serialization.SerialName
 import kotlinx.serialization.Serializable
 import kotlinx.serialization.json.JsonPrimitive
 
 @Serializable
-data class MangaTubeLatestDto(
+data class MangaSarLatestDto(
     val page: String,
-    val releases: List<MangaTubeReleaseDto> = emptyList(),
+    val releases: List<MangaSarReleaseDto> = emptyList(),
     @SerialName("total_page") val totalPage: Int
 )
 
 @Serializable
-data class MangaTubeReleaseDto(
+data class MangaSarReleaseDto(
     val image: String,
     val link: String,
     val name: String
 )
 
 @Serializable
-data class MangaTubeTitleDto(
+data class MangaSarTitleDto(
     @SerialName("img") val image: String,
     val title: String,
     val url: String
 )
 
 @Serializable
-data class MangaTubePaginatedChaptersDto(
-    val chapters: List<MangaTubeChapterDto>? = emptyList(),
+data class MangaSarPaginatedChaptersDto(
+    val chapters: List<MangaSarChapterDto>? = emptyList(),
     @SerialName("pagina") val page: Int,
     @SerialName("total_pags") val totalPages: Int
 )
 
 @Serializable
-data class MangaTubeChapterDto(
+data class MangaSarChapterDto(
     @SerialName("date_created") val dateCreated: String,
     val link: String,
     @SerialName("chapter_name") val name: JsonPrimitive,
@@ -41,11 +41,11 @@ data class MangaTubeChapterDto(
 )
 
 @Serializable
-data class MangaTubeReaderDto(
-    val images: List<MangaTubePageDto> = emptyList()
+data class MangaSarReaderDto(
+    val images: List<MangaSarPageDto> = emptyList()
 )
 
 @Serializable
-data class MangaTubePageDto(
+data class MangaSarPageDto(
     val url: String
 )
diff --git a/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/mangasar/MangaSarGenerator.kt b/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/mangasar/MangaSarGenerator.kt
new file mode 100644
index 000000000..b2aa25992
--- /dev/null
+++ b/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/mangasar/MangaSarGenerator.kt
@@ -0,0 +1,26 @@
+package eu.kanade.tachiyomi.multisrc.mangasar
+
+import generator.ThemeSourceData.SingleLang
+import generator.ThemeSourceGenerator
+
+class MangaSarGenerator : ThemeSourceGenerator {
+
+    override val themePkg = "mangasar"
+
+    override val themeClass = "MangaSar"
+
+    override val baseVersionCode: Int = 4
+
+    override val sources = listOf(
+    	SingleLang("MangaTube", "https://mangatube.site", "pt-BR"),
+    	SingleLang("Meus Mangás", "https://meusmangas.net", "pt-BR", isNsfw = true, className = "MeusMangas")
+    )
+
+    companion object {
+        @JvmStatic
+        fun main(args: Array<String>) {
+            MangaSarGenerator().createAll()
+        }
+    }
+}
+
diff --git a/src/pt/mangatube/AndroidManifest.xml b/src/pt/mangatube/AndroidManifest.xml
deleted file mode 100644
index 30deb7f79..000000000
--- a/src/pt/mangatube/AndroidManifest.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<manifest package="eu.kanade.tachiyomi.extension" />
diff --git a/src/pt/mangatube/build.gradle b/src/pt/mangatube/build.gradle
deleted file mode 100644
index 3cad5f847..000000000
--- a/src/pt/mangatube/build.gradle
+++ /dev/null
@@ -1,18 +0,0 @@
-apply plugin: 'com.android.application'
-apply plugin: 'kotlin-android'
-apply plugin: 'kotlinx-serialization'
-
-ext {
-    extName = 'MangaTube'
-    pkgNameSuffix = 'pt.mangatube'
-    extClass = '.MangaTube'
-    extVersionCode = 3
-    libVersion = '1.2'
-}
-
-dependencies {
-    implementation project(':lib-ratelimit')
-}
-
-apply from: "$rootDir/common.gradle"
-