sOolh?yh$Px=WX!EJdlB-Qqr)8OeG|Rb+Zh
z(>`460Dqy4C&d+|=YjqC$3I1td7BXq`o*o5f-v9mowU=dR#}k&$&p=t$Vxa&K_ApR
zttUghr1&JEHy`aM@WKKRHOP+J_!bI}KFX)m-4UY8N_kR4upJfVDYZbFtCr$VmDx|w
z*fBqMK;FY)o$JX)$@F=47#kbwA1
zdWTdPH6p$d-fXY3;iur3{WPNPw$km#>dEPg+-@|b2ukEbR}x_*dF}F#th>a*H*zCF
z(bsh9k1rZLexxWwu+R4rbT2=X2&WEiycPYP4hQx9v#u8wrm{*kNS5;;0{+B2i|)h%
z1I&BZOm%m}0l
z-k+~L_Yc@>d^zu#?CivIW6d>U;aXEEUCtkcP5xDkeQ|kEH`DeIux9sC3i!TsQ!IL^HB4RqX$p}KV-v~)$a$@
z_}uA<5UNT-ATI^`zvRnasbP{vLUrbURf)r6(;8^o)VL=dXzD8qO1vU{Evhk?An$_l
zBmNtPE|}3DN6_pIwIdUAD1@W|gmCe)c$5>Vr_yb1YpcP(Muj7S$e$MKs1lr_##;_v
zhU;kPzVvx;qcYzsEf>4)re?{!XVFptj_qdYGanhgnp}gs?A9+XRJ~AEm_;8?^cS+-
zMR#OB(0Hl_d?6iwmA0`ELz>0_KNo&uyb)RzvX&zARQnENvYNDGO-^glSpzJsN&$dJYNL9CSDx=
z-!@Dw5<(4Z2$%mFB){PfPW=kuD@RB+6Z=*)^9B1E?l(IefAE*WbW-?BYuWJxh^Ez1
zBGLY5Ytb#Ig=dR73Ti#QYB<_f#N~qhg^D^2-wE~pN{T))qOE(ek7kQj1{dNoLDPF)
zbU{cWQss0Vcs{KKbhT>r94u?nEPo0(7nhM>dQwY?ySNu09P(u>G++r#D13;NiF{3snj@4d5~ni
z#)3s$bMZihs*(rJVQR=H$$HX?!WLGD3%E_3(oIs!&CJ-%oX^z796SKn!238xRu)D!
zHZ>MrJ`Q$1HcomL7Csi16_r2a|DS-pqnWjZ_x~1P%6>3_>`^09LNkIV@!$0S$=AS0().getSharedPreferences("source_$id", 0x0000)
+ }
+
+ // ============================== Popular ===============================
+
+ override fun popularAnimeRequest(page: Int): Request {
+ val initialUrl = "$API_URL/ajaxPagination.php?categoryFilterOrderBy=vzViews&page=$page&categoryFilterOrderWay=desc&categoryFilterYearMin=1950&categoryFilterYearMax=2022"
+ val pageType = preferences.getString(PREF_POPULAR_PAGE_KEY, "movie")!!
+ val finalUrl = if ("movie" in pageType) {
+ initialUrl + "&saga=0&categoriesListMovies=all"
+ } else {
+ (initialUrl + "&categoriesListSeries=all").let {
+ if ("anime" in pageType) it + "&anime=1"
+ else it + "&anime=0"
+ }
+ }
+ return GET(finalUrl)
+ }
+
+ override fun popularAnimeParse(response: Response): AnimesPage {
+ val result = response.parseAs()
+ val animes = result.list.map(::animeFromObject).toList()
+ val hasNext = result.quantity == 35
+ return AnimesPage(animes, hasNext)
+ }
+
+ private fun animeFromObject(item: SearchItemDto): SAnime =
+ SAnime.create().apply {
+ var slug = if (item.status.isBlank()) "filme" else "serie"
+ url = "/$slug/online/${item.url}"
+ slug = if (slug == "filme") "movies" else "series"
+ title = item.title
+ status = when (item.status) {
+ "Retornando" -> SAnime.ONGOING
+ else -> SAnime.COMPLETED
+ }
+ thumbnail_url = "$baseUrl/content/$slug/posterPt/342/${item.id}.webp"
+ }
+
+ // ============================== Episodes ==============================
+
+ private fun getSeasonEps(seasonElement: Element): List {
+ val id = seasonElement.attr("data-season-id")
+ val sname = seasonElement.text()
+ val response = client.newCall(apiRequest("getEpisodes=$id")).execute()
+ val episodes = response.parseAs().episodes.mapNotNull {
+ if (it.released)
+ SEpisode.create().apply {
+ name = "Temp $sname: Ep ${it.name} - ${it.title}"
+ episode_number = it.name.toFloatOrNull() ?: 0F
+ url = it.id
+ }
+ else null
+ }
+ return episodes
+ }
+
+ override fun episodeListParse(response: Response): List {
+ val doc = response.asJsoup()
+ val seasons = doc.select("div#seasonsList div.item[data-season-id]")
+ return if (seasons.size > 0) {
+ seasons.flatMap(::getSeasonEps).reversed()
+ } else {
+ listOf(
+ SEpisode.create().apply {
+ name = "Filme"
+ episode_number = 1F
+ url = response.request.url.toString()
+ }
+ )
+ }
+ }
+
+ // ============================ Video Links =============================
+
+ override fun videoListRequest(episode: SEpisode): Request {
+ val url = episode.url
+ return if (url.startsWith("https")) {
+ // Its an real url, maybe from a movie
+ GET(url, headers)
+ } else {
+ // Fake url, its an ID that will be used to get episode languages
+ // (sub/dub) and then return the video link
+ apiRequest("getEpisodeLanguages=$url")
+ }
+ }
+
+ override fun videoListParse(response: Response): List