[
  {
    "path": ".gitignore",
    "content": "*.iml\n.gradle\n/local.properties\n/.idea/caches\n/.idea/libraries\n/.idea/modules.xml\n/.idea/workspace.xml\n/.idea/navEditor.xml\n/.idea/assetWizardSettings.xml\n.DS_Store\n/build\n/captures\n.externalNativeBuild\n.cxx\nlocal.properties\n"
  },
  {
    "path": ".idea/.gitignore",
    "content": "# Default ignored files\n/shelf/\n/workspace.xml\n"
  },
  {
    "path": ".idea/compiler.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"CompilerConfiguration\">\n    <bytecodeTargetLevel target=\"17\" />\n  </component>\n</project>"
  },
  {
    "path": ".idea/gradle.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"GradleMigrationSettings\" migrationVersion=\"1\" />\n  <component name=\"GradleSettings\">\n    <option name=\"linkedExternalProjectsSettings\">\n      <GradleProjectSettings>\n        <option name=\"testRunner\" value=\"GRADLE\" />\n        <option name=\"distributionType\" value=\"DEFAULT_WRAPPED\" />\n        <option name=\"externalProjectPath\" value=\"$PROJECT_DIR$\" />\n        <option name=\"modules\">\n          <set>\n            <option value=\"$PROJECT_DIR$\" />\n            <option value=\"$PROJECT_DIR$/app\" />\n          </set>\n        </option>\n      </GradleProjectSettings>\n    </option>\n  </component>\n</project>"
  },
  {
    "path": ".idea/kotlinc.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"KotlinJpsPluginSettings\">\n    <option name=\"version\" value=\"1.9.0\" />\n  </component>\n</project>"
  },
  {
    "path": ".idea/misc.xml",
    "content": "<project version=\"4\">\n  <component name=\"ExternalStorageConfigurationManager\" enabled=\"true\" />\n  <component name=\"ProjectRootManager\" version=\"2\" languageLevel=\"JDK_17\" project-jdk-name=\"jbr-17\" project-jdk-type=\"JavaSDK\">\n    <output url=\"file://$PROJECT_DIR$/build/classes\" />\n  </component>\n  <component name=\"ProjectType\">\n    <option name=\"id\" value=\"Android\" />\n  </component>\n  <component name=\"VisualizationToolProject\">\n    <option name=\"state\">\n      <ProjectState>\n        <option name=\"scale\" value=\"0.025\" />\n      </ProjectState>\n    </option>\n  </component>\n</project>"
  },
  {
    "path": ".idea/vcs.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"VcsDirectoryMappings\">\n    <mapping directory=\"$PROJECT_DIR$\" vcs=\"Git\" />\n  </component>\n</project>"
  },
  {
    "path": "README.md",
    "content": "# Tokei    <img src=\"https://github.com/Sovan22/Tokeii/blob/master/app/tokei_logo.jpeg\" width=\"40\" height=\"40\" alt=\"Image Description\">\nMovie and TV Streaming App \n\n\n## Download the app here:\n# [tokei-release_v1.1.4](https://github.com/Sovan22/Tokeii/releases/download/v1.1.4-tokei/tokei-v1.1.4.apk)\nCompatibility : Android 7+\n\n## Features:\n+ **AdFree**\n+ No tracking/analytics\n+ Lesser Loading Time\n+ Good sources for Indian OTT Content\n\n## App Demo\n\nhttps://github.com/Sovan22/Tokeii/assets/12212201/b417be95-d728-4af8-9809-b2fcdfde1c5f\n\n\n\n<img src=\"https://github.com/Sovan22/Tokeii/blob/master/app/movies.jpg\" width=\"400\" height=\"900\" alt=\"Movies\">  <img src=\"https://github.com/Sovan22/Tokeii/blob/master/app/search.jpg\" width=\"400\" height=\"900\" alt=\"Search\">\n\n<img src=\"https://github.com/Sovan22/Tokeii/blob/master/app/player.jpg\"  alt=\"Player\">\n\n## DISCLAIMER\n\n+ Tokei only scrapes links from various websites and makes it easier for users to find tvShows and movies. \n+ Tokei doesn't host any of the contents found inside Tokei. Any and all images and movie/tv information found in the app are taken from various public APIs (TMDb). \n+ Furthermore, all of the movie/tv links found in Tokei are taken from various 3rd party hosting websites.\n+ Tokei or it's owners aren't liable for any misuse of any of the contents found inside or outside of the app and cannot be held accountable for the distribution of any of the contents found inside the app. \n+ By using Tokei, you comply to the fact that the developer of the app is not responsible for any of the contents found in the app; nonetheless they may or may not be from their legitimate sources. \n+ If the internet infringement issues are involved, please contact the source website. The developer does not assume any legal responsibility.\n"
  },
  {
    "path": "app/.gitignore",
    "content": "/build"
  },
  {
    "path": "app/build.gradle",
    "content": "\n\nplugins {\n    id 'com.android.application'\n    id 'org.jetbrains.kotlin.android'\n    id(\"androidx.navigation.safeargs.kotlin\")\n    id(\"com.google.devtools.ksp\")\n\n\n}\n\ndef localProperties = new Properties()\nlocalProperties.load(new FileInputStream(rootProject.file(\"local.properties\")))\n\nandroid {\n    namespace 'com.demomiru.tokeiv2'\n    compileSdk 34\n\n    packagingOptions {\n        pickFirst \"META-INF/DEPENDENCIES\"\n        exclude 'mozilla/public-suffix-list.txt'\n    }\n    defaultConfig {\n        applicationId \"com.demomiru.tokeiv2\"\n        minSdk 26\n        targetSdk 34\n        versionCode 1\n        versionName \"1.1.4\"\n\n        testInstrumentationRunner \"androidx.test.runner.AndroidJUnitRunner\"\n\n        buildConfigField(\"String\", \"OPEN_SUBTITLE_API_KEY\", \"\\\"${localProperties[\"OPEN_SUBTITLE_API_KEY\"]}\\\"\")\n        buildConfigField(\"String\", \"TMDB_API_KEY\", \"\\\"${localProperties[\"TMDB_API_KEY\"]}\\\"\")\n        buildConfigField(\"String\", \"TMDB_TOKEN\", \"\\\"${localProperties[\"TMDB_TOKEN\"]}\\\"\")\n        buildConfigField(\"String\", \"SUPERSTREAM_API1\", \"\\\"${localProperties[\"SUPERSTREAM_API1\"]}\\\"\")\n        buildConfigField(\"String\", \"SUPERSTREAM_API2\", \"\\\"${localProperties[\"SUPERSTREAM_API2\"]}\\\"\")\n        buildConfigField(\"String\", \"PROXY_URL\", \"\\\"${localProperties[\"PROXY_URL\"]}\\\"\")\n        buildConfigField(\"String\", \"MAL_API\", \"\\\"${localProperties[\"MAL_API\"]}\\\"\")\n    }\n\n    buildTypes {\n        release {\n            minifyEnabled false\n            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'\n        }\n    }\n    compileOptions {\n        sourceCompatibility JavaVersion.VERSION_1_8\n        targetCompatibility JavaVersion.VERSION_1_8\n    }\n    kotlinOptions {\n        jvmTarget = '1.8'\n    }\n    buildFeatures{\n        viewBinding true\n        buildConfig true\n    }\n}\n\ndependencies {\n\n    def paging_version = \"3.2.1\"\n\n    implementation \"androidx.paging:paging-runtime:$paging_version\"\n    implementation 'com.github.ismaeldivita:chip-navigation-bar:1.4.0'\n\n    implementation 'androidx.core:core-ktx:1.9.0'\n    implementation \"androidx.lifecycle:lifecycle-runtime-ktx:2.3.1\"\n    implementation \"androidx.lifecycle:lifecycle-livedata-ktx:2.2.0\"\n    implementation 'androidx.cardview:cardview:1.0.0'\n    implementation 'at.blogc:expandabletextview:1.0.5'\n    implementation \"androidx.navigation:navigation-fragment-ktx:2.7.1\"\n    implementation \"androidx.navigation:navigation-ui-ktx:2.7.1\"\n    implementation 'com.google.firebase:firebase-firestore-ktx:24.1.0'\n    ksp(\"androidx.room:room-compiler:2.5.0\")\n    implementation \"androidx.activity:activity-ktx:1.7.2\"\n    implementation 'androidx.appcompat:appcompat:1.6.1'\n//    implementation(\"it.skrape:skrapeit:1.2.2\")\n//    implementation 'org.jsoup:jsoup:1.14.3'\n//    implementation 'org.danilopianini:khttp:1.3.1'\n    implementation 'com.github.Blatzar:NiceHttp:0.4.4'\n    implementation 'com.fasterxml.jackson.module:jackson-module-kotlin:2.15.2'\n    implementation(\"com.squareup.okhttp3:okhttp:4.10.0\")\n    implementation 'com.squareup.retrofit2:retrofit:2.9.0'\n    implementation 'com.squareup.retrofit2:converter-gson:2.9.0'\n    implementation \"org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.2\"\n    implementation 'com.google.android.material:material:1.9.0'\n    implementation 'androidx.constraintlayout:constraintlayout:2.1.4'\n    implementation(\"io.coil-kt:coil:2.4.0\")\n    // Room components\n    implementation \"androidx.room:room-runtime:2.5.0\"\n//    annotationProcessor \"androidx.room:room-compiler:2.5.2\"\n    implementation \"androidx.room:room-ktx:2.5.0\"\n\n    //ExoPlayer\n    implementation \"androidx.media3:media3-exoplayer:1.1.1\"\n    implementation \"androidx.media3:media3-exoplayer-hls:1.1.1\"\n    implementation \"androidx.media3:media3-exoplayer-dash:1.1.1\"\n    implementation \"androidx.media3:media3-ui:1.1.1\"\n\n\n    testImplementation 'junit:junit:4.13.2'\n    androidTestImplementation 'androidx.test.ext:junit:1.1.5'\n    androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'\n}\n"
  },
  {
    "path": "app/proguard-rules.pro",
    "content": "# Add project specific ProGuard rules here.\n# You can control the set of applied configuration files using the\n# proguardFiles setting in build.gradle.\n#\n# For more details, see\n#   http://developer.android.com/guide/developing/tools/proguard.html\n\n# If your project uses WebView with JS, uncomment the following\n# and specify the fully qualified class name to the JavaScript interface\n# class:\n#-keepclassmembers class fqcn.of.javascript.interface.for.webview {\n#   public *;\n#}\n\n# Uncomment this to preserve the line number information for\n# debugging stack traces.\n#-keepattributes SourceFile,LineNumberTable\n\n# If you keep the line number information, uncomment this to\n# hide the original source file name.\n#-renamesourcefileattribute SourceFile"
  },
  {
    "path": "app/src/androidTest/java/com/demomiru/tokeiv2/ExampleInstrumentedTest.kt",
    "content": "package com.demomiru.tokeiv2\n\nimport androidx.test.platform.app.InstrumentationRegistry\nimport androidx.test.ext.junit.runners.AndroidJUnit4\n\nimport org.junit.Test\nimport org.junit.runner.RunWith\n\nimport org.junit.Assert.*\n\n/**\n * Instrumented test, which will execute on an Android device.\n *\n * See [testing documentation](http://d.android.com/tools/testing).\n */\n@RunWith(AndroidJUnit4::class)\nclass ExampleInstrumentedTest {\n    @Test\n    fun useAppContext() {\n        // Context of the app under test.\n        val appContext = InstrumentationRegistry.getInstrumentation().targetContext\n        assertEquals(\"com.demomiru.tokeiv2\", appContext.packageName)\n    }\n}"
  },
  {
    "path": "app/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:tools=\"http://schemas.android.com/tools\">\n\n    <uses-permission android:name=\"android.permission.INTERNET\" />\n    <uses-permission android:name=\"android.permission.MODIFY_AUDIO_SETTINGS\" />\n    <uses-permission android:name=\"android.permission.WAKE_LOCK\" />\n\n    <application\n        android:allowBackup=\"true\"\n\n        android:dataExtractionRules=\"@xml/data_extraction_rules\"\n        android:fullBackupContent=\"@xml/backup_rules\"\n        android:icon=\"@mipmap/ic_launcher\"\n        android:label=\"@string/app_name\"\n        android:roundIcon=\"@mipmap/ic_launcher\"\n        android:supportsRtl=\"true\"\n        android:theme=\"@style/AppTheme\"\n        android:usesCleartextTraffic=\"true\"\n        tools:targetApi=\"31\">\n        <activity\n            android:name=\".VideoPlayActivity\"\n            android:screenOrientation=\"landscape\"\n            android:exported=\"false\" />\n        <activity\n            android:name=\".MoviePlayActivity\"\n            android:exported=\"false\"\n            android:screenOrientation=\"landscape\" />\n        <activity\n            android:name=\".MainActivity\"\n            android:exported=\"true\"\n            android:screenOrientation=\"fullSensor\"\n            tools:ignore=\"LockedOrientationActivity\">\n            <intent-filter>\n                <action android:name=\"android.intent.action.MAIN\" />\n\n                <category android:name=\"android.intent.category.LAUNCHER\" />\n            </intent-filter>\n        </activity>\n\n        <meta-data\n            android:name=\"preloaded_fonts\"\n            android:resource=\"@array/preloaded_fonts\" />\n    </application>\n\n</manifest>"
  },
  {
    "path": "app/src/main/java/com/demomiru/tokeiv2/EpisodeAdapter.kt",
    "content": "package com.demomiru.tokeiv2\n\n\n\nimport android.annotation.SuppressLint\nimport android.view.LayoutInflater\nimport android.view.View\nimport android.view.ViewGroup\nimport android.widget.TextView\nimport androidx.recyclerview.widget.RecyclerView\n\nclass EpisodeAdapter(private val episodeNumber : List<Int>,\nprivate val clickHandler : (Int) -> Unit\n) : RecyclerView.Adapter<EpisodeAdapter.ViewHolder>() {\n\n    class ViewHolder(itemView : View) : RecyclerView.ViewHolder(itemView){\n        val episodeText : TextView = itemView.findViewById(R.id.episode_no_text)\n    }\n\n    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {\n       val view = LayoutInflater.from(parent.context).inflate(R.layout.episode_item_viem,parent,false)\n        return ViewHolder(view)\n    }\n\n    @SuppressLint(\"SetTextI18n\")\n    override fun onBindViewHolder(holder: ViewHolder, position: Int) {\n        val episodeN = episodeNumber[position]\n        holder.episodeText.text = \"Episode $episodeN\"\n        holder.itemView.setOnClickListener {\n            clickHandler(episodeN)\n        }\n    }\n\n    override fun getItemCount(): Int {\n        return episodeNumber.size\n    }\n}"
  },
  {
    "path": "app/src/main/java/com/demomiru/tokeiv2/EpisodeAdapter2.kt",
    "content": "package com.demomiru.tokeiv2\n\n\n\nimport android.view.LayoutInflater\nimport android.view.View\nimport android.view.ViewGroup\nimport android.widget.FrameLayout\nimport android.widget.ImageView\nimport android.widget.TextView\nimport androidx.cardview.widget.CardView\nimport androidx.recyclerview.widget.RecyclerView\nimport at.blogc.android.views.ExpandableTextView\nimport coil.load\n\n\n//class MyDiffUtilCallback : DiffUtil.ItemCallback<MyItem>() {\n//    override fun areItemsTheSame(oldItem: MyItem, newItem: MyItem): Boolean {\n//        // Return true if items are the same.\n//        return oldItem.id == newItem.id\n//    }\n//\n//    override fun areContentsTheSame(oldItem: MyItem, newItem: MyItem): Boolean {\n//        // Return true if contents are the same.\n//        return oldItem == newItem\n//    }\n//}\n\n\nclass EpisodeAdapter2(private val episodes : List<Episode>,\n                      private val clickHandler : (Episode) -> Unit\n) : RecyclerView.Adapter<EpisodeAdapter2.ViewHolder>() {\n\n    class ViewHolder(itemView : View) : RecyclerView.ViewHolder(itemView){\n        val episodeText : TextView = itemView.findViewById(R.id.episode_no_text)\n        val episodeImg : ImageView = itemView.findViewById(R.id.episode_img)\n        val episodeOverview : ExpandableTextView = itemView.findViewById(R.id.episode_overview_text)\n        val fl : FrameLayout = itemView.findViewById(R.id.expanded_episode_fl)\n        val epCard: CardView = itemView.findViewById(R.id.episode_card)\n        val expandText : ImageView = itemView.findViewById(R.id.expand_text)\n        val expandableTextView : ExpandableTextView = itemView.findViewById(R.id.episode_overview_text)\n        val episodeNumber : TextView = itemView.findViewById(R.id.episode_number)\n    }\n\n    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {\n       val view = LayoutInflater.from(parent.context).inflate(R.layout.test,parent,false)\n        return ViewHolder(view)\n    }\n\n    override fun onBindViewHolder(holder: ViewHolder, position: Int) {\n        val episode = episodes[position]\n        holder.episodeText.text = episode.name\n        holder.episodeNumber.text = episode.episode_number\n        holder.episodeOverview.text = episode.overview\n        holder.episodeImg.load(\"https://image.tmdb.org/t/p/w500${episode.still_path}\")\n        holder.fl.setOnClickListener {\n            clickHandler(episode)\n        }\n        holder.epCard.setOnClickListener {\n            holder.fl.performClick()\n//            clickHandler(episode)\n        }\n        val etv = holder.expandableTextView\n        etv.setAnimationDuration(750L)\n        holder.expandText.setOnClickListener {\n            if(etv.isExpanded){\n                etv.collapse()\n                holder.expandText.load(R.drawable.baseline_keyboard_arrow_down_24)\n            }else{\n                etv.expand()\n                holder.expandText.load(R.drawable.baseline_keyboard_arrow_up_24)\n            }\n        }\n\n\n\n    }\n\n    override fun getItemCount(): Int {\n        return episodes.size\n    }\n}"
  },
  {
    "path": "app/src/main/java/com/demomiru/tokeiv2/MainActivity.kt",
    "content": "package com.demomiru.tokeiv2\n\nimport android.annotation.SuppressLint\nimport android.app.AlertDialog\nimport android.content.Intent\nimport android.net.Uri\nimport android.os.Bundle\nimport android.view.KeyEvent\nimport android.view.View\nimport android.widget.TextView\nimport androidx.activity.viewModels\nimport androidx.appcompat.app.AppCompatActivity\nimport androidx.core.widget.NestedScrollView\nimport androidx.lifecycle.MutableLiveData\nimport androidx.lifecycle.Observer\nimport androidx.lifecycle.lifecycleScope\nimport androidx.navigation.NavOptions\nimport androidx.navigation.findNavController\nimport androidx.recyclerview.widget.LinearLayoutManager\nimport androidx.recyclerview.widget.RecyclerView\nimport com.demomiru.tokeiv2.utils.ContinueWatchingViewModel2\nimport com.demomiru.tokeiv2.utils.ContinueWatchingViewModelFactory2\nimport com.demomiru.tokeiv2.utils.addRecyclerAnimation\nimport com.demomiru.tokeiv2.utils.passData\nimport com.demomiru.tokeiv2.watching.ContinueWatching\nimport com.demomiru.tokeiv2.watching.ContinueWatchingAdapter\nimport com.demomiru.tokeiv2.watching.ContinueWatchingDatabase\nimport com.demomiru.tokeiv2.watching.ContinueWatchingRepository\nimport com.google.android.material.bottomnavigation.BottomNavigationView\nimport com.google.common.primitives.UnsignedBytes.toInt\nimport com.google.gson.Gson\nimport com.lagradost.nicehttp.Requests\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.launch\nimport kotlinx.coroutines.withContext\nimport okhttp3.OkHttpClient\nimport okhttp3.Request\nimport org.json.JSONArray\nimport org.jsoup.Jsoup\n\n\n@Suppress(\"DEPRECATION\")\nclass MainActivity : AppCompatActivity() {\n    private val version = 114\n    private val gson = Gson()\n    private lateinit var watchHistoryRc : RecyclerView\n    private val database by lazy { ContinueWatchingDatabase.getInstance(this) }\n    private val watchHistoryDao by lazy { database.watchDao() }\n    private val app = Requests()\n    private lateinit var viewModelFactory: ContinueWatchingViewModelFactory2\n    private val viewModel: ContinueWatchingViewModel2 by viewModels(\n        factoryProducer = {\n            viewModelFactory\n        }\n    )\n    private var currentFragment = MutableLiveData(R.id.moviesFragment)\n    private lateinit var continueText: TextView\n    private lateinit var bottomNavigationView : BottomNavigationView\n\n    private var nestedScrollView : NestedScrollView? = null\n    private lateinit var adapter: ContinueWatchingAdapter\n    private lateinit var continueWatchingRepository: ContinueWatchingRepository\n    override fun onCreate(savedInstanceState: Bundle?) {\n        super.onCreate(savedInstanceState)\n        setContentView(R.layout.activity_main)\n\n        viewModelFactory = ContinueWatchingViewModelFactory2(watchHistoryDao)\n        val options = NavOptions.Builder()\n            .setEnterAnim(R.anim.enter_from_bottom)\n            .setExitAnim(R.anim.exit_to_top)\n            .build()\n\n        nestedScrollView = findViewById(R.id.nestedScrollView)\n        val navController = findNavController(R.id.nav_host_fragment)\n        bottomNavigationView = findViewById(R.id.bottom_nav_bar)\n        continueWatchingRepository = ContinueWatchingRepository(watchHistoryDao)\n        watchHistoryRc = findViewById(R.id.watch_history_rc)\n        watchHistoryRc.layoutManager = LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL,false)\n        continueText = findViewById(R.id.continue_watching_text)\n\n\n\n\n\n\n        adapter = ContinueWatchingAdapter{it,delete->\n            if(delete){\n                lifecycleScope.launch  (Dispatchers.IO) {\n                    continueWatchingRepository.delete(it)\n//                    continueWatchingRepository.loadData()\n                }\n            }\n            else {\n                startActivity(passData(it, this))\n            }\n\n        }\n\n\n        watchHistoryRc.adapter = adapter\n       bottomNavigationView.setOnNavigationItemSelectedListener { item ->\n            when (item.itemId) {\n                R.id.moviesFragment -> {\n                    navController.navigate(R.id.moviesFragment, null, options)\n                    if (viewModel.allWatchHistory.value?.size !=0){\n                        watchHistoryRc.visibility = View.VISIBLE\n                        continueText.visibility = View.VISIBLE\n                        currentFragment.value = R.id.moviesFragment\n                    }\n\n                }\n                R.id.searchFragment -> {\n                    navController.navigate(R.id.searchFragment, null, options)\n                    watchHistoryRc.visibility = View.GONE\n                    continueText.visibility = View.GONE\n                    currentFragment.value = R.id.searchFragment\n                }\n                R.id.TVShowFragment -> {\n                    navController.navigate(R.id.TVShowFragment, null, options)\n                    if (viewModel.allWatchHistory.value?.size !=0){\n                        watchHistoryRc.visibility = View.VISIBLE\n                        continueText.visibility = View.VISIBLE\n                        currentFragment.value = R.id.TVShowFragment\n                    }\n\n                }\n                R.id.animeFragment ->{\n                    navController.navigate(R.id.animeFragment,null,options)\n                    if (viewModel.allWatchHistory.value?.size !=0){\n                        watchHistoryRc.visibility = View.VISIBLE\n                        continueText.visibility = View.VISIBLE\n                        currentFragment.value = R.id.animeFragment\n                    }\n                }\n            }\n            true\n        }\n        bottomNavigationView.setOnNavigationItemReselectedListener {\n            return@setOnNavigationItemReselectedListener\n        }\n//        bottomNavigationView.selectedItemId = R.id.animeFragment\n\n        lifecycleScope.launch (Dispatchers.IO){\n//            val update = app.get(\"https://github.com/Sovan22/Tokeii/\").document.select(\"article.markdown-body.entry-content.container-lg .anchor\")[2].attr(\"href\").substringAfter(\"v\").toInt()\n            val client = OkHttpClient()\n            val request = Request.Builder()\n                .url(\"https://api.github.com/repos/Sovan22/Tokeii/releases\").build()\n            val response = client.newCall(request).execute()\n            if (response.isSuccessful) {\n                val releases = JSONArray(response.body.string())\n                val update = gson.fromJson(releases.getJSONObject(0).toString(),Release::class.java).tag_name.replace(\".\",\"\").replace(\"v\",\"\").replace(\"-tokei\",\"\").toInt()\n//                [2].attr(\"href\").substringAfter(\"v\").toInt()\n                println(update)\n                if (version < update)\n                    withContext(Dispatchers.Main) {\n                        showDialog()\n                    }\n            }\n        }\n\n\n\n    }\n\n    data class Release(val tag_name:String)\n    fun triggerSearchKeyPress() {\n        val enterKeyEvent = KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_ENTER)\n        dispatchKeyEvent(enterKeyEvent)\n\n    }\n\n\n    @SuppressLint(\"SetTextI18n\")\n    override fun onResume() {\n//        viewModel.currentFragment.observe(this){\n//            if(it == R.id.searchFragment ){\n//                watchHistoryRc.visibility = View.GONE\n//                continueText.visibility = View.GONE\n//            }\n//            else{\n//                watchHistoryRc.visibility = View.VISIBLE\n//                continueText.visibility = View.VISIBLE\n//            }\n//        }\n\n//        viewModel.showContinue.observe(this){\n//            if(!it){\n//                watchHistoryRc.visibility = View.GONE\n//                continueText.visibility = View.GONE\n//            }\n//            else{\n//                watchHistoryRc.visibility = View.VISIBLE\n//                continueText.visibility = View.VISIBLE\n//            }\n//        }\n            val viewStateObserver = Observer<List<ContinueWatching>> {watchFrom ->\n            if(watchFrom.isNotEmpty()){\n                watchHistoryRc.visibility = View.VISIBLE\n                continueText.visibility = View.VISIBLE\n\n                adapter.submitList(watchFrom)\n                addRecyclerAnimation(watchHistoryRc,adapter)\n                viewModel.currentFragment.observe(this){\n\n                    if(it == R.id.searchFragment || it == R.id.TVShowDetails || it == R.id.animeDetailsFragment ){\n                        watchHistoryRc.visibility = View.GONE\n                        continueText.visibility = View.GONE\n                    }\n                    else{\n                        watchHistoryRc.visibility = View.VISIBLE\n                        continueText.visibility = View.VISIBLE\n                    }\n                }\n//                if(currentFragment.value  == R.id.searchFragment){\n//                    watchHistoryRc.visibility = View.GONE\n//                    continueText.visibility = View.GONE\n//                }else\n//                {\n//                    watchHistoryRc.visibility = View.VISIBLE\n//                    continueText.visibility = View.VISIBLE\n//                }\n            }\n            else{\n\n                watchHistoryRc.visibility = View.GONE\n                continueText.visibility = View.GONE\n            }\n\n        }\n        viewModel.allWatchHistory.observe(this,viewStateObserver)\n        viewModel.currentFragment.observe(this){\n            bottomNavigationView.selectedItemId = it\n        }\n        super.onResume()\n    }\n\n    private fun showDialog(){\n        val builder = AlertDialog.Builder(this)\n\n\n        builder.setMessage(\"There is an update available to this app\")\n            .setTitle(\"Update Found\")\n\n\n        builder.setPositiveButton(\"Download\"){ dialog, _ ->\n            // User clicked OK button\n            val url = \"https://github.com/Sovan22/Tokeii/releases/\"\n            val intent = Intent(Intent.ACTION_VIEW)\n            intent.data = Uri.parse(url)\n            startActivity(intent)\n            dialog.dismiss()\n        }\n        builder.setNegativeButton(\"Cancel\"){ _, _ ->\n            // User cancelled the dialog\n        }\n\n        val dialog = builder.create()\n        dialog.show()\n    }\n\n    override fun onBackPressed() {\n        if(viewModel.currentFragment.value == R.id.searchFragment && viewModel.searchOpen.value == true) {\n\n            viewModel.searchOpen.value = false\n\n        }\n        else\n            super.onBackPressed()\n    }\n\n}"
  },
  {
    "path": "app/src/main/java/com/demomiru/tokeiv2/Movie.kt",
    "content": "package com.demomiru.tokeiv2\n\nimport java.io.Serializable\n\n\ndata class Movie(\n    val id : String,\n    val original_language:String,\n    val production_countries:List<Prod>,\n    val title: String,\n    val poster_path : String,\n    val release_date : String\n) : Serializable\n\ndata class Prod(\n    val iso_3166_1 : String,\n    val name: String\n)\ndata class MovieArray(\n    val movieFile : ArrayList<MovieFile>\n)\n\ndata class MovieFile(\n    val file: String, //episode file\n    val title: String// language\n)\n\ndata class MovieIMDB(\n    val id: String,\n    val imdb_id : String,\n    val external_ids: ExternalIDs\n)\n\n\n\ndata class Keys(\n    val file: String,\n    val key : String\n)\n"
  },
  {
    "path": "app/src/main/java/com/demomiru/tokeiv2/MovieAdapter.kt",
    "content": "package com.demomiru.tokeiv2\n\nimport android.annotation.SuppressLint\nimport android.view.LayoutInflater\nimport android.view.View\nimport android.view.ViewGroup\nimport android.widget.ImageView\nimport android.widget.ProgressBar\nimport android.widget.TextView\nimport androidx.paging.PagingDataAdapter\nimport androidx.paging.PagingSource\nimport androidx.paging.PagingState\nimport androidx.recyclerview.widget.DiffUtil\nimport androidx.recyclerview.widget.ListAdapter\nimport androidx.recyclerview.widget.RecyclerView\nimport coil.load\nimport com.demomiru.tokeiv2.utils.retrofitBuilder\nimport com.demomiru.tokeiv2.utils.yearExtract\n\nclass MovieAdapter(private val clickHandler : (Movie) -> Unit) :\n    ListAdapter<Movie,MovieAdapter.ViewHolder>(differCallback) {\n\n    class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {\n        val imageView: ImageView = itemView.findViewById(R.id.image_view)\n        val titleTextView: TextView = itemView.findViewById(R.id.title_text_view)\n    }\n\n    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {\n        val view = LayoutInflater.from(parent.context).inflate(R.layout.item_view,parent,false)\n        return ViewHolder(view)\n    }\n\n    companion object {\n        val differCallback = object : DiffUtil.ItemCallback<Movie>() {\n            override fun areItemsTheSame(oldItem: Movie, newItem: Movie): Boolean {\n                return oldItem.id == newItem.id\n            }\n\n            override fun areContentsTheSame(oldItem: Movie, newItem: Movie): Boolean {\n                return oldItem == newItem\n            }\n        }\n    }\n\n\n\n    @SuppressLint(\"SetTextI18n\")\n    override fun onBindViewHolder(holder: ViewHolder, position: Int) {\n        val movie = getItem(position)\n        holder.titleTextView.text = movie.title + \" (${yearExtract(movie.release_date)})\"\n        holder.imageView.load(\"https://image.tmdb.org/t/p/w500${movie.poster_path}\")\n        holder.itemView.setOnClickListener {\n            clickHandler(movie)\n        }\n    }\n\n}\n\nclass MoviesPagingSource(private val list: Int): PagingSource<Int, Movie>() {\n    private val retrofit = retrofitBuilder()\n    private val movieService = retrofit.create(MovieService::class.java)\n    override suspend fun load(params: LoadParams<Int>): LoadResult<Int, Movie> {\n        return try {\n            val currentPage = params.key ?: 1\n            val response = when(list){\n                1-> movieService.getPopularMovies(BuildConfig.TMDB_API_KEY,\"en-US\",currentPage)\n                2-> movieService.getTrendingMovies(BuildConfig.TMDB_API_KEY, \"en-US\",currentPage)\n                3-> movieService.getTopRatedMovies(BuildConfig.TMDB_API_KEY,\"en-US\",currentPage)\n                else -> throw Exception(\"wrong list parameter input\")\n            }\n\n            val data = response.body()!!.results\n            val responseData = mutableListOf<Movie>()\n            responseData.addAll(data)\n\n            LoadResult.Page(\n                data = responseData,\n                prevKey = if (currentPage == 1) null else -1,\n                nextKey = currentPage.plus(1)\n            )\n        } catch (e: Exception) {\n            LoadResult.Error(e)\n        }\n\n    }\n\n\n    override fun getRefreshKey(state: PagingState<Int, Movie>): Int? {\n        return null\n    }\n\n\n}\n\nclass MovieAdapter2(\n    private val clickHandler : (Movie) -> Unit\n) :\n    PagingDataAdapter<Movie,MovieAdapter2.ViewHolder>(differCallback) {\n\n    class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {\n        val imageView: ImageView = itemView.findViewById(R.id.image_view)\n        val titleTextView: TextView = itemView.findViewById(R.id.title_text_view)\n    }\n\n    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {\n        val view = LayoutInflater.from(parent.context).inflate(R.layout.item_view,parent,false)\n        return ViewHolder(view)\n    }\n\n    companion object {\n        val differCallback = object : DiffUtil.ItemCallback<Movie>() {\n            override fun areItemsTheSame(oldItem: Movie, newItem: Movie): Boolean {\n                return oldItem.id == newItem.id\n            }\n\n            override fun areContentsTheSame(oldItem: Movie, newItem: Movie): Boolean {\n                return oldItem == newItem\n            }\n        }\n    }\n\n\n\n    @SuppressLint(\"SetTextI18n\")\n    override fun onBindViewHolder(holder: ViewHolder, position: Int) {\n        val movie = getItem(position)!!\n        holder.titleTextView.text = movie.title + \" (${yearExtract(movie.release_date)})\"\n        holder.imageView.load(\"https://image.tmdb.org/t/p/w500${movie.poster_path}\")\n        holder.itemView.setOnClickListener {\n            clickHandler(movie)\n        }\n        holder.setIsRecyclable(false)\n    }\n\n}\n"
  },
  {
    "path": "app/src/main/java/com/demomiru/tokeiv2/MoviePlayActivity.kt",
    "content": "package com.demomiru.tokeiv2\n\nimport android.annotation.SuppressLint\nimport android.content.Context\nimport android.content.res.Resources\nimport android.net.Uri\n\nimport androidx.appcompat.app.AppCompatActivity\nimport android.os.Bundle\nimport android.util.Log\nimport android.view.MotionEvent\n\nimport android.view.View\nimport android.view.ViewGroup\n\n\nimport android.webkit.WebChromeClient\n\nimport android.webkit.WebResourceRequest\nimport android.webkit.WebResourceResponse\nimport android.webkit.WebView\nimport android.webkit.WebViewClient\nimport android.widget.FrameLayout\n\nimport android.widget.ProgressBar\nimport android.widget.Toast\n\n\nimport androidx.lifecycle.MutableLiveData\nimport androidx.lifecycle.lifecycleScope\n\n\nimport androidx.media3.common.Player.*\nimport androidx.recyclerview.widget.GridLayoutManager\nimport androidx.recyclerview.widget.RecyclerView\nimport com.demomiru.tokeiv2.extractors.PrMovies\nimport com.demomiru.tokeiv2.extractors.ResultsAdapter\nimport com.demomiru.tokeiv2.extractors.SearchResponse\nimport com.demomiru.tokeiv2.utils.Extractor\nimport com.demomiru.tokeiv2.utils.GoMovies\nimport com.demomiru.tokeiv2.utils.GogoAnime\nimport com.demomiru.tokeiv2.utils.SmashyStream\nimport com.demomiru.tokeiv2.utils.SuperstreamUtils\n\nimport com.demomiru.tokeiv2.utils.getMovieImdb\nimport com.demomiru.tokeiv2.utils.getMovieLink\nimport com.demomiru.tokeiv2.utils.getTvImdb\nimport com.demomiru.tokeiv2.utils.getTvLink\n\n\nimport com.demomiru.tokeiv2.utils.passVideoData\n\n\nimport com.demomiru.tokeiv2.watching.ContinueWatching\n\nimport com.demomiru.tokeiv2.watching.VideoData\nimport com.google.gson.Gson\nimport kotlinx.coroutines.Dispatchers\n\nimport kotlinx.coroutines.launch\nimport kotlinx.coroutines.withContext\n\n\nimport kotlin.Exception\n\n\n@Suppress(\"DEPRECATION\")\nclass MoviePlayActivity : AppCompatActivity(){\n    private val gson = Gson()\n    private lateinit var webView : WebView\n    private  var fullscreenContainer: FullscreenHolder? = null\n    private var animeEp : List<GogoAnime.Episode> = listOf()\n    private var isSuper = false\n    private var superId: Int? = null\n    private var IMDBid: String? = null\n    private val superStream = SuperstreamUtils()\n    private lateinit var loading:ProgressBar\n    private lateinit var id:String\n//    private var clickedMiddle = false\n    private lateinit var resultRc : RecyclerView\n    private var animeUrl = \"\"\n    private var season: Int = 1\n    private var episode: Int = 1\n    private var origin : String = \"\"\n    private var year : String = \"\"\n    private var seekProgress : Int = 0\n    private var imgLink : String? = null\n    private lateinit var title:String\n    private var type : String? = null\n    private val videoUrl = MutableLiveData<String?>()\n    private var subUrl : MutableList<String> = mutableListOf()\n    private var source : String? = null\n\n    private val COVER_SCREEN_PARAMS = FrameLayout.LayoutParams(\n        ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)\n    private val prMovies = PrMovies()\n    private lateinit var url : String\n\n//    private val args : MoviePlayActivityArgs by navArgs()\n    @SuppressLint(\"SetJavaScriptEnabled\")\n\n\n    override fun onCreate(savedInstanceState: Bundle?) {\n        super.onCreate(savedInstanceState)\n\n        setContentView(R.layout.activity_movie_play)\n        Log.i(\"Start\", \"Time\")\n        resultRc = findViewById(R.id.results_rc)\n        val bundle = intent.extras\n        type = bundle?.getString(\"type\")\n        when (type) {\n        \"movie\" -> {\n            val data = bundle?.getSerializable(\"Data\") as? Movie\n\n            origin = data!!.original_language\n            year = data.release_date.substringBefore(\"-\")\n            if(origin == \"kn\" || origin == \"ml\" || origin == \"ta\" || origin == \"te\")\n                origin = \"hi\"\n            id = data.id\n            title = data.title\n            imgLink = data.poster_path\n        }\n        \"tvshow\" -> {\n            val data =  bundle?.getSerializable(\"Data\") as? Episode\n\n            id = bundle?.getString(\"id\")!!\n            title = bundle.getString(\"showTitle\")!!\n            imgLink = bundle.getString(\"poster\")\n\n            season = data!!.season_number.toInt()\n            episode = data.episode_number.toInt()\n\n        }\n        \"anime\" ->{\n            val data =  bundle?.getParcelable(\"Data\") as? GogoAnime.AnimeDetails\n            id = bundle?.getString(\"id\")!!\n            title = data?.title!!\n            imgLink = data.poster\n            season = 1\n            episode = bundle.getInt(\"ep\")\n            animeEp = data.episodes!!\n            animeUrl = data.episodes[episode].url\n        }\n        else -> {\n            val data = bundle?.getParcelable(\"Data\") as? ContinueWatching\n            id = data!!.tmdbID.toString()\n            title = data.title\n            imgLink = data.imgLink\n            seekProgress = data.progress\n            type = data.type\n            year = data.year ?: \"\"\n            origin = data.origin ?: \"\"\n            println(data)\n            if (type != \"movie\"){\n                season = data.season\n                episode = data.episode\n                if(type == \"anime\"){\n                    animeEp = data.animeEp!!\n                    animeUrl = data.animeEp[episode].url\n                }\n            }\n        }\n    }\n\n        loading = findViewById(R.id.loading_content)\n\n\n        webView = findViewById(R.id.web_view)\n        loading.visibility = View.VISIBLE\n\n\n        videoUrl.observe(this) { hlsUri ->\n            if (!hlsUri.isNullOrEmpty()) {\n                webView.visibility = View.GONE\n                videoUrl.removeObservers(this)\n               val intent =  passVideoData(VideoData(\n                    seekProgress,\n                    imgLink!!,\n                    id.toInt(),\n                    IMDBid,\n                    title,\n                    episode,\n                    season,\n                    type!!,\n                    hlsUri,\n                    superId,\n                   subUrl,\n                   animeEp,\n                   origin,\n                   year\n                   ),this)\n                intent.putExtra(\"origin\", origin)\n                intent.putExtra(\"superstream\",isSuper)\n                intent.putExtra(\"animeUrl\",animeUrl)\n//                println(source)\n                intent.putExtra(\"source\",source)\n                startActivity(intent)\n                finish()\n            }\n        }\n\n//            if(type == \"tvshow\"){\n//                lifecycleScope.launch {\n//                    val imdbId = getTvImdb(id)\n//                    if(imdbId.isNotBlank()){\n//                        origin = \"hi\"\n//                        IMDBid = imdbId\n//                        val link = getTvLink(imdbId,season-1,episode-1)\n//                        if(link.isNotBlank())\n//                        videoUrl.value = link\n//                        else{\n//                            withContext(Dispatchers.Main){\n//                                Toast.makeText(this@MoviePlayActivity,\"No Links Available\", Toast.LENGTH_SHORT).show()\n//                                finish()\n//                            }\n//                        }\n//                    }\n//                    else{\n//                        //Superstream add\n//                        val mainData = superStream.search(title)\n//                        superId = mainData.data.list[0].id\n//                        if (superId != null) {\n//                            isSuper = true\n//                            val tvLinks = superStream.loadLinks(false, superId!!, season, episode)\n//                            val urlMaps: MutableMap<String,String> = mutableMapOf()\n//                            tvLinks.data?.list?.forEach {\n//                                if(!it.path.isNullOrBlank()){\n//                                    println(\"${it.quality} : ${it.path}\")\n//                                    urlMaps[it.quality!!] = it.path\n//                                    if(it.quality == \"720p\") {\n//                                        val subtitle = superStream.loadSubtile(false,it.fid!!,superId!!,season,episode).data\n////\n//                                        getSub(subtitle)\n//\n//                                        return@forEach\n//                                    }\n//                                }\n//                            }\n//                            if(urlMaps.isNotEmpty())\n//                                videoUrl.value = gson.toJson(urlMaps)\n//                            if(videoUrl.value.isNullOrBlank()){\n////                                withContext(Dispatchers.Main){\n////                                    Toast.makeText(this@MoviePlayActivity, \"Not Available\",Toast.LENGTH_SHORT).show()\n////                                    finish()\n////                                }\n//                                isSuper = false\n//                                getGoMovieLink(false)\n////                                getSmashLink(false)\n//                            }\n//                        }\n//                        else{\n//                            isSuper = false\n//                            getGoMovieLink(false)\n////                            getSmashLink(false)\n//                        }\n//\n//                    }\n//                }\n//            }\n            if(type == \"tvshow\"){\n                lifecycleScope.launch (Dispatchers.IO){\n                    val imdbId = getTvImdb(id)\n                    if (imdbId.isNotBlank()) {\n                        origin = \"hi\"\n                        IMDBid = imdbId\n                    }\n                    val links = Extractor(origin).loadExtractor(title,id,year,season,episode,false)\n                    println(links)\n                    val list = prMovies.getPrMovieLink(title)\n                    withContext(Dispatchers.Main) {\n                        if (!links.videoUrl.isNullOrBlank()) {\n                            println(\"if run\")\n                            subUrl.addAll(links.subs)\n                            isSuper = links.isSuper\n                            source = links.source\n                            videoUrl.value = links.videoUrl\n\n                        } else {\n                            println(\"else run\")\n                            loading.visibility = View.GONE\n                            try {\n                                val rcAdapter = ResultsAdapter {\n                                    lifecycleScope.launch(Dispatchers.IO) {\n                                        val src = prMovies.loadLinks(it.link!!)\n                                        if (src.file.isNullOrBlank()) throw Exception(\"no video url found\")\n                                        withContext(Dispatchers.Main) {\n                                            isSuper = false\n                                            source = \"prmovies\"\n                                            videoUrl.value = src.file\n                                        }\n                                    }\n                                }\n                                val width = Resources.getSystem().displayMetrics.widthPixels\n                                val dpi = Resources.getSystem().displayMetrics.densityDpi\n                                val grid = (width*160)/(165*dpi)\n                                resultRc.apply {\n                                    layoutManager = GridLayoutManager(this@MoviePlayActivity,grid)\n                                    adapter = rcAdapter\n                                }\n                                if (list.isEmpty()) throw Exception(\"Empty search\")\n\n                                rcAdapter.submitList(list)\n                            }catch (e:Exception){\n                                Toast.makeText(\n                                    this@MoviePlayActivity,\n                                    \"No available links\",\n                                    Toast.LENGTH_SHORT\n                                ).show()\n                                finish()\n                            }\n                        }\n                    }\n                }\n            }\n            else if(type == \"movie\"){\n                println(\"Reached here\")\n//                if (origin != \"hi\") {\n                    lifecycleScope.launch(Dispatchers.IO) {\n//                        try {\n//                            val mainData = superStream.search(title)\n////                        println(mainData.data.list[0].year)\n//                            val item = mainData.data.list[0]\n//                            println(year + \" ${item.year}\")\n//                            superId =\n//                                if (item.title == title && item.year.toString() == year) item.id else null\n//                            getMovieEn()\n//                        }catch (e : Exception){\n//                            getMovieEn()\n//                        }\n                        val links = Extractor(origin).loadExtractor(title,id,year, season,episode,true)\n                        println(links)\n                        val query = title.filter {\n                            it.isLetterOrDigit() || it.isWhitespace()\n                        }\n                        val list = prMovies.getPrMovieLink(query)\n\n                        withContext(Dispatchers.Main) {\n                            if (!links.videoUrl.isNullOrBlank()) {\n                                subUrl.addAll(links.subs)\n                                isSuper = links.isSuper\n                                source = links.source\n                                videoUrl.value = links.videoUrl\n\n                            } else {\n                                println(\"else run\")\n                                println(list)\n                                loading.visibility = View.GONE\n                                try {\n                                    if (list.isEmpty()) throw Exception(\"Empty search\")\n                                    val rcAdapter = ResultsAdapter {\n                                        lifecycleScope.launch(Dispatchers.IO) {\n                                            val src = prMovies.loadLinks(it.link!!)\n                                            if (src.file.isNullOrBlank()) throw Exception(\"no video url found\")\n                                            withContext(Dispatchers.Main) {\n                                                isSuper = false\n                                                source = \"prmovies\"\n                                                videoUrl.value = src.file\n                                            }\n                                        }\n                                    }\n                                    val width = Resources.getSystem().displayMetrics.widthPixels\n                                    val dpi = Resources.getSystem().displayMetrics.densityDpi\n                                    val grid = (width*160)/(165*dpi)\n                                    resultRc.apply {\n                                        layoutManager = GridLayoutManager(this@MoviePlayActivity,grid)\n                                        adapter = rcAdapter\n                                    }\n\n\n                                    rcAdapter.submitList(list)\n                                }catch (e:Exception){\n                                    Toast.makeText(\n                                        this@MoviePlayActivity,\n                                        \"No available links\",\n                                        Toast.LENGTH_SHORT\n                                    ).show()\n                                    finish()\n                                }\n//                                Toast.makeText(\n//                                    this@MoviePlayActivity,\n//                                    \"No available links\",\n//                                    Toast.LENGTH_SHORT\n//                                ).show()\n//                                finish()\n\n                            }\n                        }\n//                        webView.loadUrl(url)\n                    }\n\n//                }\n//                else {\n//                    lifecycleScope.launch {\n//                        val imdbId = getMovieImdb(id)\n//                        IMDBid = imdbId\n//                        println(imdbId)\n//                        lifecycleScope.launch {\n//                            try {\n//                                val mainData = superStream.search(title)\n////                        println(mainData.data.list[0].year)\n//                                val item = mainData.data.list[0]\n//                                println(year + \" ${item.year}\")\n//                                superId =\n//                                    if (item.title == title && item.year.toString() == year) item.id else null\n//                                getMovieHi(imdbId)\n//                            } catch (e: Exception) {\n//                                getMovieHi(imdbId)\n//                            }\n//                        }\n// //                        videoUrl.value = getMovieLink(imdbId)\n//\n//\n//                    }\n//                }\n            }\n            else{\n                lifecycleScope.launch (Dispatchers.IO){\n                    val gogoSrc = GogoAnime()\n                    val link = gogoSrc.extractVideos(animeUrl)\n                    withContext(Dispatchers.Main){\n                        videoUrl.value = link\n                    }\n                }\n            }\n    }\n\n    private fun getPrMovie(list: List<SearchResponse>){\n\n    }\n\n    private suspend fun getGoMovieLink(isMovie: Boolean){\n        val goMovie = GoMovies()\n        val data = goMovie.search(season,episode,title,isMovie,year)\n        val vidLink = data.first\n        val subLinks = data.second\n        if(vidLink.isNullOrBlank()){\n//            Toast.makeText(this@MoviePlayActivity, \"Not Available\", Toast.LENGTH_SHORT).show()\n//            finish()\n            getSmashLink(isMovie)\n        }\n        else{\n            if (!subLinks.isNullOrEmpty())subUrl.add(subLinks)\n            videoUrl.value = vidLink\n        }\n    }\n\n    private fun getSub(subtitle: SuperstreamUtils.PrivateSubtitleData?){\n        subtitle?.list?.forEach { subList->\n            if(subList.language == \"English\"){\n                subList.subtitles.forEach { sub->\n\n                        if (subUrl.size == 3) {\n                        return\n                        }\n                        if (sub.lang == \"en\" && !sub.file_path.isNullOrBlank()) {\n                            subUrl.add(sub.file_path)\n//                            println(\"${sub.language} : ${sub.file_path}\")\n                        }\n\n\n                }\n                return\n            }\n        }\n    }\n\n    private fun getSub2(subtitle: SuperstreamUtils.PrivateSubtitleData?){\n        subtitle?.list?.forEach { subList->\n                subList.subtitles.forEach { sub->\n                    if (!sub.file_path.isNullOrBlank()) {\n                        subUrl.add(\"${subList.language} :${sub.file_path}\")\n                    }\n            }\n        }\n    }\n\n    private suspend fun getMovie()\n    {\n        if (superId != null) {\n            isSuper = true\n            val movieLinks = superStream.loadLinks(true, superId!!)\n            movieLinks.data?.list?.forEach {\n                if(!it.path.isNullOrBlank()){\n                    println(\"${it.quality} : ${it.path}\")\n                    if(it.quality == \"720p\") {\n                        val subtitle = superStream.loadSubtile(true,it.fid!!,superId!!).data\n//\n                        getSub(subtitle)\n                        videoUrl.value = it.path\n                        return\n                    }\n                }\n            }\n            if(videoUrl.value.isNullOrBlank()){\n                withContext(Dispatchers.Main){\n                    Toast.makeText(this@MoviePlayActivity, \"Not Available\",Toast.LENGTH_SHORT).show()\n                    finish()\n                }\n            }\n        }\n        else{\n            withContext(Dispatchers.Main){\n                Toast.makeText(this@MoviePlayActivity, \"Not Available\",Toast.LENGTH_SHORT).show()\n                finish()\n            }\n        }\n    }\n\n    private suspend fun getMovieHi(imdbId: String)\n    {\n        if (superId != null) {\n            isSuper = true\n            val movieLinks = superStream.loadLinks(true, superId!!)\n            val urlMaps: MutableMap<String,String> = mutableMapOf()\n            movieLinks.data?.list?.forEach {\n                if(!it.path.isNullOrBlank()){\n                    println(\"${it.quality} : ${it.path}\")\n                    urlMaps[it.quality!!] = it.path\n                    if(it.quality == \"720p\") {\n                        val subtitle = superStream.loadSubtile(true,it.fid!!,superId!!).data\n//\n                        getSub(subtitle)\n\n                        return@forEach\n                    }\n                }\n\n            }\n            if(urlMaps.isNotEmpty())\n                videoUrl.value = gson.toJson(urlMaps)\n            if(videoUrl.value.isNullOrBlank()){\n                withContext(Dispatchers.Main){\n//                    webView.loadUrl(url)\n//                    getSmashLink(true)\n                    isSuper = false\n                    val link = getMovieLink(imdbId)\n                    if (link.isBlank()) {\n                        getSmashLink(true,\"hi\")\n                    }\n                    else\n                        videoUrl.value = link\n\n                }\n            }\n        }\n        else{\n            withContext(Dispatchers.Main){\n//                webView.loadUrl(url)\n//                getSmashLink(true)\n                isSuper = false\n                val link = getMovieLink(imdbId)\n                if (link.isBlank())\n                    getSmashLink(true,\"hi\")\n                else\n                    videoUrl.value = link\n\n            }\n        }\n    }\n\n    private suspend fun getMovieEn()\n    {\n        if (superId != null) {\n            isSuper = true\n            val movieLinks = superStream.loadLinks(true, superId!!)\n            val urlMaps: MutableMap<String,String> = mutableMapOf()\n            movieLinks.data?.list?.forEach {\n                if(!it.path.isNullOrBlank()){\n                    println(\"${it.quality} : ${it.path}\")\n                    urlMaps[it.quality!!] = it.path\n                    if(it.quality == \"720p\") {\n                        val subtitle = superStream.loadSubtile(true,it.fid!!,superId!!).data\n//\n                        getSub(subtitle)\n\n                        return@forEach\n                    }\n                }\n\n            }\n            if(urlMaps.isNotEmpty())\n                videoUrl.value = gson.toJson(urlMaps)\n            if(videoUrl.value.isNullOrBlank()){\n                withContext(Dispatchers.Main){\n//                    webView.loadUrl(url)\n//                    getSmashLink(true)\n                    isSuper = false\n                    getGoMovieLink(true)\n\n                }\n            }\n        }\n        else{\n            withContext(Dispatchers.Main){\n//                webView.loadUrl(url)\n//                getSmashLink(true)\n                isSuper = false\n                getGoMovieLink(true)\n\n            }\n        }\n    }\n\n    private fun getSmashLink(isMovie:Boolean,src: String = \"en\")\n    {\n        val smashSrc = SmashyStream()\n        lifecycleScope.launch {\n            val links = smashSrc.getLink(isMovie,id, season, episode,src)\n            val vidLink = links.first\n            val subLink = links.second\n            if(vidLink.isNullOrBlank()){\n\n                if (isMovie && origin == \"hi\"){\n                    val mainData = superStream.search(title)\n                    superId = mainData.data.list[0].id\n                    getMovie()\n                }\n                else {\n                    withContext(Dispatchers.Main) {\n                        Toast.makeText(this@MoviePlayActivity, \"Not Available\", Toast.LENGTH_SHORT)\n                            .show()\n                        finish()\n                    }\n                }\n            }\n            else{\n                if (!subLink.isNullOrBlank())subUrl.add(subLink)\n                videoUrl.value = vidLink\n            }\n        }\n    }\n\n\n    override fun onSaveInstanceState(outState: Bundle) {\n        super.onSaveInstanceState(outState)\n        webView.saveState(outState)\n    }\n\n\n    override fun onWindowFocusChanged(hasFocus: Boolean) {\n        super.onWindowFocusChanged(hasFocus)\n        if (hasFocus) {\n            hideSystemUI()\n        }\n    }\n\n    private fun hideSystemUI() {\n        window.decorView.systemUiVisibility = (View.SYSTEM_UI_FLAG_IMMERSIVE\n                // Set the content to appear under the system bars so that the\n                // content doesn't resize when the system bars hide and show.\n                or View.SYSTEM_UI_FLAG_LAYOUT_STABLE\n                or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION\n                or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN\n                // Hide the nav bar and status bar\n                or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION\n                or View.SYSTEM_UI_FLAG_FULLSCREEN)\n    }\n\n}\n\n\n@Suppress(\"DEPRECATION\")\nclass FullscreenHolder(ctx: Context) : FrameLayout(ctx) {\n    init {\n        setBackgroundColor(ctx.resources.getColor(android.R.color.black))\n    }\n\n    @SuppressLint(\"ClickableViewAccessibility\")\n    override fun onTouchEvent(evt: MotionEvent): Boolean {\n        return true\n    }\n\n\n}\n\n\n"
  },
  {
    "path": "app/src/main/java/com/demomiru/tokeiv2/MovieService.kt",
    "content": "package com.demomiru.tokeiv2\n\nimport retrofit2.Response\nimport retrofit2.http.GET\n\n\nimport retrofit2.http.Query\n\ninterface MovieService {\n    @GET(\"movie/popular\")\n    suspend fun getPopularMovies(\n        @Query(\"api_key\") apiKey: String,\n        @Query(\"language\") language: String,\n        @Query(\"page\") page: Int\n    ): Response<MovieResponse>\n\n    @GET(\"trending/movie/day\")\n    suspend fun getTrendingMovies(\n        @Query(\"api_key\") apiKey: String,\n        @Query(\"language\") language: String,\n        @Query(\"page\") page: Int\n    ): Response<MovieResponse>\n\n\n    @GET(\"search/movie\")\n    suspend fun searchMovie(\n        @Query(\"query\") query: String,\n        @Query(\"api_key\") apiKey: String,\n        @Query(\"language\") language: String\n    ) : Response<MovieResponse>\n\n//    @GET(\"movie/{movie_id}\")\n//    suspend fun getImdbId(\n//        @Path(\"movie_id\") movie_id : String,\n//        @Query(\"api_key\") apiKey: String,\n//        @Query(\"language\") language: String\n//    ) : Response<IdDB>\n\n//    @GET(\"scrape\") // Replace with the actual endpoint path\n//    fun fetchDataFromServer(\n//        @Header(\"ngrok-skip-browser-warning\") value: String\n//    ): Response<ServerResponse>\n\n    @GET(\"movie/top_rated\")\n    suspend fun getTopRatedMovies(\n        @Query(\"api_key\") apiKey: String,\n        @Query(\"language\") language: String,\n        @Query(\"page\") page: Int\n    ) : Response<MovieResponse>\n\n\n\n}\n//data class IdDB(\n//    val id: String,\n//    val imdb_id: String\n//)\n\ndata class MovieResponse(\n        val results: List<Movie>\n        )\n//data class ServerResponse(\n//    val videoLink: String\n//    )\n\n\n\n"
  },
  {
    "path": "app/src/main/java/com/demomiru/tokeiv2/MoviesFragment.kt",
    "content": "package com.demomiru.tokeiv2\n\n\n\nimport android.os.Bundle\nimport androidx.fragment.app.Fragment\nimport android.view.LayoutInflater\nimport android.view.View\nimport android.view.ViewGroup\nimport android.widget.ProgressBar\nimport android.widget.TextView\nimport android.widget.Toast\nimport androidx.core.view.isVisible\nimport androidx.fragment.app.activityViewModels\nimport androidx.lifecycle.MutableLiveData\nimport androidx.lifecycle.lifecycleScope\nimport androidx.paging.CombinedLoadStates\nimport androidx.paging.LoadState\nimport androidx.paging.Pager\nimport androidx.paging.PagingConfig\nimport androidx.paging.cachedIn\n\nimport androidx.recyclerview.widget.LinearLayoutManager\nimport androidx.recyclerview.widget.RecyclerView\nimport com.demomiru.tokeiv2.utils.ContinueWatchingViewModel2\nimport com.demomiru.tokeiv2.utils.addRecyclerAnimation\nimport com.demomiru.tokeiv2.utils.passData\n\nimport com.demomiru.tokeiv2.utils.retrofitBuilder\nimport kotlinx.coroutines.DelicateCoroutinesApi\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.GlobalScope\nimport kotlinx.coroutines.flow.collect\nimport kotlinx.coroutines.launch\nimport kotlinx.coroutines.withContext\n\n// TODO: Rename parameter arguments, choose names that match\n// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER\nprivate const val ARG_PARAM1 = \"param1\"\nprivate const val ARG_PARAM2 = \"param2\"\n\n/**\n * A simple [Fragment] subclass.\n * Use the [MoviesFragment.newInstance] factory method to\n * create an instance of this fragment.\n */\nclass MoviesFragment : Fragment() {\n    // TODO: Rename and change types of parameters\n    private var param1: String? = null\n    private val activityViewModel: ContinueWatchingViewModel2 by activityViewModels()\n    private lateinit var popMovieRc: RecyclerView\n    private lateinit var trenMovieRc : RecyclerView\n    private lateinit var topMovieRc : RecyclerView\n    private var loading = MutableLiveData(true)\n    private val adapter = MovieAdapter2{\n        println(it.release_date)\n        startActivity(passData(it,requireContext()))\n    }\n    private var param2: String? = null\n\n    override fun onCreate(savedInstanceState: Bundle?) {\n        super.onCreate(savedInstanceState)\n        arguments?.let {\n            param1 = it.getString(ARG_PARAM1)\n            param2 = it.getString(ARG_PARAM2)\n        }\n    }\n\n    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {\n        lifecycleScope.launch (Dispatchers.IO){\n\n        }\n        super.onViewCreated(view, savedInstanceState)\n    }\n\n    @DelicateCoroutinesApi\n    override fun onCreateView(\n        inflater: LayoutInflater, container: ViewGroup?,\n        savedInstanceState: Bundle?\n    ): View? {\n        // Inflate the layout for this fragment\n        val view =  inflater.inflate(R.layout.fragment_movies, container, false)\n        popMovieRc = view.findViewById(R.id.movie_recycler_view)\n        trenMovieRc = view.findViewById(R.id.trending_movie_rc)\n        topMovieRc = view.findViewById(R.id.topRatedMovie_recycler_view)\n\n\n        topMovieRc.layoutManager = LinearLayoutManager(requireContext(), LinearLayoutManager.HORIZONTAL,false)\n        trenMovieRc.layoutManager = LinearLayoutManager(requireContext(), LinearLayoutManager.HORIZONTAL,false)\n        popMovieRc.layoutManager = LinearLayoutManager(requireContext(), LinearLayoutManager.HORIZONTAL,false)\n\n        val retrofit = retrofitBuilder()\n        val movieService = retrofit.create(MovieService::class.java)\n\n        lifecycleScope.launch(Dispatchers.Main) {\n            withContext(Dispatchers.IO){\n\n//                val trmovies =   Pager(PagingConfig(1)){MoviesPagingSource(3)}.flow.cachedIn(lifecycleScope)\n                val tradapter = MovieAdapter2{\n//                    val action = MoviesFragmentDirections.actionMoviesFragmentToMoviePlayActivity(it.id, \"movie\")\n//                    findNavController().navigate(play(it))\n                    println(it.release_date)\n                    startActivity(passData(it, requireContext()))\n\n                }\n\n//                val tmovies =  Pager(PagingConfig(1)){MoviesPagingSource(2)}.flow.cachedIn(lifecycleScope)\n                val tadapter = MovieAdapter2 {\n//                    findNavController().navigate(play(it))\n                    println(it.release_date)\n                    startActivity(passData(it, requireContext()))\n\n                }\n\n//                val movies = Pager(PagingConfig(1)){MoviesPagingSource(1)}.flow.cachedIn(lifecycleScope)\n                val adapter = MovieAdapter2 {\n                    println(it.release_date)\n                    startActivity(passData(it, requireContext()))\n\n                }\n                withContext(Dispatchers.Main) {\n                    addRecyclerAnimation(topMovieRc, tradapter)\n                    addRecyclerAnimation(trenMovieRc, tadapter)\n                    addRecyclerAnimation(popMovieRc, adapter)\n\n\n                    lifecycleScope.launch {\n                        activityViewModel.topMovies.collect {\n                            tradapter.submitData(it)\n                        }\n                    }\n                    lifecycleScope.launch {\n                        activityViewModel.popMovies.collect{\n                            adapter.submitData(it)\n                        }\n                    }\n                    lifecycleScope.launch {\n                        tadapter.addLoadStateListener {\n                            val state = it.refresh\n                            val visible = state is LoadState.Loading\n                            if(visible){\n                                view.findViewById<ProgressBar>(R.id.loading_movies).visibility = View.VISIBLE\n                            }\n                            else{\n                                view.findViewById<TextView>(R.id.trending_text).visibility = View.VISIBLE\n                                view.findViewById<TextView>(R.id.movies_text).visibility = View.VISIBLE\n                                view.findViewById<TextView>(R.id.topmovies_text).visibility = View.VISIBLE\n                                view.findViewById<ProgressBar>(R.id.loading_movies).visibility = View.GONE\n                            }\n                        }\n//                        view.findViewById<ProgressBar>(R.id.loading_movies).visibility = View.GONE\n//                        view.findViewById<TextView>(R.id.trending_text).visibility = View.VISIBLE\n//                        view.findViewById<TextView>(R.id.movies_text).visibility = View.VISIBLE\n//                        view.findViewById<TextView>(R.id.topmovies_text).visibility = View.VISIBLE\n                        activityViewModel.trenMovies.collect {\n                            tadapter.submitData(it)\n                        }\n                    }\n\n\n                }\n//\n\n        }\n\n//            withContext(Dispatchers.Main) {\n\n//                view.findViewById<ProgressBar>(R.id.loading_movies).visibility = View.GONE\n//                view.findViewById<TextView>(R.id.trending_text).visibility = View.VISIBLE\n//                view.findViewById<TextView>(R.id.movies_text).visibility = View.VISIBLE\n//                view.findViewById<TextView>(R.id.topmovies_text).visibility = View.VISIBLE\n//            }\n        }\n\n\n        return view\n    }\n\n//    private inline fun CombinedLoadStates.decideOnState(\n//        showLoading: (Boolean) -> Unit,\n//        showEmptyState: (Boolean) -> Unit,\n//        showError: (String) -> Unit\n//    ) {\n//        showLoading(refresh is LoadState.Loading)\n//\n//        showEmptyState(\n//            source.append is LoadState.NotLoading\n//                    && source.append.endOfPaginationReached\n//                    && adapter.itemCount == 0\n//        )\n//\n//        val errorState = source.append as? LoadState.Error\n//            ?: source.prepend as? LoadState.Error\n//            ?: source.refresh as? LoadState.Error\n//            ?: append as? LoadState.Error\n//            ?: prepend as? LoadState.Error\n//            ?: refresh as? LoadState.Error\n//\n//        errorState?.let { showError(it.error.toString()) }\n//    }\n\n    override fun onResume() {\n        activityViewModel.currentFragment.value = R.id.moviesFragment\n        super.onResume()\n    }\n    companion object {\n        /**\n         * Use this factory method to create a new instance of\n         * this fragment using the provided parameters.\n         *\n         * @param param1 Parameter 1.\n         * @param param2 Parameter 2.\n         * @return A new instance of fragment MoviesFragment.\n         */\n        // TODO: Rename and change types and number of parameters\n        @JvmStatic\n        fun newInstance(param1: String, param2: String) =\n            MoviesFragment().apply {\n                arguments = Bundle().apply {\n                    putString(ARG_PARAM1, param1)\n                    putString(ARG_PARAM2, param2)\n                }\n            }\n    }\n\n}\n"
  },
  {
    "path": "app/src/main/java/com/demomiru/tokeiv2/SearchFragment.kt",
    "content": "@file:OptIn(DelicateCoroutinesApi::class)\n\npackage com.demomiru.tokeiv2\n\n\nimport android.content.Context\nimport android.content.res.Resources\nimport android.os.Bundle\nimport android.view.LayoutInflater\nimport android.view.View\nimport android.view.ViewGroup\nimport android.view.inputmethod.InputMethodManager\nimport android.widget.EditText\nimport android.widget.LinearLayout\nimport android.widget.ProgressBar\nimport android.widget.RadioButton\nimport android.widget.RadioGroup\nimport android.widget.SearchView\nimport android.widget.TextView\nimport android.widget.Toast\nimport androidx.fragment.app.Fragment\nimport androidx.fragment.app.activityViewModels\nimport androidx.fragment.app.viewModels\nimport androidx.lifecycle.Observer\nimport androidx.navigation.fragment.findNavController\nimport androidx.recyclerview.widget.GridLayoutManager\nimport androidx.recyclerview.widget.LinearLayoutManager\nimport androidx.recyclerview.widget.RecyclerView\nimport com.demomiru.tokeiv2.anime.AnimeAdapter\nimport com.demomiru.tokeiv2.history.QueryRepository\nimport com.demomiru.tokeiv2.history.SearchDatabase\nimport com.demomiru.tokeiv2.history.SearchHistory\nimport com.demomiru.tokeiv2.history.SearchHistoryAdapter2\nimport com.demomiru.tokeiv2.utils.ContinueWatchingViewModel2\nimport com.demomiru.tokeiv2.utils.SearchVMFactory\nimport com.demomiru.tokeiv2.utils.SearchViewModel\nimport com.demomiru.tokeiv2.utils.addRecyclerAnimation\nimport com.demomiru.tokeiv2.utils.passData\nimport kotlinx.coroutines.DelicateCoroutinesApi\n\nclass SearchFragment : Fragment() {\n    //    private lateinit var searchHistoryList: List<String>\n    private lateinit var searchHistoryRC: RecyclerView\n    private lateinit var searchView : SearchView\n    private val activityViewModel: ContinueWatchingViewModel2 by activityViewModels()\n    private lateinit var searchHistoryFl : LinearLayout\n    private lateinit var deleteAll : TextView\n    private var isClicked = true\n    private lateinit var adapter: SearchHistoryAdapter2\n    private lateinit var searchResultsRc : RecyclerView\n    private lateinit var searchEt: EditText\n    private lateinit var movieChoice : RadioButton\n    private lateinit var tvChoice : RadioButton\n    private lateinit var animeChoice: RadioButton\n    private lateinit var choice : RadioGroup\n    private lateinit var searchLoading : ProgressBar\n    private val database by lazy { SearchDatabase.getInstance(requireContext()) }\n    private val searchHistoryDao by lazy { database.searchDao() }\n    private lateinit var queryRepository:QueryRepository\n    private lateinit var viewModelFactory: SearchVMFactory\n    private lateinit var mAdapter : MovieAdapter\n    private lateinit var tvAdapter : TVShowAdapter\n    private lateinit var aAdapter: AnimeAdapter\n    private val viewModel: SearchViewModel by viewModels(\n        factoryProducer = {\n            viewModelFactory\n        }\n    )\n\n\n\n    override fun onCreateView(\n        inflater: LayoutInflater, container: ViewGroup?,\n        savedInstanceState: Bundle?\n    ): View? {\n        // Inflate the layout for this fragment\n        val view =  inflater.inflate(R.layout.fragment_search, container, false)\n        searchHistoryFl = view.findViewById(R.id.search_history_ll)\n        searchView = view.findViewById(R.id.searchView)\n        queryRepository = QueryRepository(searchHistoryDao)\n        viewModelFactory = SearchVMFactory(queryRepository)\n        deleteAll = view.findViewById(R.id.delete_all_button)\n        searchHistoryRC = view.findViewById(R.id.search_history_rc)\n        searchResultsRc = view.findViewById(R.id.search_results_rc)\n        searchLoading = view.findViewById(R.id.search_loading)\n        movieChoice = view.findViewById(R.id.movies_search)\n        tvChoice = view.findViewById(R.id.tvShows_search)\n        animeChoice = view.findViewById(R.id.anime_search)\n        choice = view.findViewById(R.id.choice)\n        activityViewModel.currentFragment.value = R.id.searchFragment\n//        println(activityViewModel.test)\n        mAdapter = MovieAdapter{\n//                    val action = SearchFragmentDirections.actionSearchFragmentToMoviePlayActivity(it.id,\"movie\",title = it.title)\n//                    findNavController().navigate(action)\n            startActivity(passData(it, requireContext()))\n        }\n\n        tvAdapter = TVShowAdapter{it, _ ->\n            val action = SearchFragmentDirections.actionSearchFragmentToTVShowDetails(it.id, title = it.name)\n            findNavController().navigate(action)\n        }\n\n        aAdapter = AnimeAdapter(requireContext()){\n\n//                val action = SearchFragmentDirections.actionSearchFragmentToTVShowDetails(\n//                    encodeStringToInt(it.name).toString(), title = \"\",animeUrl = it.url)\n//                findNavController().navigate(action)\n            val action =  SearchFragmentDirections.actionSearchFragmentToAnimeDetailsFragment(it.name,it.url)\n            findNavController().navigate(action)\n\n        }\n\n//        var start = true\n//        viewModel.queryText.observe(viewLifecycleOwner){\n//            if(it.isNotBlank() && start)searchView.setQuery(it,false)\n//        }\n\n//        searchView.setQuery(viewModel.queryText.value,false)\n\n\n\n        val width = Resources.getSystem().displayMetrics.widthPixels\n        val dpi = Resources.getSystem().displayMetrics.densityDpi\n        val grid = (width*160)/(165*dpi)\n        println(grid)\n        searchResultsRc.layoutManager = GridLayoutManager(requireContext(),grid)\n        searchHistoryRC.layoutManager = LinearLayoutManager(requireContext())\n//        start   = false\n        adapter = SearchHistoryAdapter2{it,search->\n            if (search){\n\n                searchView.setQuery(it.query,true)\n                viewModel.queryText.value = it.query\n                viewModel.searchClicked.value = true\n//                (activity as MainActivity).triggerSearchKeyPress()\n            }\n            else {\n                viewModel.deleteRecord(it)\n            }\n        }\n        searchHistoryRC.adapter = adapter\n        searchHistoryRC.visibility = View.VISIBLE\n//        GlobalScope.launch (Dispatchers.IO){\n//            queryRepository.loadData()\n//        }\n\n        val searchHistoryObserver = Observer<List<SearchHistory>>{\n            adapter.submitList(it)\n            if (it.isEmpty()){\n//                searchHistoryRC.visibility = View.GONE\n//                deleteAll.visibility = View.GONE\n                searchHistoryFl.visibility = View.GONE\n                activityViewModel.searchOpen.value = false\n                isClicked = true\n            }\n\n        }\n        viewModel.searchClicked.observe(viewLifecycleOwner){\n            if(it){\n//                deleteAll.visibility = View.GONE\n//                searchHistoryRC.visibility = View.GONE\n                searchHistoryFl.visibility = View.GONE\n                activityViewModel.searchOpen.value = false\n            }\n            else{\n//                deleteAll.visibility = View.VISIBLE\n//                searchHistoryRC.visibility = View.VISIBLE\n                searchHistoryFl.visibility = View.VISIBLE\n                activityViewModel.searchOpen.value = true\n            }\n        }\n\n//        queryRepository.allQueries.observe(viewLifecycleOwner,searchHistoryObserver)\n        viewModel.queries.observe(viewLifecycleOwner,searchHistoryObserver)\n\n\n        deleteAll.setOnClickListener{\n            viewModel.deleteAll()\n        }\n\n        searchEt = view.findViewById(R.id.search_et)\n        searchEt.setOnClickListener{\n            if(isClicked) {\n                deleteAll.visibility = View.VISIBLE\n                searchHistoryRC.visibility = View.VISIBLE\n                isClicked = false\n            }\n            else{\n                deleteAll.visibility = View.GONE\n                searchHistoryRC.visibility = View.GONE\n                isClicked = true\n            }\n\n        }\n//        searchView.queryHint = \"Search\"\n\n//        searchView.setOnCloseListener {\n//            deleteAll.visibility = View.GONE\n//            searchHistoryRC.visibility = View.GONE\n//            false\n//        }\n        searchView.setOnClickListener {\n            val imm =\n                requireActivity().getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager\n            imm.showSoftInput(it.findFocus(), 0)\n        }\n\n//        viewModel.queryText.observe(viewLifecycleOwner){\n//            if(it.isNotBlank())searchView.setQuery(it,false)\n//        }\n\n        searchView.setOnQueryTextFocusChangeListener { view, hasFocus ->\n            if(hasFocus) {\n//                deleteAll.visibility = View.VISIBLE\n//                searchHistoryRC.visibility = View.VISIBLE\n                view.postDelayed({\n                    val imm =\n                        requireActivity().getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager\n                    imm.showSoftInput(view.findFocus(), 0)\n                }, 200)\n                searchHistoryFl.visibility = View.VISIBLE\n                activityViewModel.searchOpen.value = true\n\n            }\n//            else{\n//\n//                deleteAll.visibility = View.GONE\n//                viewModel.searchClicked.value = true\n//                searchHistoryRC.visibility = View.GONE\n//\n//            }\n        }\n\n        activityViewModel.searchOpen.observe(viewLifecycleOwner){\n            if(it == false){\n                searchHistoryFl.visibility = View.GONE\n                searchView.clearFocus()\n            }\n        }\n\n        searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener {\n            override fun onQueryTextSubmit(query: String?): Boolean {\n                // Logic for when search button is clicked\n                if(query.isNullOrEmpty())return false\n                viewModel.searchClicked.value = true\n                if(movieChoice.isChecked)\n                {\n                    viewModel.choice.value = 1\n                    performMovieSearch(query)\n                }\n                else if(tvChoice.isChecked){\n                    viewModel.choice.value = 2\n                    performShowSearch(query)\n                }\n                else{\n                    viewModel.choice.value = 3\n                    performAnimeSearch(query)\n                }\n//                searchView.isIconified = true\n//                searchView.queryHint = query\n                viewModel.queryText.value = query\n                searchHistoryFl.visibility = View.GONE\n\n                searchView.clearFocus()\n\n                return false\n            }\n\n            override fun onQueryTextChange(newText: String?): Boolean {\n                // Logic for when text in search view changes\n                //add filter in searchHistory Rc\n//                deleteAll.visibility = View.VISIBLE\n//                searchHistoryRC.visibility = View.VISIBLE\n                searchHistoryFl.visibility = View.VISIBLE\n                viewModel.queryText.value = newText?:\"\"\n                return false\n            }\n        })\n\n//        searchView.setOnClickListener {\n//            searchView.isIconified = false\n//        }\n\n//        searchEt.setOnKeyListener { _, actionId, event ->\n//            if(searchEt.text.toString().isEmpty()) return@setOnKeyListener true\n//            if (actionId == KeyEvent.ACTION_DOWN || event.keyCode == KeyEvent.KEYCODE_ENTER) {\n//                // The \"Search\" button on the keyboard was clicked\n//                viewModel.searchClicked.value = true\n//                if(movieChoice.isChecked)\n//                {\n//                    viewModel.choice.value = 1\n//                    performMovieSearch()\n//                }\n//                else if(tvChoice.isChecked){\n//                    viewModel.choice.value = 2\n//                    performShowSearch()\n//                }\n//                else{\n//                    viewModel.choice.value = 3\n//                    performAnimeSearch()\n//                }\n//                return@setOnKeyListener true\n//            }\n//            false\n//        }\n\n        choice.setOnCheckedChangeListener { _, _: Int ->\n            if(movieChoice.isChecked)\n            {\n                viewModel.choice.value = 1\n\n            }\n            else if(tvChoice.isChecked){\n                viewModel.choice.value = 2\n\n            }\n            else{\n                viewModel.choice.value = 3\n            }\n            searchResultsRc.visibility = View.GONE\n//            searchHistoryRC.visibility = View.VISIBLE\n            searchHistoryFl.visibility = View.VISIBLE\n            viewModel.searchClicked.value = false\n        }\n\n        when(viewModel.choice.value){\n            1 -> viewModel.movieList.observe(viewLifecycleOwner) { movies ->\n                if (movies.isNotEmpty()) {\n                    mAdapter.submitList(movies)\n                    addRecyclerAnimation(searchResultsRc,mAdapter)\n                    searchLoading.visibility = View.GONE\n                    searchResultsRc.visibility = View.VISIBLE\n                }\n            }\n            2 -> viewModel.tvList.observe(viewLifecycleOwner){shows->\n                if(shows.isNotEmpty()){\n                    tvAdapter.submitList(shows)\n                    addRecyclerAnimation(searchResultsRc,tvAdapter)\n                    searchLoading.visibility = View.GONE\n                    searchResultsRc.visibility = View.VISIBLE\n                }\n            }\n            3 -> viewModel.animeList.observe(viewLifecycleOwner){ anime->\n                if(anime.isNotEmpty()){\n                    aAdapter.submitList(anime)\n                    addRecyclerAnimation(searchResultsRc,aAdapter)\n                    searchLoading.visibility = View.GONE\n                    searchResultsRc.visibility = View.VISIBLE\n                }\n            }\n            else -> println(viewModel.choice.value)\n        }\n\n        viewModel.noMatches.observe(viewLifecycleOwner){\n            if(it) {\n                Toast.makeText(requireContext(), \"No Matches\", Toast.LENGTH_SHORT).show()\n                viewModel.noMatches.value = false\n            }\n        }\n\n        return view\n    }\n\n\n    private fun performAnimeSearch(query: String)\n    {\n        searchResultsRc.visibility = View.GONE\n        searchHistoryFl.visibility = View.GONE\n        isClicked = true\n//        deleteAll.visibility = View.GONE\n        searchLoading.visibility = View.VISIBLE\n//        val gogoSrc = GogoAnime()\n\n//        val query = searchEt.text.toString()\n        val history = SearchHistory(query = query)\n        viewModel.addToHistory(history)\n        viewModel.searchAnime(query)\n//        val adapter = AnimeAdapter(requireContext()){\n//            lifecycleScope.launch {\n//\n////                val action = SearchFragmentDirections.actionSearchFragmentToTVShowDetails(\n////                    encodeStringToInt(it.name).toString(), title = \"\",animeUrl = it.url)\n////                findNavController().navigate(action)\n//\n//               val action =  SearchFragmentDirections.actionSearchFragmentToAnimeDetailsFragment(it.name,it.url)\n//                findNavController().navigate(action)\n//\n//            }\n//        }\n\n\n\n\n\n        viewModel.animeList.observe(viewLifecycleOwner){anime->\n            if(anime.isNotEmpty()){\n                aAdapter.submitList(anime)\n                addRecyclerAnimation(searchResultsRc, aAdapter)\n                searchLoading.visibility = View.GONE\n                searchResultsRc.visibility = View.VISIBLE\n                searchResultsRc.requestFocus()\n            }\n            else{\n//                Toast.makeText(requireContext(),\"No Matches\",Toast.LENGTH_SHORT).show()\n                searchLoading.visibility = View.GONE\n                searchResultsRc.visibility = View.GONE\n            }\n        }\n//        addRecyclerAnimation(searchResultsRc, aAdapter)\n//        lifecycleScope.launch(Dispatchers.IO) {\n//            val history = SearchHistory(query = query)\n//            queryRepository.insert(history)\n//            queryRepository.loadData()\n//            val animeList = gogoSrc.search(query)\n//\n//            withContext(Dispatchers.Main)\n//            {\n//                if (animeList.isEmpty()) Toast.makeText(requireContext(),\"No Matches\",Toast.LENGTH_LONG).show()\n//                adapter.submitList(animeList)\n//                searchLoading.visibility = View.GONE\n//                searchResultsRc.visibility = View.VISIBLE\n//            }\n//        }\n\n    }\n\n    @OptIn(DelicateCoroutinesApi::class)\n    private fun performMovieSearch(query:String)\n    {\n        searchResultsRc.visibility = View.GONE\n//        searchHistoryRC.visibility = View.GONE\n        isClicked = true\n//        deleteAll.visibility = View.GONE\n        searchHistoryFl.visibility = View.GONE\n        searchLoading.visibility = View.VISIBLE\n\n//        val query = searchEt.text.toString()\n\n//        GlobalScope.launch(Dispatchers.IO) {\n//\n//            val history = SearchHistory(query = query)\n//            queryRepository.insert(history)\n//            queryRepository.loadData()\n//        }\n        val history = SearchHistory(query = query)\n        viewModel.addToHistory(history)\n\n//        val retrofit = retrofitBuilder()\n//\n//        val movieService = retrofit.create(MovieService::class.java)\n\n        viewModel.searchMovie(query)\n        viewModel.movieList.observe(viewLifecycleOwner){movies->\n            if(movies.isNotEmpty()){\n                mAdapter.submitList(movies)\n                addRecyclerAnimation(searchResultsRc,mAdapter)\n                searchLoading.visibility = View.GONE\n                searchResultsRc.visibility = View.VISIBLE\n                searchResultsRc.requestFocus()\n            }\n            else{\n//                Toast.makeText(requireContext(),\"No Matches\",Toast.LENGTH_SHORT).show()\n                searchLoading.visibility = View.GONE\n                searchResultsRc.visibility = View.GONE\n            }\n        }\n\n//        GlobalScope.launch (Dispatchers.Main){\n//\n//            val searchResults = movieService.searchMovie(\n//                query,\n//                BuildConfig.TMDB_API_KEY,\n//                \"en-US\"\n//            )\n//\n//            if (searchResults.isSuccessful)\n//            {\n//                val movies = searchResults.body()?.results ?: emptyList()\n//                if (movies.isEmpty()) Toast.makeText(requireContext(),\"No Matches\",Toast.LENGTH_LONG).show()\n//                val adapter = MovieAdapter(movies){\n////                    val action = SearchFragmentDirections.actionSearchFragmentToMoviePlayActivity(it.id,\"movie\",title = it.title)\n////                    findNavController().navigate(action)\n//                    startActivity(passData(it,requireContext()))\n//                }\n//                addRecyclerAnimation(searchResultsRc,adapter)\n//            }\n//\n//            withContext(Dispatchers.Main) {\n//                searchLoading.visibility = View.GONE\n//                searchResultsRc.visibility = View.VISIBLE\n//            }\n//        }\n\n    }\n\n    @OptIn(DelicateCoroutinesApi::class)\n    private fun performShowSearch(query: String)\n    {\n        searchResultsRc.visibility = View.GONE\n//        searchHistoryRC.visibility = View.GONE\n        searchHistoryFl.visibility = View.GONE\n        isClicked = true\n        searchLoading.visibility = View.VISIBLE\n//        deleteAll.visibility = View.GONE\n\n//        val query = searchEt.text.toString()\n//        GlobalScope.launch(Dispatchers.IO) {\n////            searchHistoryDao.deleteAll()\n//            val history = SearchHistory(query = query)\n//            queryRepository.insert(history)\n//            queryRepository.loadData()\n//        }\n\n        val history = SearchHistory(query = query)\n        viewModel.addToHistory(history)\n\n        viewModel.searchTv(query)\n        viewModel.tvList.observe(viewLifecycleOwner){shows->\n            if(shows.isNotEmpty()){\n                tvAdapter.submitList(shows)\n                addRecyclerAnimation(searchResultsRc,tvAdapter)\n                searchLoading.visibility = View.GONE\n                searchResultsRc.visibility = View.VISIBLE\n                searchResultsRc.requestFocus()\n            }\n            else{\n//                Toast.makeText(requireContext(),\"No Matches\",Toast.LENGTH_SHORT).show()\n                searchLoading.visibility = View.GONE\n                searchResultsRc.visibility = View.GONE\n            }\n\n        }\n\n//        val retrofit = retrofitBuilder()\n//\n//        val tvService = retrofit.create(TMDBService::class.java)\n\n//        GlobalScope.launch (Dispatchers.Main){\n//\n//            val searchResults = tvService.searchShow(\n//                query,\n//                BuildConfig.TMDB_API_KEY,\n//                \"en-US\"\n//            )\n//\n//            if (searchResults.isSuccessful)\n//            {\n//                val tvShows = searchResults.body()?.results ?: emptyList()\n//                if (tvShows.isEmpty()) Toast.makeText(requireContext(),\"No Matches\",Toast.LENGTH_LONG).show()\n//                val adapter = TVShowAdapter(tvShows){it, _ ->\n//                    val action = SearchFragmentDirections.actionSearchFragmentToTVShowDetails(it.id, title = it.name)\n//                    findNavController().navigate(action)\n//                }\n//                addRecyclerAnimation(searchResultsRc,adapter)\n//            }\n//            withContext(Dispatchers.Main) {\n//                searchLoading.visibility = View.GONE\n//                searchResultsRc.visibility = View.VISIBLE\n//            }\n//        }\n\n    }\n\n\n\n}"
  },
  {
    "path": "app/src/main/java/com/demomiru/tokeiv2/TMDBService.kt",
    "content": "package com.demomiru.tokeiv2\n\nimport retrofit2.Response\nimport retrofit2.http.GET\nimport retrofit2.http.Path\nimport retrofit2.http.Query\nimport java.io.Serializable\n\n\ninterface TMDBService {\n\n    @GET(\"tv/popular\")\n    suspend fun getPopularTVShows(\n        @Query(\"api_key\") apiKey: String,\n        @Query(\"language\") language: String,\n        @Query(\"page\") page: Int\n    ): Response<TVShowResponse>\n\n    @GET(\"trending/tv/day\")\n    suspend fun getTrendingTVShows(\n        @Query(\"api_key\") apiKey: String,\n        @Query(\"language\") language: String,\n        @Query(\"page\") page: Int\n    ): Response<TVShowResponse>\n\n    @GET(\"tv/{series_id}\")\n    suspend fun getTVShowDetails(\n        @Path(\"series_id\") seriesID: String,\n        @Query(\"api_key\") apiKey: String,\n        @Query(\"language\") language: String\n    ): Response<TVShowDetailsResponse>\n\n    @GET(\"tv/{series_id}/season/{season_number}\")\n    suspend fun getEpisodeDetails(\n        @Path(\"series_id\") seriesID: String,\n        @Path(\"season_number\") season: String,\n        @Query(\"api_key\") apiKey: String,\n        @Query(\"language\") language: String\n    ) : Response<TVShowEpisodeDetailsResponse>\n\n    @GET(\"search/tv\")\n    suspend fun searchShow(\n        @Query(\"query\") query: String,\n        @Query(\"api_key\") apiKey: String,\n        @Query(\"language\") language: String\n    ) : Response<TVShowResponse>\n\n    @GET(\"tv/top_rated\")\n    suspend fun getTopRatedTVShows(\n        @Query(\"api_key\") apiKey: String,\n        @Query(\"language\") language: String,\n        @Query(\"page\") page: Int\n    ) : Response<TVShowResponse>\n\n\n\n}\n\ndata class TVShowResponse(\n    val results: List<TVshow>\n)\n\ndata class TVShowDetailsResponse(\n    val backdrop_path : String,\n    val overview : String,\n    val original_name : String,\n    val number_of_seasons: String,\n    val poster_path : String,\n    val number_of_episodes : Int,\n    val tagline : String\n)\n\ndata class TVShowEpisodeDetailsResponse(\n    val episodes : List<Episode>\n)\ndata class Episode(\n    val air_date: String?,\n    val season_number: String,\n    val episode_number: String,\n    val overview: String?,\n    val name: String?,\n    val still_path: String?,\n) : Serializable\n\ndata class Season(\n    val id : String,\n    val title:String,\n    val folder: List<Folder>\n)\ndata class Folder(\n    val episode: String,\n    val folder: List<EpisodeID>\n)\ndata class EpisodeID(\n    val file: String, //episode file\n    val title: String// language\n)\n\ndata class TvIMDB(\n    val languages: List<String>,\n    val external_ids : ExternalIDs,\n    val number_of_seasons: String,\n    val origin_country: List<String>\n)\ndata class ExternalIDs(\n    val imdb_id : String\n)\n\ndata class ImdbEpisode(\n    val episodes : List<EP>\n)\ndata class EP(\n    val episode_number: String\n)\n\n"
  },
  {
    "path": "app/src/main/java/com/demomiru/tokeiv2/TVShowAdapter.kt",
    "content": "package com.demomiru.tokeiv2\n\nimport android.view.LayoutInflater\nimport android.view.View\nimport android.view.ViewGroup\nimport android.widget.ImageView\nimport android.widget.TextView\nimport androidx.core.view.ViewCompat\nimport androidx.paging.PagingDataAdapter\nimport androidx.paging.PagingSource\nimport androidx.paging.PagingState\nimport androidx.recyclerview.widget.DiffUtil\nimport androidx.recyclerview.widget.ListAdapter\nimport androidx.recyclerview.widget.RecyclerView\nimport coil.load\nimport com.demomiru.tokeiv2.MovieAdapter2.Companion.differCallback\nimport com.demomiru.tokeiv2.utils.retrofitBuilder\n\nclass TVShowAdapter(\nprivate val clickHandler : (TVshow,Int) -> Unit\n) :\n    ListAdapter<TVshow,TVShowAdapter.ViewHolder>(differCallback) {\n\n    class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {\n        val imageView: ImageView = itemView.findViewById(R.id.image_view)\n        val titleTextView: TextView = itemView.findViewById(R.id.title_text_view)\n    }\n\n    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {\n        val view = LayoutInflater.from(parent.context)\n            .inflate(R.layout.item_view, parent, false)\n        return ViewHolder(view)\n    }\n\n    override fun onBindViewHolder(holder: ViewHolder, position: Int) {\n        val tvShow = getItem(position)\n        holder.titleTextView.text = tvShow.name\n        holder.imageView\n            .load(\"https://image.tmdb.org/t/p/w500${tvShow.poster_path}\")\n        ViewCompat.setTransitionName(holder.imageView, \"image_$position\")\n\n        holder.itemView.setOnClickListener {\n            clickHandler(tvShow,position)\n        }\n    }\n    companion object {\n        val differCallback = object : DiffUtil.ItemCallback<TVshow>() {\n            override fun areItemsTheSame(oldItem: TVshow, newItem: TVshow): Boolean {\n                return oldItem.id == newItem.id\n            }\n\n            override fun areContentsTheSame(oldItem: TVshow, newItem: TVshow): Boolean {\n                return oldItem == newItem\n            }\n        }\n    }\n\n}\n\nclass TvShowPagingSource(private val list: Int): PagingSource<Int, TVshow>() {\n    private val retrofit = retrofitBuilder()\n    private val tvService = retrofit.create(TMDBService::class.java)\n    override suspend fun load(params: LoadParams<Int>): LoadResult<Int, TVshow> {\n        return try {\n            val currentPage = params.key ?: 1\n            val response = when(list){\n                1-> tvService.getPopularTVShows(BuildConfig.TMDB_API_KEY,\"en-US\",currentPage)\n                2-> tvService.getTrendingTVShows(BuildConfig.TMDB_API_KEY, \"en-US\",currentPage)\n                3-> tvService.getTopRatedTVShows(BuildConfig.TMDB_API_KEY,\"en-US\",currentPage)\n                else -> throw Exception(\"wrong list parameter input\")\n            }\n\n            val data = response.body()!!.results\n            val responseData = mutableListOf<TVshow>()\n            responseData.addAll(data)\n\n            LoadResult.Page(\n                data = responseData,\n                prevKey = if (currentPage == 1) null else -1,\n                nextKey = currentPage.plus(1)\n            )\n        } catch (e: Exception) {\n            LoadResult.Error(e)\n        }\n\n    }\n\n\n    override fun getRefreshKey(state: PagingState<Int, TVshow>): Int? {\n        return null\n    }\n\n}\n\nclass TVShowAdapter2(private val clickHandler : (TVshow,Int) -> Unit) :\n    PagingDataAdapter<TVshow,TVShowAdapter2.ViewHolder>(differCallback) {\n\n    class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {\n        val imageView: ImageView = itemView.findViewById(R.id.image_view)\n        val titleTextView: TextView = itemView.findViewById(R.id.title_text_view)\n    }\n\n    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {\n        val view = LayoutInflater.from(parent.context)\n            .inflate(R.layout.item_view, parent, false)\n        return ViewHolder(view)\n    }\n\n    override fun onBindViewHolder(holder: ViewHolder, position: Int) {\n        val tvShow = getItem(position)!!\n        holder.titleTextView.text = tvShow.name\n        holder.imageView\n            .load(\"https://image.tmdb.org/t/p/w500${tvShow.poster_path}\")\n        ViewCompat.setTransitionName(holder.imageView, \"image_$position\")\n\n        holder.itemView.setOnClickListener {\n            clickHandler(tvShow,position)\n        }\n        holder.setIsRecyclable(false)\n    }\n    companion object {\n        val differCallback = object : DiffUtil.ItemCallback<TVshow>() {\n            override fun areItemsTheSame(oldItem: TVshow, newItem: TVshow): Boolean {\n                return oldItem.id == newItem.id\n            }\n\n            override fun areContentsTheSame(oldItem: TVshow, newItem: TVshow): Boolean {\n                return oldItem == newItem\n            }\n        }\n    }\n}"
  },
  {
    "path": "app/src/main/java/com/demomiru/tokeiv2/TVShowCardAdapter.kt",
    "content": "package com.demomiru.tokeiv2\n\n\nimport androidx.recyclerview.widget.RecyclerView\nimport android.view.LayoutInflater\nimport android.view.View\nimport android.view.ViewGroup\nimport android.widget.ImageView\nimport coil.load\n\n\nclass TVShowCardAdapter(private val tvShows: List<List<TVshow>>): RecyclerView.Adapter<TVShowCardAdapter.ViewHolder>() {\n\n    class ViewHolder(itemView : View) : RecyclerView.ViewHolder(itemView){\n        val verticalImage: ImageView = itemView.findViewById(R.id.vertical_container)\n        val horizontalImage1: ImageView = itemView.findViewById(R.id.horizontal_container1)\n        val horizontalImage2: ImageView = itemView.findViewById(R.id.horizontal_container2)\n    }\n\n    override fun onCreateViewHolder(\n        parent: ViewGroup,\n        viewType: Int\n    ): ViewHolder {\n        val view = LayoutInflater.from(parent.context).inflate(R.layout.card_view,parent,false)\n        return ViewHolder(view)\n    }\n\n    override fun onBindViewHolder(holder: ViewHolder, position: Int) {\n        val tvShow = tvShows[position  % tvShows.size]\n        holder.verticalImage.load(\"https://image.tmdb.org/t/p/w500${tvShow[0].poster_path}\")\n        holder.horizontalImage1.load(\"https://image.tmdb.org/t/p/original${tvShow[1].backdrop_path}\")\n        holder.horizontalImage2.load(\"https://image.tmdb.org/t/p/original${tvShow[2].backdrop_path}\")\n    }\n\n    override fun getItemCount(): Int {\n       return Int.MAX_VALUE\n    }\n}"
  },
  {
    "path": "app/src/main/java/com/demomiru/tokeiv2/TVShowDetails.kt",
    "content": "package com.demomiru.tokeiv2\n\nimport android.annotation.SuppressLint\nimport android.content.res.Configuration\n\nimport android.os.Bundle\n\nimport android.util.Log\nimport androidx.fragment.app.Fragment\nimport android.view.LayoutInflater\nimport android.view.View\nimport android.view.ViewGroup\nimport android.view.animation.AnimationUtils\nimport android.widget.AdapterView\nimport android.widget.ArrayAdapter\n\nimport android.widget.Button\nimport android.widget.ImageView\nimport android.widget.LinearLayout\nimport android.widget.ProgressBar\nimport android.widget.Spinner\nimport android.widget.TextView\nimport android.widget.Toast\nimport androidx.constraintlayout.widget.ConstraintLayout\nimport androidx.fragment.app.activityViewModels\nimport androidx.fragment.app.viewModels\nimport androidx.lifecycle.MutableLiveData\nimport androidx.lifecycle.Observer\nimport androidx.lifecycle.lifecycleScope\n\nimport androidx.navigation.fragment.navArgs\nimport androidx.recyclerview.widget.LinearLayoutManager\nimport androidx.recyclerview.widget.RecyclerView\nimport coil.load\nimport com.demomiru.tokeiv2.anime.AnimeEpisodeAdapter\nimport com.demomiru.tokeiv2.utils.ContinueWatchingViewModel\nimport com.demomiru.tokeiv2.utils.ContinueWatchingViewModel2\nimport com.demomiru.tokeiv2.utils.ContinueWatchingViewModelFactory\nimport com.demomiru.tokeiv2.utils.GogoAnime\nimport com.demomiru.tokeiv2.utils.dateToUnixTime\nimport com.demomiru.tokeiv2.utils.dropDownMenu\nimport com.demomiru.tokeiv2.utils.passData\nimport com.demomiru.tokeiv2.utils.retrofitBuilder\nimport com.demomiru.tokeiv2.watching.ContinueWatching\nimport com.demomiru.tokeiv2.watching.ContinueWatchingDatabase\n\nimport kotlinx.coroutines.DelicateCoroutinesApi\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.GlobalScope\n\nimport kotlinx.coroutines.launch\nimport kotlinx.coroutines.withContext\n\n\nclass TVShowDetails : Fragment() {\n    private val args : TVShowDetailsArgs by navArgs()\n    private val activityViewModel: ContinueWatchingViewModel2 by activityViewModels()\n    private lateinit var id: String\n    private lateinit var title: String\n    private var isAnime: Boolean = false\n    private var animeDetails = MutableLiveData<GogoAnime.AnimeDetails>(null)\n    private lateinit var viewModelFactory: ContinueWatchingViewModelFactory\n    private val viewModel: ContinueWatchingViewModel by viewModels(\n        factoryProducer = {\n            viewModelFactory\n        }\n    )\n    private var lastPlayedSeason = 1\n    private lateinit var episodeProgress : ContinueWatching\n    private val database by lazy { ContinueWatchingDatabase.getInstance(requireContext()) }\n    private val watchHistoryDao by lazy { database.watchDao() }\n    private lateinit var episodesRc: RecyclerView\n    private lateinit var progressBar: ProgressBar\n    private lateinit var dropDownSpinner: Spinner\n\n\n    @SuppressLint(\"SetTextI18n\")\n    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {\n        super.onViewCreated(view, savedInstanceState)\n        val viewStateObserver = Observer<ContinueWatching?> {watchFrom ->\n            val continueButton =  view.findViewById<Button>(R.id.continue_button)\n            if (watchFrom != null) {\n                episodeProgress = watchFrom\n                continueButton.visibility = View.VISIBLE\n               continueButton.text =\n                    \"Continue Watching \\t S${watchFrom.season} E${watchFrom.episode}\"\n                lastPlayedSeason = watchFrom.season\n            }\n\n            continueButton.setOnClickListener {\n                startActivity(passData(watchFrom!!, requireContext()))\n            }\n        }\n        viewModel.watchFrom.observe(viewLifecycleOwner,viewStateObserver)\n    }\n\n    @SuppressLint(\"NotifyDataSetChanged\", \"SetTextI18n\")\n    @OptIn(DelicateCoroutinesApi::class)\n    override fun onCreateView(\n        inflater: LayoutInflater, container: ViewGroup?,\n        savedInstanceState: Bundle?\n    ): View? {\n//        postponeEnterTransition()\n        // Inflate the layout for this fragment\n        activityViewModel.currentFragment.value = R.id.TVShowDetails\n        val view = inflater.inflate(R.layout.fragment_tv_show_details, container, false)\n//        val animeDetails = arguments?.getSerializable(\"anime-details\") as? GogoAnime.AnimeDetails\n//        if (animeDetails!= null) isAnime = true\n\n        val animeUrl: String = args.animeUrl\n        println(animeUrl)\n        isAnime = animeUrl.length > 5\n\n        if (!isAnime) {\n            id = args.tmdbID\n            viewModelFactory = ContinueWatchingViewModelFactory(watchHistoryDao, id.toInt())\n            title = args.title\n            val position = args.position\n        }\n        else\n        {\n            id=args.tmdbID\n            viewModelFactory = ContinueWatchingViewModelFactory(watchHistoryDao, id.toInt())\n            title = args.title\n            val gogoSrc = GogoAnime()\n            lifecycleScope.launch {\n                val details  = gogoSrc.load(animeUrl)\n                withContext(Dispatchers.Main){\n                    animeDetails.value = details\n                    if (animeDetails!=null){\n                        title = details.title!!\n                    }\n                    else{\n                        Toast.makeText(requireContext(),\"Error Loading\", Toast.LENGTH_SHORT).show()\n                    }\n                }\n            }\n        }\n//        val continueButton  = view.findViewById<Button>(R.id.continue_button)\n\n\n\n//        hintTil = view.findViewById(R.id.dropdown_menu)\n        progressBar = view.findViewById(R.id.progress_circular)\n        episodesRc = view.findViewById(R.id.episode_display_rc)\n        val orientation = this.resources.configuration.orientation\n        if(orientation == Configuration.ORIENTATION_LANDSCAPE)\n            episodesRc.layoutManager = LinearLayoutManager(requireContext(), LinearLayoutManager.HORIZONTAL, false)\n        else\n        episodesRc.layoutManager = LinearLayoutManager(requireContext())\n\n        val expandView = view.findViewById<ConstraintLayout>(R.id.expand_tvshow_view)\n        val titleTv = view.findViewById<TextView>(R.id.title_show)\n        val backdropImg: ImageView = view.findViewById(R.id.show_backdrop)\n        val posterImg: ImageView = view.findViewById(R.id.show_poster)\n        val overview: TextView = view.findViewById(R.id.overview)\n        val retrofit = retrofitBuilder()\n        dropDownSpinner = view.findViewById(R.id.dropdown_spinner)\n//        viewModel.season.observe(viewLifecycleOwner){\n//            dropDownSpinner.setSelection(it)\n//        }\n//        expandView.transitionName = \"image_$position\"\n\n\n        if (!isAnime){\n            println(\" NOt anime\")\n        val tvService = retrofit.create(TMDBService::class.java)\n        lifecycleScope.launch(Dispatchers.IO) {\n            val tvDetailsResponse = tvService.getTVShowDetails(\n                id,\n                BuildConfig.TMDB_API_KEY,\n                \"en-US\"\n            )\n\n            if (tvDetailsResponse.isSuccessful) {\n                val tvShows = tvDetailsResponse.body()\n\n                withContext(Dispatchers.Main){\n                    posterImg.load(\"https://image.tmdb.org/t/p/w500${tvShows?.poster_path}\")\n                    backdropImg.load(\"https://image.tmdb.org/t/p/original${tvShows?.backdrop_path}\")\n                    overview.text = tvShows?.overview\n                    titleTv.text = title\n                }\n\n\n                val seasons = dropDownMenu(tvShows!!.number_of_seasons.toInt()) // Fetch the data\n                val arrayAdapter = ArrayAdapter(\n                    requireContext(),\n                    android.R.layout.simple_dropdown_item_1line,\n                    seasons\n                ) // Create an ArrayAdapter\n//                dropdownMenu = view.findViewById(R.id.autoCompleteTextView)\n//                dropdownMenu.setAdapter(arrayAdapter) // Set the adapter\n\n                withContext(Dispatchers.Main){\n                    dropDownSpinner.adapter = arrayAdapter\n                    dropDownSpinner.setSelection(lastPlayedSeason-1)\n\n                }\n\n                var seasonNumber: String\n                dropDownSpinner.onItemSelectedListener =\n                    object : AdapterView.OnItemSelectedListener {\n                        override fun onItemSelected(\n                            parent: AdapterView<*>?,\n                            p1: View?,\n                            position: Int,\n                            p3: Long\n                        ) {\n                            val selectedItem = parent?.getItemAtPosition(position) as String\n                            seasonNumber = selectedItem.substringAfter(\" \")\n                            Log.i(\"Season Number\", seasonNumber)\n                            viewModel.season.value = position\n\n                            lifecycleScope.launch(Dispatchers.IO) {\n                                val episodeResponse = tvService.getEpisodeDetails(\n                                    id, seasonNumber,\n                                    BuildConfig.TMDB_API_KEY,\n                                    \"en-US\"\n                                )\n\n                                if (episodeResponse.isSuccessful) {\n                                    var episodes = episodeResponse.body()?.episodes ?: emptyList()\n\n                                    if(episodes.isNotEmpty()){\n                                        val condition: (Episode) -> Boolean = { episode ->\n                                            if (episode.air_date == null) true\n                                            else\n                                            dateToUnixTime(episode.air_date) > System.currentTimeMillis()\n                                        }\n                                        val repisodes =  episodes.toMutableList()\n                                        repisodes.removeIf(condition)\n                                        episodes = repisodes\n                                    }\n\n                                    val adapter = EpisodeAdapter2(episodes) {\n                                        startActivity(\n                                            passData(\n                                                it,\n                                                requireContext(),\n                                                title,\n                                                tvShows.poster_path,\n                                                id\n                                            )\n                                        )\n\n                                    }\n\n                                    val context = episodesRc.context\n                                    val controller = AnimationUtils.loadLayoutAnimation(\n                                        context,\n                                        R.anim.layout_animation\n                                    )\n                                    withContext(Dispatchers.Main) {\n                                        episodesRc.adapter = adapter\n                                        episodesRc.layoutAnimation = controller\n                                        adapter.notifyDataSetChanged()\n                                        episodesRc.scheduleLayoutAnimation()\n                                        view.findViewById<TextView>(R.id.episodes_text).visibility =\n                                            View.VISIBLE\n                                    }\n\n                                }\n                            }\n                        }\n\n                        override fun onNothingSelected(p0: AdapterView<*>?) {\n\n                        }\n\n                    }\n\n                withContext(Dispatchers.Main) {\n\n                    view.findViewById<LinearLayout>(R.id.progress_layout).visibility = View.GONE\n//                    view.findViewById<TextView>(R.id.episodes_text).visibility = View.VISIBLE\n                }\n\n            }\n        }\n    }else\n        {\n        dropDownSpinner.visibility = View.GONE\n        animeDetails.observe(viewLifecycleOwner) {animeDetails->\n            if(animeDetails!=null){\n\n                view.findViewById<LinearLayout>(R.id.progress_layout).visibility = View.GONE\n                posterImg.load(animeDetails.poster)\n                backdropImg.load(animeDetails.poster)\n                overview.text = animeDetails.description\n                titleTv.text = animeDetails.title\n\n                val episodes = animeDetails.episodes\n                val adapter = AnimeEpisodeAdapter() { _, epPos->\n                    startActivity(\n                        passData(\n                            animeDetails,\n                            requireContext(),\n                            \"0\",\n                            epPos,\n                            animeDetails.title?:\"\"\n                        )\n                    )\n                }\n                episodesRc.adapter = adapter\n                adapter.submitList(episodes)\n                val context = episodesRc.context\n                val controller = AnimationUtils.loadLayoutAnimation(\n                    context,\n                    R.anim.layout_animation\n                )\n                episodesRc.layoutAnimation = controller\n                adapter.notifyDataSetChanged()\n                episodesRc.scheduleLayoutAnimation()\n                view.findViewById<TextView>(R.id.episodes_text).visibility =\n                    View.VISIBLE\n                }\n            }\n        }\n        return view\n    }\n}"
  },
  {
    "path": "app/src/main/java/com/demomiru/tokeiv2/TVShowFragment.kt",
    "content": "package com.demomiru.tokeiv2\n\nimport android.os.Bundle\n\nimport androidx.fragment.app.Fragment\nimport android.view.LayoutInflater\nimport android.view.View\nimport androidx.navigation.fragment.findNavController\nimport android.view.ViewGroup\nimport android.widget.ProgressBar\nimport android.widget.TextView\nimport androidx.fragment.app.activityViewModels\nimport androidx.lifecycle.lifecycleScope\nimport androidx.paging.LoadState\nimport androidx.paging.Pager\nimport androidx.paging.PagingConfig\nimport androidx.paging.cachedIn\n\nimport androidx.recyclerview.widget.LinearLayoutManager\nimport androidx.recyclerview.widget.RecyclerView\nimport com.demomiru.tokeiv2.utils.ContinueWatchingViewModel2\n\nimport com.demomiru.tokeiv2.utils.addRecyclerAnimation\nimport com.demomiru.tokeiv2.utils.playShow\nimport com.demomiru.tokeiv2.utils.retrofitBuilder\n\nimport kotlinx.coroutines.DelicateCoroutinesApi\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.GlobalScope\nimport kotlinx.coroutines.launch\nimport kotlinx.coroutines.withContext\n\nclass TVShowFragment : Fragment() {\n\n    private val activityViewModel : ContinueWatchingViewModel2 by activityViewModels()\n    private lateinit var popTvRc: RecyclerView\n    private lateinit var trenTvRc: RecyclerView\n    private lateinit var topTvRc : RecyclerView\n\n\n\n\n    @OptIn(DelicateCoroutinesApi::class)\n    override fun onCreateView(\n        inflater: LayoutInflater, container: ViewGroup?,\n        savedInstanceState: Bundle?\n    ): View? {\n        // Inflate the layout for this fragment\n        val view =  inflater.inflate(R.layout.fragment_tv_show, container, false)\n        popTvRc = view.findViewById(R.id.popular_tvshow_rc)\n        trenTvRc = view.findViewById(R.id.trending_tvshow_rc)\n        topTvRc = view.findViewById(R.id.toprated_tvshow_rc)\n\n\n        val retrofit = retrofitBuilder()\n        topTvRc.layoutManager = LinearLayoutManager(requireContext(),LinearLayoutManager.HORIZONTAL,false)\n        popTvRc.layoutManager = LinearLayoutManager(requireContext(),LinearLayoutManager.HORIZONTAL,false)\n        trenTvRc.layoutManager = LinearLayoutManager(requireContext(),LinearLayoutManager.HORIZONTAL,false)\n\n        val tvService = retrofit.create(TMDBService::class.java)\n\n        lifecycleScope.launch(Dispatchers.IO) {\n//            val tvPopularShows = Pager(PagingConfig(1)){TvShowPagingSource(1)}.flow.cachedIn(lifecycleScope)\n//\n//\n//            val tvTrendingShows = Pager(PagingConfig(1)){TvShowPagingSource(2)}.flow.cachedIn(lifecycleScope)\n//\n//            val tvTopShows = Pager(PagingConfig(1)){TvShowPagingSource(3)}.flow.cachedIn(lifecycleScope)\n\n            val topAdapter = TVShowAdapter2{ it, position->\n//                    val action = TVShowFragmentDirections.actionTVShowFragmentToTVShowDetails(it.id)\n                    findNavController().navigate(playShow(it,position,it.name))\n            }\n\n\n\n            val trenAdapter = TVShowAdapter2{it, position->\n//                    val action = TVShowFragmentDirections.actionTVShowFragmentToTVShowDetails(it.id)\n                    findNavController().navigate(playShow(it,position,it.name))\n                }\n\n\n\n            val popAdapter = TVShowAdapter2{it, position->\n//                    val action = TVShowFragmentDirections.actionTVShowFragmentToTVShowDetails(it.id)\n                    findNavController().navigate(playShow(it,position,it.name))\n            }\n\n\n\n            withContext(Dispatchers.Main){\n                addRecyclerAnimation(popTvRc,popAdapter)\n                addRecyclerAnimation(trenTvRc,trenAdapter)\n                addRecyclerAnimation(topTvRc,topAdapter)\n                lifecycleScope.launch {\n                    activityViewModel.tvTrendingShows.collect{\n                        trenAdapter.submitData(it)\n                    }\n                }\n\n                lifecycleScope.launch {\n                    activityViewModel.tvPopularShows.collect{\n                        popAdapter.submitData(it)\n                    }\n                }\n\n                lifecycleScope.launch {\n                    topAdapter.addLoadStateListener {\n                        val state = it.refresh\n                        val visible = state is LoadState.Loading\n                        if(visible)\n                        {\n                            view.findViewById<ProgressBar>(R.id.loading_tvshow).visibility = View.VISIBLE\n                        }else{\n                            view.findViewById<ProgressBar>(R.id.loading_tvshow).visibility = View.GONE\n                            view.findViewById<TextView>(R.id.trending_text).visibility = View.VISIBLE\n                            view.findViewById<TextView>(R.id.popular_text).visibility = View.VISIBLE\n                            view.findViewById<TextView>(R.id.topShows_text).visibility = View.VISIBLE\n                        }\n                    }\n                    activityViewModel.tvTopShows.collect{\n                        topAdapter.submitData(it)\n                    }\n                }\n\n            }\n        }\n        return view\n    }\n\n    override fun onResume() {\n        activityViewModel.currentFragment.value = R.id.TVShowFragment\n        super.onResume()\n    }\n}"
  },
  {
    "path": "app/src/main/java/com/demomiru/tokeiv2/TVshow.kt",
    "content": "package com.demomiru.tokeiv2\n\ndata class TVshow(\n    val id: String,\n    val name: String,\n    val poster_path: String,\n    val backdrop_path: String\n)\n"
  },
  {
    "path": "app/src/main/java/com/demomiru/tokeiv2/VideoPlayActivity.kt",
    "content": "@file:Suppress(\"DEPRECATION\")\n@file:OptIn(DelicateCoroutinesApi::class)\n\npackage com.demomiru.tokeiv2\n\nimport androidx.appcompat.app.AppCompatActivity\nimport android.os.Bundle\nimport com.demomiru.tokeiv2.watching.VideoData\nimport android.annotation.SuppressLint\nimport android.content.Context\nimport android.content.res.Resources\nimport android.health.connect.datatypes.units.Length\nimport android.media.AudioManager\nimport android.net.Uri\nimport android.os.Handler\nimport android.os.Looper\nimport android.os.PowerManager\nimport android.provider.Settings\nimport android.util.Log\nimport android.view.GestureDetector\nimport android.view.MotionEvent\nimport android.view.View\nimport android.webkit.WebResourceRequest\nimport android.webkit.WebResourceResponse\nimport android.webkit.WebView\nimport android.webkit.WebViewClient\nimport android.widget.AdapterView\nimport android.widget.ArrayAdapter\nimport android.widget.Button\nimport android.widget.FrameLayout\nimport android.widget.ImageButton\nimport android.widget.ImageView\nimport android.widget.LinearLayout\nimport android.widget.ProgressBar\n\nimport android.widget.SeekBar\nimport android.widget.Spinner\nimport android.widget.TextView\nimport android.widget.Toast\nimport androidx.activity.viewModels\n\nimport androidx.constraintlayout.widget.ConstraintLayout\nimport androidx.core.content.ContentProviderCompat.requireContext\n\n\nimport androidx.core.view.GestureDetectorCompat\nimport androidx.core.view.isVisible\nimport androidx.lifecycle.MutableLiveData\nimport androidx.lifecycle.lifecycleScope\nimport androidx.media3.common.C\nimport androidx.media3.common.MediaItem\nimport androidx.media3.common.MimeTypes\nimport androidx.media3.common.PlaybackException\nimport androidx.media3.common.Player\nimport androidx.media3.common.Timeline\nimport androidx.media3.common.TrackSelectionOverride\nimport androidx.media3.common.Tracks\nimport androidx.media3.common.text.CueGroup\nimport androidx.media3.datasource.DefaultDataSourceFactory\nimport androidx.media3.datasource.DefaultHttpDataSource\nimport androidx.media3.exoplayer.ExoPlayer\n\nimport androidx.media3.exoplayer.hls.HlsMediaSource\nimport androidx.media3.exoplayer.source.BaseMediaSource\nimport androidx.media3.exoplayer.source.MediaSource\nimport androidx.media3.exoplayer.source.MergingMediaSource\nimport androidx.media3.exoplayer.source.ProgressiveMediaSource\nimport androidx.media3.exoplayer.source.SingleSampleMediaSource\nimport androidx.media3.exoplayer.trackselection.DefaultTrackSelector\nimport androidx.media3.exoplayer.upstream.DefaultBandwidthMeter\nimport androidx.media3.ui.AspectRatioFrameLayout\n\nimport androidx.media3.ui.PlayerView\nimport androidx.media3.ui.SubtitleView\nimport androidx.recyclerview.widget.LinearLayoutManager\nimport androidx.recyclerview.widget.RecyclerView\nimport com.demomiru.tokeiv2.subtitles.SubTrackAdapter\nimport com.demomiru.tokeiv2.subtitles.Subtitle\nimport com.demomiru.tokeiv2.subtitles.SubtitleConfig\nimport com.demomiru.tokeiv2.tracks.SourceAdapter\nimport com.demomiru.tokeiv2.tracks.Track\nimport com.demomiru.tokeiv2.tracks.TrackAdapter\nimport com.demomiru.tokeiv2.utils.ExtractedData\nimport com.demomiru.tokeiv2.utils.Extractor\nimport com.demomiru.tokeiv2.utils.GoMovies\nimport com.demomiru.tokeiv2.utils.GogoAnime\nimport com.demomiru.tokeiv2.utils.OpenSubtitle\nimport com.demomiru.tokeiv2.utils.SmashyStream\nimport com.demomiru.tokeiv2.utils.SubAdapter\nimport com.demomiru.tokeiv2.utils.SuperstreamUtils\nimport com.demomiru.tokeiv2.utils.VideoViewModel\nimport com.demomiru.tokeiv2.utils.encodeStringToInt\n\nimport com.demomiru.tokeiv2.utils.getHiTvSeasons\nimport com.demomiru.tokeiv2.utils.getMovieImdb\nimport com.demomiru.tokeiv2.utils.getSeasonEpisodes\nimport com.demomiru.tokeiv2.utils.getTvIMDB\nimport com.demomiru.tokeiv2.utils.getTvImdb\nimport com.demomiru.tokeiv2.utils.getTvLink\nimport com.demomiru.tokeiv2.utils.getTvSeasons\nimport com.demomiru.tokeiv2.utils.setSeekBarTime\nimport com.demomiru.tokeiv2.watching.ContinueWatching\nimport com.demomiru.tokeiv2.watching.ContinueWatchingDatabase\nimport com.google.android.material.progressindicator.CircularProgressIndicator\nimport com.google.android.material.switchmaterial.SwitchMaterial\nimport com.google.gson.Gson\nimport com.google.gson.reflect.TypeToken\nimport kotlinx.coroutines.DelicateCoroutinesApi\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.GlobalScope\nimport kotlinx.coroutines.launch\nimport kotlinx.coroutines.withContext\nimport okhttp3.MediaType.Companion.toMediaTypeOrNull\nimport okhttp3.OkHttpClient\nimport okhttp3.Request\nimport okhttp3.RequestBody.Companion.toRequestBody\nimport java.io.File\nimport java.lang.reflect.Type\nimport kotlin.Exception\nimport kotlin.math.abs\n\n\nclass VideoPlayActivity : AppCompatActivity(),AudioManager.OnAudioFocusChangeListener, GestureDetector.OnGestureListener {\n\n    private val gson = Gson()\n    private val superStream = SuperstreamUtils()\n    private var trackUpdate = 0L\n    private val fileList: MutableList<String> = mutableListOf()\n    private val fileLinks: MutableList<String> = mutableListOf()\n    private var bfapplyUrl = \"\"\n    private var setTrackAdapter = 1\n    private val openSubtitleAPI = BuildConfig.OPEN_SUBTITLE_API_KEY\n    private var subUpdateProgress = 0L\n    private var isShowFinished = false\n    private var animeEpList : List<GogoAnime.Episode>? = null\n    private lateinit var subSelectBg : ConstraintLayout\n    private lateinit var sourceSelectRc: RecyclerView\n    private lateinit var qualitySelectBg: ConstraintLayout\n    private lateinit var videoLoading: FrameLayout\n    private lateinit var showSubs: SwitchMaterial\n    private var totalSeasons = 1\n    private var totalEpisode = 0\n    private var superId: Int? = null\n    private var isNextEpisode = MutableLiveData(false)\n//    private var isControllerVisible = true\n    private lateinit var id:String\n    private var season: Int = 1\n    private var episode: Int = 1\n    private var progress : Int = 0\n    private var imgLink : String? = null\n    private var year : String = \"\"\n    private lateinit var title:String\n    private var type : String? = null\n    private var imdbId : String? = null\n    private var urlMaps: MutableMap<String,String> = mutableMapOf()\n    private lateinit var unlockIv : ImageView\n    private var isLocked = false\n    private lateinit var lockLL : LinearLayout\n    private val database by lazy { ContinueWatchingDatabase.getInstance(this) }\n    private val watchHistoryDao by lazy { database.watchDao() }\n    private lateinit var gestureDetectorCompat : GestureDetectorCompat\n    private var subList = MutableLiveData<List<String>>()\n    private lateinit var player : ExoPlayer\n    private lateinit var goBack : ImageView\n    private lateinit var videoUri: Uri\n    private var newVideoUrl  = MutableLiveData<String>(\"\")\n    private var isTrackChanged = false\n    private var maxVolume: Int = 0\n    private var brightness: Int = 0\n    private lateinit var brightnessLL: LinearLayout\n    private var animeUrl = \"\"\n    private lateinit var brightnessSeek : SeekBar\n    private lateinit var volumeLL: LinearLayout\n    private lateinit var mainPlayer:FrameLayout\n    private lateinit var volumeSeek : SeekBar\n    private var audioManager: AudioManager? = null\n    private lateinit var seekBar:SeekBar\n    private var q = \"\"\n    private var subUrl : List<String> = listOf()\n    private var newSubUrl: MutableList<String> = mutableListOf()\n    private lateinit var mediaSource: MediaSource\n    private lateinit var videoMediaSource: BaseMediaSource\n    private lateinit var playPause: ImageButton\n    private lateinit var titleTv : TextView\n    private lateinit var screenScale: LinearLayout\n    private var volume : Int = 0\n    private var minSwipeY: Float = 0f\n    private var fit = 1\n    private var mOrigin: String? = null\n    private var selectedUrl : String = \"\"\n    private var sourcesList = listOf<ExtractedData>()\n    private var source: String? = \"\"\n    private lateinit var powerManager: PowerManager\n    private lateinit var wakeLock: PowerManager.WakeLock\n    private lateinit var openSubll : LinearLayout\n    private val oS = OpenSubtitle(this)\n\n\n\n    private val handler = Handler(Looper.getMainLooper())\n    private val updateSeekBarRunnable = object : Runnable {\n        override fun run() {\n            seekBar.progress = player.currentPosition.toInt()\n            subUpdateProgress = player.currentPosition\n            //TODO get link for next episode after progress > 95\n            handler.postDelayed(this, 1000)\n        }\n    }\n\n    @SuppressLint(\"UnsafeOptInUsageError\", \"ClickableViewAccessibility\", \"SetTextI18n\",\n        \"SetJavaScriptEnabled\"\n    )\n\n    override fun onCreate(savedInstanceState: Bundle?) {\n        super.onCreate(savedInstanceState)\n\n        setContentView(R.layout.activity_video_play)\n        powerManager = getSystemService(POWER_SERVICE) as PowerManager\n        wakeLock = powerManager.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK, \"VideoPlayerActivity:wakelock\")\n        showSubs = findViewById(R.id.switchcompat)\n\n\n//        val sub =PlayerControlView.findViewById<SubtitleView>(R.id.exo_subtitles)\n        val videoNext = findViewById<LinearLayout>(R.id.videoView_next_ep)\n        val buffer = findViewById<ProgressBar>(R.id.buffering)\n        val bundle = intent.extras\n        val origin = intent.getStringExtra(\"origin\")\n\n        var isSuper = intent.getBooleanExtra(\"superstream\",false)\n        source = intent.getStringExtra(\"source\")\n\n        val data = bundle?.getParcelable(\"VidData\") as? VideoData\n\n        type = data!!.type\n        mOrigin = data.origin\n        year = data.year?: \"\"\n        if(type == \"anime\") {\n            animeEpList = data.animeEpisode\n            totalEpisode = animeEpList!!.size\n        }\n        id = data.tmdbID.toString()\n        println(\"Video Url:\" + data.videoUrl)\n\n        videoUri =  if(isSuper){\n            q = \"720p\"\n            urlMaps = gson.fromJson(data.videoUrl,object : TypeToken<Map<String, String>>() {}.type)\n            selectedUrl = if(urlMaps[\"720p\"].isNullOrEmpty()) {\n                q = urlMaps.keys.first()\n                urlMaps[q]!!\n            } else\n                urlMaps[\"720p\"]!!\n\n            Uri.parse(selectedUrl)\n\n        } else Uri.parse(data.videoUrl)\n\n        bfapplyUrl = selectedUrl\n\n\n        progress = data.progress\n        title = data.title\n        imgLink = data.imgLink\n        superId = data.superId\n        subUrl = data.superSub\n        imdbId = data.imdbId\n\n        println(\"SuperID: $superId\")\n\n        if (type != \"movie\"){\n            season = data.season\n            episode = data.episode\n        }\n\n        val videoQuality = findViewById<TextView>(R.id.videoView_quality)\n        videoQuality.text = if (isSuper) q else \"Auto\"\n        val sourceLoading = findViewById<ProgressBar>(R.id.source_loading)\n\n        val sourceAdapter = SourceAdapter{\n            newSubUrl.clear()\n            newSubUrl.addAll(it.subs)\n            if(fileLinks.isNotEmpty()){\n                val l = fileLinks.size\n                val fl = fileList.size\n                var j = 1\n                val map  = mutableMapOf<String,String>()\n                for (i in (fl-l) until fl ){\n                    val lang = fileList[i].substringAfter(\"lang-\").substringBefore(\"N\").replace(\"%20\",\"\")\n                    map[\"$j OS - $lang\"] = fileList[i]\n                }\n                val mapString = gson.toJson(map)\n                val prevSubs = newSubUrl\n                newSubUrl = (prevSubs + mapString).toMutableList()\n            }\n            source = it.source\n            isSuper = it.isSuper\n            isTrackChanged = true\n            setTrackAdapter = 1\n            newVideoUrl.value = if(!it.isSuper)it.videoUrl else{\n                urlMaps = gson.fromJson(it.videoUrl,object : TypeToken<Map<String, String>>() {}.type)\n                selectedUrl = urlMaps[\"720p\"]!!\n                bfapplyUrl = selectedUrl\n                selectedUrl\n            }\n            subSelectBg.visibility = View.GONE\n            videoQuality.text = if (isSuper) q else \"Auto\"\n        }\n        sourceSelectRc = findViewById(R.id.source_change_rc)\n        sourceSelectRc.apply {\n            layoutManager = LinearLayoutManager(this@VideoPlayActivity)\n            adapter = sourceAdapter\n        }\n\n        if(type!=\"anime\") {\n            lifecycleScope.launch(Dispatchers.IO) {\n                sourcesList = sourcesList + ExtractedData(data.videoUrl, subUrl, source!!, isSuper)\n                sourcesList = sourcesList + Extractor(mOrigin!!).loadSourceChange(\n                    title,\n                    id,\n                    season,\n                    episode,\n                    year,\n                    type == \"movie\",\n                    source\n                )\n                withContext(Dispatchers.Main) {\n                    sourceLoading.visibility = View.GONE\n                    sourceAdapter.submitList(sourcesList)\n                }\n            }\n        }\n\n\n\n\n        window.decorView.apply {\n            systemUiVisibility = (\n                    View.SYSTEM_UI_FLAG_HIDE_NAVIGATION or\n                            View.SYSTEM_UI_FLAG_IMMERSIVE or\n                            View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY or\n                            View.SYSTEM_UI_FLAG_FULLSCREEN\n                    )\n        }\n        gestureDetectorCompat = GestureDetectorCompat(this,this)\n\n        var play = true\n\n        videoLoading = findViewById(R.id.video_loading_fl)\n        val webView = findViewById<WebView>(R.id.web_view2)\n\n        webView.settings.javaScriptEnabled = true\n        webView.settings.domStorageEnabled = true\n        println(\"Superstream : $isSuper\")\n        webView.webViewClient = object : WebViewClient() {\n\n            override fun shouldOverrideUrlLoading(view: WebView?, request: WebResourceRequest?): Boolean {\n                return request?.url.toString() != view?.url\n            }\n\n            override fun shouldInterceptRequest(\n                view: WebView?,\n                request: WebResourceRequest?\n            ): WebResourceResponse? {\n                if (request?.url.toString().endsWith(\"m3u8\")){\n//                    Log.i(\"Video Link\",\"Found\")\n                    lifecycleScope.launch {\n                        newVideoUrl.value = request?.url.toString()\n                    }\n                }\n                return super.shouldInterceptRequest(view, request)\n            }\n        }\n\n\n\n\n        openSubll = findViewById<LinearLayout>(R.id.open_sub_ll)\n        val addOpenSub = findViewById<Button>(R.id.add_open_sub)\n        val spinner = findViewById<Spinner>(R.id.spinner)\n        val search = findViewById<Button>(R.id.search)\n        val apply = findViewById<Button>(R.id.apply)\n        val subRv = findViewById<RecyclerView>(R.id.sub_rc)\n        var langMap : Map<String,String> = mapOf()\n        var spinList :List<String>\n        var selectedItem = \"English\"\n        var fileLink = \"\"\n        var lI = 0\n\n        var openSubAdapter = SubAdapter{\n            fileLink = it\n        }\n\n        subRv.apply {\n            layoutManager = LinearLayoutManager(this@VideoPlayActivity)\n            adapter = openSubAdapter\n        }\n\n\n        lifecycleScope.launch(Dispatchers.IO) {\n           langMap =  oS.getLang()\n            spinList = langMap.map{\n                it.key\n            }\n            val eI = spinList.indexOfFirst {\n                it == \"English\"\n            }\n\n            withContext(Dispatchers.Main){\n                val arrayAdapter = ArrayAdapter(\n                    this@VideoPlayActivity,\n                    android.R.layout.simple_dropdown_item_1line,\n                    spinList\n                )\n                spinner.adapter = arrayAdapter\n                spinner.setSelection(eI)\n            }\n        }\n\n\n        spinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {\n            override fun onItemSelected(\n                parent: AdapterView<*>?,\n                p1: View?,\n                position: Int,\n                p3: Long\n            ) {\n                val lang = parent?.getItemAtPosition(position) as String\n                if(selectedItem != lang){\n                    openSubAdapter = SubAdapter{\n                        fileLink = it\n                    }\n                    subRv.adapter = openSubAdapter\n                }\n                selectedItem = lang\n\n            }\n\n            override fun onNothingSelected(p0: AdapterView<*>?) {\n                selectedItem = \"English\"\n            }\n\n        }\n\n        search.setOnClickListener {\n            if (langMap.isEmpty())return@setOnClickListener\n            val langCode = langMap[selectedItem]!!\n            lifecycleScope.launch(Dispatchers.IO) {\n                val sid = if(type==\"movie\") getMovieImdb(id) else getTvIMDB(id)\n                val subRes = oS.searchSubs(sid,langCode,season,episode,type==\"movie\" )\n\n                withContext(Dispatchers.Main){\n                    if (subRes.isEmpty()) Toast.makeText(this@VideoPlayActivity,\"No Subs for this Language\",Toast.LENGTH_SHORT).show()\n                    openSubAdapter.submitList(subRes)\n                }\n            }\n        }\n\n\n        apply.setOnClickListener{\n            if(fileLink.isBlank()) return@setOnClickListener\n            if(fileLink in fileLinks) {\n                Toast.makeText(this@VideoPlayActivity,\"Already added\", Toast.LENGTH_SHORT).show()\n                return@setOnClickListener\n            }\n            lifecycleScope.launch(Dispatchers.IO) {\n                val fileName = \"$title-S$season-E$episode-lang-$selectedItem N$lI\"\n                oS.getSub2(fileLink, selectedItem, fileName)\n                fileLinks.add(fileLink)\n                trackUpdate = subUpdateProgress\n                isTrackChanged = true\n                withContext(Dispatchers.Main) {\n                    val map: MutableMap<String, String> = mutableMapOf()\n                    lI++\n                    val link = oS.getSRT(fileName).toString()\n                    map[\"$lI OS - $selectedItem\"] = link\n                    if(link !in fileList) {\n                        val mapString = gson.toJson(map)\n                        val prevSubs = subList.value\n                        subList.value = if (prevSubs != null)\n                            prevSubs + mapString\n                        else\n                            listOf(mapString)\n                        fileList.add(link)\n                    }\n                }\n            }\n        }\n\n\n\n\n        val remTimeTv = findViewById<TextView>(R.id.videoView_endtime)\n        val seekForward: ImageButton = findViewById(R.id.videoView_forward)\n        val seekBack : ImageButton = findViewById(R.id.videoView_rewind)\n        val subTracks : LinearLayout = findViewById(R.id.videoView_track)\n        val vidTracks : LinearLayout = findViewById(R.id.videoView_resolution)\n//        if (isSuper) vidTracks.visibility = View.GONE\n\n        if(type == \"anime\") subTracks.visibility = View.GONE\n\n\n        val skipOp : LinearLayout = findViewById(R.id.videoView_skip_op)\n        if(type != \"tvshow\") skipOp.visibility = View.VISIBLE\n        val skipOpText = findViewById<TextView>(R.id.skip_op_text)\n        skipOpText.text = if(type == \"movie\") \"Skip CAM Ads\" else \"Skip OP\"\n\n\n        val subSelectionView: RecyclerView = findViewById(R.id.sub_tracks_rc)\n\n        subSelectBg = findViewById(R.id.subtitle_select)\n        qualitySelectBg = findViewById(R.id.quality_select)\n\n        val applySub : Button = findViewById(R.id.apply_sub)\n        val applyQuality : Button = findViewById(R.id.apply_quality)\n        val screenResizeTv : TextView = findViewById(R.id.screen_resize_text)\n        val screenResizeIv : ImageView = findViewById(R.id.screen_resize_img)\n        mainPlayer = findViewById(R.id.main_player)\n        goBack = findViewById(R.id.videoView_go_back)\n        screenScale = findViewById(R.id.videoView_screen_size)\n        lockLL  = findViewById(R.id.videoView_lock_screen)\n        unlockIv = findViewById(R.id.unlock_controls)\n\n\n\n\n\n        brightnessLL = findViewById(R.id.videoView_two_layout)\n        brightnessSeek = findViewById(R.id.videoView_brightness)\n        val contentResolver = contentResolver\n        val currbrightness = Settings.System.getInt(contentResolver, Settings.System.SCREEN_BRIGHTNESS)*3\n\n        brightnessSeek.max = 30\n        brightness = currbrightness / 10\n\n        if(audioManager == null) audioManager = getSystemService(Context.AUDIO_SERVICE) as AudioManager\n        maxVolume = audioManager!!.getStreamMaxVolume(AudioManager.STREAM_MUSIC)\n        Log.i(\"maxVolume\",maxVolume.toString())\n        volumeLL = findViewById(R.id.volume_ll)\n        volumeSeek = findViewById(R.id.volume_seek)\n        volumeSeek.max = maxVolume\n        volume = maxVolume/2\n\n        subSelectionView.layoutManager = LinearLayoutManager(this)\n\n        val subtitleView = findViewById<SubtitleView>(R.id.custom_subtitles)\n        val playerView = findViewById<PlayerView>(R.id.video_view)\n\n        if(type!=\"anime\")\n        playerView.resizeMode = AspectRatioFrameLayout.RESIZE_MODE_ZOOM\n        else {\n            playerView.resizeMode = AspectRatioFrameLayout.RESIZE_MODE_FIT\n            fit = 3\n            screenResizeTv.text = \"Fit\"\n            screenResizeIv.setImageResource(R.drawable.fit_screen)\n        }\n        playerView.subtitleView?.visibility = View.GONE\n\n        subtitleView.setFractionalTextSize(0.05f)\n        subtitleView.setApplyEmbeddedStyles(false)\n\n        val trackSelector = DefaultTrackSelector(this)\n        player = ExoPlayer.Builder(this).setTrackSelector(trackSelector).build()\n        val tracksRv = findViewById<RecyclerView>(R.id.tracks_rc)\n        tracksRv.layoutManager = LinearLayoutManager(this)\n\n\n        showSubs.setOnClickListener {\n            if (showSubs.isChecked) subtitleView.visibility = View.VISIBLE\n            else subtitleView.visibility = View.GONE\n        }\n\n\n       val a = PlayerView.ControllerVisibilityListener { visibility ->\n           if(visibility == View.VISIBLE || !showSubs.isChecked) subtitleView.visibility = View.GONE\n           else subtitleView.visibility = View.VISIBLE\n       }\n        playerView.setControllerVisibilityListener(a)\n\n        try {\n\n\n            val gestureDetectorDouble =\n                GestureDetectorCompat(this, object : GestureDetector.SimpleOnGestureListener() {\n                    override fun onDoubleTap(e: MotionEvent): Boolean {\n\n                        if (e.x > playerView.width / 2) {\n                            // Double tapped on the right side - forward seek\n                            player.seekTo(player.currentPosition + 10000)\n                            seekBar.progress = player.currentPosition.toInt()\n                        } else {\n                            // Double tapped on the left side - backward seek\n                            player.seekTo(player.currentPosition - 10000)\n                            seekBar.progress = player.currentPosition.toInt()\n                        }\n\n                        return super.onDoubleTap(e)\n                    }\n\n\n//            override fun onSingleTapConfirmed(e: MotionEvent): Boolean {\n//                // Handle single tap event if needed\n//                if (isControllerVisible) {\n//                    playerView.hideController()\n//                    isControllerVisible = false\n//                } else {\n//                    playerView.showController()\n//                    isControllerVisible = true\n//                }\n//                return super.onSingleTapConfirmed(e)\n//            }\n\n                })\n\n            val dataSourceFactory = DefaultHttpDataSource.Factory()\n                .setAllowCrossProtocolRedirects(true)\n                .setConnectTimeoutMs(50000)\n                .setReadTimeoutMs(50000)\n                .setTransferListener(DefaultBandwidthMeter.Builder(this).build())\n\n\n            playPause = findViewById(R.id.videoView_play_pause_btn)\n            seekBar = findViewById(R.id.videoView_seekbar)\n            titleTv = findViewById(R.id.videoView_title)\n\n\n\n\n            val listener = object : Player.Listener {\n\n\n                override fun onTracksChanged(tracks: Tracks) {\n                    if (qualitySelectBg.isVisible || subSelectBg.isVisible) return\n//                    if (isSuper && setTrackAdapter == 1) {\n//                        println(\"Called adapter\")\n//                        val trackData = superUrlSelector()\n//                        val ta = TrackAdapter(trackData) {\n//                            isTrackChanged = true\n//                            newSubUrl = subUrl.toMutableList()\n//                            selectedUrl = urlMaps[it.resolution.second]!!\n//                            videoQuality.text = \"${it.resolution.second}\"\n//                        }\n//                        tracksRv.adapter = ta\n//                        setTrackAdapter--\n//                    }\n                    if (setTrackAdapter == 0) return\n                    else if(player.duration == C.TIME_UNSET) return\n                    else {\n                        val trackGroup = tracks.groups[0]\n                        val trackRv: MutableList<Track> = mutableListOf()\n                        for (i in 0 until trackGroup.length) {\n                            val trackDetails = trackGroup.getTrackFormat(i)\n//                    val selected = trackGroup.isTrackSelected(i)\n                            trackRv.add(\n                                Track(\n                                    trackDetails.id!!.toInt(),\n                                    trackDetails.label.toString(),\n                                    Pair(\n                                        trackDetails.width.toString(),\n                                        trackDetails.height.toString()\n                                    ),\n                                    selected = false\n                                )\n                            )\n                        }\n                        trackRv.add(\n                            Track(\n                                trackGroup.length,\n                                \"Auto\",\n                                Pair(\"\", \"\"),\n                                selected = true\n                            )\n                        )\n                        trackRv.reverse()\n                        val trackAdapter = TrackAdapter(trackRv) { track ->\n//                    val trackSelectionOverride = TrackSelectionOverride(0, track.id)\n//                    track.selected = true\n                            player.trackSelectionParameters = if (track.format != \"Auto\") {\n                                videoQuality.text = \"${track.resolution.second}p\"\n                                player.trackSelectionParameters\n                                    .buildUpon()\n                                    .setOverrideForType(\n                                        TrackSelectionOverride(trackGroup.mediaTrackGroup, track.id)\n                                    )\n                                    .build()\n\n                            } else {\n                                videoQuality.text = \"Auto\"\n                                player.trackSelectionParameters\n                                    .buildUpon()\n                                    .setOverrideForType(\n                                        TrackSelectionOverride(\n                                            trackGroup.mediaTrackGroup,\n                                            MutableList(track.id) { it })\n                                    )\n                                    .build()\n\n\n                            }\n//                    for( i in 0 until ) println(player.currentTracks.groups[0].isTrackSelected(i))\n//                    player.prepare()\n                        }\n                        for (track in trackRv) {\n                            println(track)\n                        }\n                        tracksRv.adapter = trackAdapter\n                    }\n                    super.onTracksChanged(tracks)\n                }\n\n                //            override fun onVideoSizeChanged(videoSize: VideoSize) {\n//               if(videoSize.width !=0 && videoSize.height!=0 ){\n//                   videoQuality.text = \"${videoSize.height}p\"\n//               }\n//                super.onVideoSizeChanged(videoSize)\n//            }\n                override fun onPlayerError(error: PlaybackException) {\n                    Toast.makeText(\n                        this@VideoPlayActivity,\n                        \"Quality not available or Network Issue\",\n                        Toast.LENGTH_SHORT\n                    ).show()\n                    super.onPlayerError(error)\n                }\n\n                @SuppressLint(\"UnsafeOptInUsageError\")\n                override fun onTimelineChanged(timeline: Timeline, reason: Int) {\n\n                        if (isSuper && setTrackAdapter == 1) {\n                            println(\"Called adapter\")\n                            val trackData = superUrlSelector()\n                            val ta = TrackAdapter(trackData) {\n                                isTrackChanged = true\n                                newSubUrl = subList.value?.toMutableList() ?: mutableListOf()\n                                selectedUrl = urlMaps[it.resolution.second]!!\n                                videoQuality.text = \"${it.resolution.second}\"\n                            }\n                            tracksRv.adapter = ta\n                            setTrackAdapter--\n                        }\n\n\n                    if (player.duration != C.TIME_UNSET) {\n                        // Duration is available\n                        seekBar.max = player.duration.toInt()\n\n                        subUpdateProgress = trackUpdate\n                        trackUpdate = 0L\n                        isTrackChanged = false\n\n//                    val seek = player.duration / 100 * progress\n//                    println(subUpdateProgress)\n                        val seek =\n                            if (subUpdateProgress > 0) subUpdateProgress else player.duration / 100 * progress\n                        player.seekTo(seek)\n                        seekBar.progress = seek.toInt()\n                        playerView.setOnTouchListener { _, motionEvent ->\n                            if (!isLocked) {\n                                gestureDetectorDouble.onTouchEvent(motionEvent)\n                                gestureDetectorCompat.onTouchEvent(motionEvent)\n                                if (motionEvent.action == MotionEvent.ACTION_UP) {\n                                    if (brightnessLL.visibility == View.VISIBLE || volumeLL.visibility == View.VISIBLE) {\n                                        playerView.useController = false\n                                        brightnessLL.visibility = View.GONE\n                                        volumeLL.visibility = View.GONE\n\n                                    }\n                                }\n                                Handler(Looper.getMainLooper()).postDelayed({\n                                    playerView.useController = true\n                                }, 1000)\n                            } else {\n\n                                if (unlockIv.visibility == View.VISIBLE) {\n                                    unlockIv.visibility = View.GONE\n                                } else {\n                                    unlockIv.visibility = View.VISIBLE\n                                    Handler(Looper.getMainLooper()).postDelayed({\n                                        unlockIv.visibility = View.GONE\n                                    }, 5000)\n                                }\n\n                            }\n                            return@setOnTouchListener false\n                        }\n                    }\n                    super.onTimelineChanged(timeline, reason)\n                }\n\n                override fun onPlaybackStateChanged(playbackState: Int) {\n                    if (playbackState == Player.STATE_ENDED) {\n                        if (type == \"tvshow\") {\n                            if (isShowFinished || (season == totalSeasons && episode == totalEpisode)) finish()\n                            isNextEpisode.value = true\n                        } else finish()\n\n                    }\n                else if(playbackState == Player.STATE_BUFFERING) {\n                        buffer.visibility = View.VISIBLE\n                        playPause.visibility = View.GONE\n                    }\n                    else {\n                        playPause.visibility = View.VISIBLE\n                        buffer.visibility = View.GONE\n                    }\n                    super.onPlaybackStateChanged(playbackState)\n                }\n\n                override fun onCues(cueGroup: CueGroup) {\n                    subtitleView.setCues(cueGroup.cues)\n                    super.onCues(cueGroup)\n                }\n            }\n            player.addListener(listener)\n\n\n\n\n\n\n            if (subUrl.isEmpty() && imdbId!=null) {\n                println(\"empty\")\n//                lifecycleScope.launch(Dispatchers.IO) {\n//                   val subs = oS.searchSubs(imdbId!!,\"eng\",season,episode,type==\"movie\")\n//                    val fileName = \"$title-$season-$episode-English\"\n//                    oS.getSub2(subs[0].SubDownloadLink,\"English\",fileName)\n//                    subList.postValue(subUrl + listOf(oS.getSRT(fileName).toString()))\n//                }\n                subList.postValue(subUrl)\n\n            } else {\n                subList.postValue(subUrl)\n            }\n\n            isNextEpisode.observe(this) { isNext ->\n                if (isNext) {\n                    setTrackAdapter = 1\n                    if (type == \"anime\") {\n                        getNextAnimeEp()\n                        return@observe\n                    }\n                    println(\"Source: $source\")\n                    episodeNext()\n                    fileLinks.clear()\n                    openSubAdapter = SubAdapter {\n                        fileLink = it\n                    }\n                    subRv.adapter = openSubAdapter\n                    sourceLoading.visibility = View.VISIBLE\n                    lifecycleScope.launch (Dispatchers.IO){\n\n                        val vidData = Extractor(origin!!).loadExtractorNext(title,id,season,episode,source!!)\n                        withContext(Dispatchers.Main){\n                            if(vidData.videoUrl!=null){\n                                newSubUrl.clear()\n                                newSubUrl.addAll(vidData.subs)\n                                newVideoUrl.value = if(!vidData.isSuper)vidData.videoUrl ?: \"\" else{\n                                    urlMaps = gson.fromJson(vidData.videoUrl,object : TypeToken<Map<String, String>>() {}.type)\n                                    selectedUrl = if(urlMaps[q].isNullOrEmpty()){\n                                        q = urlMaps.keys.first()\n                                        urlMaps[q]!!\n                                    }\n                                    else urlMaps[q]!!\n                                    selectedUrl\n                                }\n                            }\n                            else\n                            {\n                                Toast.makeText(this@VideoPlayActivity,\"Link not available\", Toast.LENGTH_SHORT).show()\n                                finish()\n                            }\n                        }\n\n                        val sourceAdapter2 = SourceAdapter{\n                            newSubUrl.clear()\n                            newSubUrl.addAll(it.subs)\n                            if(fileLinks.isNotEmpty()){\n                                val l = fileLinks.size\n                                val fl = fileList.size\n                                var j = 1\n                                val map  = mutableMapOf<String,String>()\n                                for (i in (fl-l) until fl ){\n                                    val lang = fileList[i].substringAfter(\"lang-\").substringBefore(\" \")\n                                    map[\"$j OS - $lang\"] = fileList[i]\n                                }\n                                val mapString = gson.toJson(map)\n                                val prevSubs = newSubUrl\n                                newSubUrl = (prevSubs + mapString).toMutableList()\n                            }\n                            source = it.source\n                            isSuper = it.isSuper\n                            isTrackChanged = true\n                            setTrackAdapter = 1\n                            newVideoUrl.value = if(!it.isSuper)it.videoUrl else{\n                                urlMaps = gson.fromJson(it.videoUrl,object : TypeToken<Map<String, String>>() {}.type)\n                                selectedUrl = if(urlMaps[q].isNullOrEmpty()){\n                                    q = urlMaps.keys.first()\n                                    urlMaps[q]!!\n                                }\n                                else urlMaps[q]!!\n                                bfapplyUrl = selectedUrl\n                                selectedUrl\n                            }\n                            subSelectBg.visibility = View.GONE\n                            videoQuality.text = if (isSuper) q else \"Auto\"\n                        }\n                        sourceSelectRc.adapter = sourceAdapter2\n                        sourcesList = listOf(ExtractedData(newVideoUrl.value,newSubUrl,source!!,isSuper))\n                        sourcesList = sourcesList + Extractor(mOrigin!!).loadSourceChange(title,id,season,episode,year,type == \"movie\",source)\n                        withContext(Dispatchers.Main){\n                            sourceLoading.visibility = View.GONE\n                            sourceAdapter2.submitList(sourcesList)\n                        }\n                    }\n\n//                    if (origin == \"hi\") {\n//                        episodeNext()\n//                        if (!isShowFinished)\n//                            lifecycleScope.launch(Dispatchers.IO) {\n//                                val res =\n//                                    imdbId?.let { getTvLink(it, season - 1, episode - 1) } ?: \"\"\n//\n//                                if (res.isNotBlank()) newVideoUrl.postValue(res)\n//                                else {\n//                                    withContext(Dispatchers.Main) {\n//                                        Toast.makeText(\n//                                            this@VideoPlayActivity,\n//                                            \"Not Available\",\n//                                            Toast.LENGTH_SHORT\n//                                        ).show()\n//                                        finish()\n//                                    }\n//                                }\n//                            }\n//                    } else {\n//                        episodeNext()\n//                        var isVideo = false\n//                        if (!isShowFinished) {\n//                            lifecycleScope.launch(Dispatchers.IO) {\n//                                if (superId != null && isSuper) {\n//                                    val tvLinks =\n//                                        superStream.loadLinks(false, superId!!, season, episode)\n//                                    tvLinks.data?.list?.forEach {\n//                                        if (!it.path.isNullOrBlank()) {\n//                                            println(\"${it.quality} : ${it.path}\")\n//                                            if (it.quality == \"720p\") {\n//                                                val subtitle = superStream.loadSubtile(\n//                                                    false,\n//                                                    it.fid!!,\n//                                                    superId!!,\n//                                                    season,\n//                                                    episode\n//                                                ).data\n//                                                getSub(subtitle)\n//                                                if (it.path.isNullOrBlank()) isVideo = true\n//                                                newVideoUrl.postValue(it.path!!)\n//                                            }\n//                                        }\n//                                    }\n//                                    if (isVideo) {\n////                                    withContext(Dispatchers.Main){\n////                                        Toast.makeText(this@VideoPlayActivity, \"Not Available\",Toast.LENGTH_SHORT).show()\n////                                        finish()\n////                                    }\n//                                        getGoMovieLink()\n////                                    getSmashLink()\n//                                    }\n//                                } else {\n////                                withContext(Dispatchers.Main){\n////                                    Toast.makeText(this@VideoPlayActivity, \"Not Available\",Toast.LENGTH_SHORT).show()\n////                                    finish()\n////                                }\n//                                    getGoMovieLink()\n////                                getSmashLink()\n//                                }\n//                            }\n//                        }\n//                    }\n                    isNextEpisode.value = false\n                }\n            }\n\n            // When Subtitles are available\n            subList.observe(this) {\n                fileLink = \"\"\n                val subtitleConfig: MutableList<SubtitleConfig> = mutableListOf()\n                var s = 0\n//                videoQuality.text = if (isSuper) \"720p\" else \"Auto\"\n                if (!it.isNullOrEmpty()) {\n                    val map = it[0]\n                    var subMap : MutableMap<String,String> = mutableMapOf()\n                    if(!map.isNullOrBlank()) subMap = gson.fromJson(map, object : TypeToken<Map<String, String>>() {}.type)\n                    for( key in subMap.keys){\n                        val subs = subMap[key]!!.split(\",\")\n                        var i = 1\n                        for (element in subs) {\n                            val subtitleMediaSource = if (element.contains(\"vtt\")) {\n                                SingleSampleMediaSource.Factory(dataSourceFactory).createMediaSource(\n                                    MediaItem.SubtitleConfiguration.Builder(Uri.parse(element))\n                                        .setMimeType(MimeTypes.TEXT_VTT)\n                                        .setLanguage(\"en\")\n                                        .setSelectionFlags(C.SELECTION_FLAG_DEFAULT)\n                                        .build(),\n                                    C.TIME_UNSET\n                                )\n                            }else if (element.contains(\"file://\")) {\n                                SingleSampleMediaSource.Factory(DefaultDataSourceFactory(this@VideoPlayActivity,\"user-agent\")).createMediaSource(\n                                    MediaItem.SubtitleConfiguration.Builder(Uri.parse(element))\n                                        .setMimeType(MimeTypes.APPLICATION_SUBRIP)\n                                        .setLanguage(\"en\")\n                                        .setSelectionFlags(C.SELECTION_FLAG_DEFAULT)\n                                        .build(),\n                                    C.TIME_UNSET\n                                )\n                            }\n                            else {\n                                SingleSampleMediaSource.Factory(dataSourceFactory).createMediaSource(\n                                    MediaItem.SubtitleConfiguration.Builder(Uri.parse(element))\n                                        .setMimeType(MimeTypes.APPLICATION_SUBRIP)\n                                        .setLanguage(\"en\")\n                                        .setSelectionFlags(C.SELECTION_FLAG_DEFAULT)\n                                        .build(),\n                                    C.TIME_UNSET\n                                )\n\n                            }\n                            subtitleConfig.add(SubtitleConfig(subtitleMediaSource, language = \"$key $i\"))\n                            if(i==6)break\n                            i++\n                        }\n                    }\n\n                    s = subtitleConfig.indexOfFirst {subConfig ->\n                        subConfig.language.contains(\"English\")\n                    }\n                    if(it.size > 1){\n                        for( i in 1 until it.size){\n                            val map = it[i]\n                            var subMap : MutableMap<String,String> = mutableMapOf()\n                            if(!map.isNullOrBlank()) subMap = gson.fromJson(map, object : TypeToken<Map<String, String>>() {}.type)\n                            for( key in subMap.keys){\n                                val subtitleMediaSource =\n                                    SingleSampleMediaSource.Factory(DefaultDataSourceFactory(this@VideoPlayActivity,\"user-agent\")).createMediaSource(\n                                        MediaItem.SubtitleConfiguration.Builder(Uri.parse(subMap[key]))\n                                            .setMimeType(MimeTypes.APPLICATION_SUBRIP)\n                                            .setLanguage(\"en\")\n                                            .setSelectionFlags(C.SELECTION_FLAG_DEFAULT)\n                                            .build(),\n                                        C.TIME_UNSET\n                                    )\n                                subtitleConfig.add(0,SubtitleConfig(subtitleMediaSource, language = \"$key\"))\n                                s = 0\n                            }\n                        }\n                    }\n\n\n                    // change from here\n//                    for (element in it) {\n//                        println(element)\n//                        val subtitleMediaSource = if (element.contains(\"vtt\")) {\n//                            SingleSampleMediaSource.Factory(dataSourceFactory).createMediaSource(\n//                                MediaItem.SubtitleConfiguration.Builder(Uri.parse(element))\n//                                    .setMimeType(MimeTypes.TEXT_VTT)\n//                                    .setLanguage(\"en\")\n//                                    .setSelectionFlags(C.SELECTION_FLAG_DEFAULT)\n//                                    .build(),\n//                                C.TIME_UNSET\n//                            )\n//                        } else {\n//                            SingleSampleMediaSource.Factory(dataSourceFactory).createMediaSource(\n//                                MediaItem.SubtitleConfiguration.Builder(Uri.parse(element))\n//                                    .setMimeType(MimeTypes.APPLICATION_SUBRIP)\n//                                    .setLanguage(\"en\")\n//                                    .setSelectionFlags(C.SELECTION_FLAG_DEFAULT)\n//                                    .build(),\n//                                C.TIME_UNSET\n//                            )\n//\n//                        }\n//                        subtitleConfig.add(SubtitleConfig(subtitleMediaSource))\n//                    }\n\n//                    val\n                            videoMediaSource = if (isSuper || source == \"nowtv\") {\n                                if(source == \"nowtv\"){\n                                    val dsF = DefaultHttpDataSource.Factory()\n                                        .setDefaultRequestProperties(mapOf(\"Referer\" to \"https://bflix.gs/\",\n                                        \"Connection\" to \"keep-alive\"\n                                            ))\n                                        .setAllowCrossProtocolRedirects(true)\n                                        .setConnectTimeoutMs(50000)\n                                        .setReadTimeoutMs(50000)\n                                        .setTransferListener(DefaultBandwidthMeter.Builder(this).build())\n                                    println(\"NowTV insiide videomedia\")\n                                    ProgressiveMediaSource.Factory(dsF)\n                                        .createMediaSource(MediaItem.fromUri(videoUri))\n\n                                }else\n                                ProgressiveMediaSource.Factory(dataSourceFactory)\n                            .createMediaSource(MediaItem.fromUri(videoUri))\n                    } else {\n                        HlsMediaSource.Factory(dataSourceFactory)\n                            .createMediaSource(MediaItem.fromUri(videoUri))\n                    }\n\n//                player.setMediaItem(mediaItem)\n\n                    subSelectionView.adapter = SubTrackAdapter(subtitleConfig, s){ sub ->\n                        val newMediaSource = MergingMediaSource(videoMediaSource, sub.subConfig)\n                        subUpdateProgress = player.currentPosition\n                        trackUpdate = subUpdateProgress\n                        player.setMediaSource(newMediaSource)\n                        player.prepare()\n//                    player.seekTo(subUpdateProgress)\n//                    seekBar.progress = subUpdateProgress.toInt()\n                    }\n                    mediaSource = MergingMediaSource(videoMediaSource, subtitleConfig[s].subConfig)\n                } else {\n                    subSelectionView.adapter = SubTrackAdapter(subtitleConfig, s) {}\n                    mediaSource = if (isSuper) {\n                        ProgressiveMediaSource.Factory(dataSourceFactory)\n                            .createMediaSource(MediaItem.fromUri(videoUri))\n                    } else {\n                        HlsMediaSource.Factory(dataSourceFactory)\n                            .createMediaSource(MediaItem.fromUri(videoUri))\n                    }\n                }\n\n                player.setMediaSource(mediaSource)\n                if (type == \"movie\")\n                    titleTv.text = title\n                else {\n                    videoNext.visibility = View.VISIBLE\n                    titleTv.text =\n                        if (type == \"tvshow\") \"$title S$season E$episode\" else \"$title E${episode + 1}\"\n                }\n\n                mainPlayer.visibility = View.VISIBLE\n                playerView.player = player\n                videoLoading.visibility = View.GONE\n\n                player.prepare()\n                player.playWhenReady = true\n\n                println(\"${player.videoSize.width} x ${player.videoSize.height}\")\n\n                playerPlay()\n\n                subTracks.setOnClickListener {\n                    playerPause()\n                    mainPlayer.visibility = View.GONE\n                    subSelectBg.visibility = View.VISIBLE\n\n                }\n\n                addOpenSub.setOnClickListener {\n                    openSubll.visibility = View.VISIBLE\n                    subSelectBg.visibility = View.GONE\n                }\n\n                vidTracks.setOnClickListener {\n                    playerPause()\n                    mainPlayer.visibility = View.GONE\n                    qualitySelectBg.visibility = View.VISIBLE\n                }\n\n                applyQuality.setOnClickListener {\n                    qualitySelectBg.visibility = View.GONE\n                    mainPlayer.visibility = View.VISIBLE\n                    if(isSuper) {\n                        if (bfapplyUrl != selectedUrl)\n                            newVideoUrl.value = selectedUrl\n                    }\n\n                    player.seekTo(subUpdateProgress)\n                    seekBar.progress = subUpdateProgress.toInt()\n\n                    playerPlay()\n                    bfapplyUrl = selectedUrl\n                }\n\n                applySub.setOnClickListener {\n                    subSelectBg.visibility = View.GONE\n                    mainPlayer.visibility = View.VISIBLE\n                    player.seekTo(subUpdateProgress)\n                    seekBar.progress = subUpdateProgress.toInt()\n                    playerPlay()\n                }\n\n\n                playPause.setOnClickListener {\n                    play = if (play) {\n                        player.pause()\n                        playPause.setImageResource(R.drawable.icon_play)\n                        false\n                    } else {\n                        player.play()\n                        playPause.setImageResource(R.drawable.netflix_pause_button)\n                        true\n                    }\n                }\n\n                seekForward.setOnClickListener {\n                    val progress = (player.currentPosition + 10000)\n                    player.seekTo(progress)\n                    seekBar.progress = progress.toInt()\n                    seekForward.rotation = 90f\n                    Handler(Looper.getMainLooper()).postDelayed({\n                        seekForward.rotation = 0f\n                    }, 1000)\n                }\n\n                seekBack.setOnClickListener {\n                    val progress = (player.currentPosition - 10000)\n                    player.seekTo(progress)\n                    seekBar.progress = progress.toInt()\n                    seekBack.rotation = -90f\n                    Handler(Looper.getMainLooper()).postDelayed({\n                        seekBack.rotation = 0f\n                    }, 1000)  // Delay of 1 second\n\n                }\n\n                screenScale.setOnClickListener {\n                    when (fit) {\n                        1 -> {\n                            playerView.resizeMode = AspectRatioFrameLayout.RESIZE_MODE_FILL\n                            screenResizeTv.text = \"Fill\"\n                            screenResizeIv.setImageResource(R.drawable.fill_screen)\n                            fit = 2\n                        }\n\n                        2 -> {\n                            playerView.resizeMode = AspectRatioFrameLayout.RESIZE_MODE_FIT\n                            screenResizeTv.text = \"Fit\"\n                            screenResizeIv.setImageResource(R.drawable.fit_screen)\n                            fit = 3\n                        }\n\n                        else -> {\n                            playerView.resizeMode = AspectRatioFrameLayout.RESIZE_MODE_ZOOM\n                            screenResizeTv.text = \"Zoom\"\n                            screenResizeIv.setImageResource(R.drawable.baseline_zoom_out_map_24)\n                            fit = 1\n                        }\n                    }\n                }\n\n                lockLL.setOnClickListener {\n                    isLocked = true\n                    playerView.useController = false\n//                    unlockIv.visibility = View.VISIBLE\n                }\n\n\n                goBack.setOnClickListener {\n                    finish()\n                }\n\n                unlockIv.setOnClickListener {\n                    isLocked = false\n                    playerView.useController = true\n                    unlockIv.visibility = View.GONE\n                }\n\n                videoNext.setOnClickListener {\n                    isNextEpisode.value = true\n                }\n\n                skipOp.setOnClickListener {\n                    val progress = (player.currentPosition + 90000)\n                    player.seekTo(progress)\n                    seekBar.progress = progress.toInt()\n                }\n\n            }\n\n            newVideoUrl.observe(this) { newUrl ->\n                if (!newUrl.isNullOrEmpty()) {\n                    videoUri = Uri.parse(newUrl)\n                    if (!isTrackChanged) {\n                        if(isSuper) videoQuality.text = \"720p\" else videoQuality.text = \"Auto\"\n                        progress = 0\n                        subUpdateProgress = 0\n                    } else {\n//                        newSubUrl = subUrl.toMutableList()\n                        trackUpdate = subUpdateProgress\n                    }\n                    isTrackChanged = false\n\n                    subList.value = newSubUrl.toList()\n\n//                    if (newSubUrl.isEmpty() && type != \"anime\") {\n//                        println(\"empty\")\n//                        lifecycleScope.launch(Dispatchers.IO) {\n//                            val fileID: List<String> = if (type == \"movie\") {\n//                                getSubtitles(id)\n//                            } else {\n//                                getSubtitles(id, season, episode)\n//                            }\n//\n//                            subList.postValue(getAuthToken(fileID))\n//                        }\n//                    } else {\n//                        subList.postValue(newSubUrl.toList())\n//                    }\n                }\n            }\n\n            if (type == \"tvshow\") {\n                lifecycleScope.launch(Dispatchers.IO) {\n                    totalSeasons =\n                        if (origin != \"hi\") getTvSeasons(id) else getHiTvSeasons(imdbId!!)\n                    totalEpisode = getSeasonEpisodes(id, season)\n                }\n\n            }\n\n\n//        if (seekBar.progress == seekBar.max)isNextEpisode.value = true\n\n\n            seekBar.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {\n                override fun onProgressChanged(\n                    seekBar: SeekBar?,\n                    progress: Int,\n                    fromUser: Boolean\n                ) {\n                    if (player.duration != C.TIME_UNSET) {\n                        val rem = player.duration - progress.toLong()\n                        if (fromUser) {\n                            player.seekTo(progress.toLong())\n                            subUpdateProgress = player.currentPosition\n                            remTimeTv.text = setSeekBarTime(rem)\n                        }\n                        remTimeTv.text = setSeekBarTime(rem)\n                        subUpdateProgress = player.currentPosition\n                    }\n                }\n\n                override fun onStartTrackingTouch(seekBar: SeekBar?) {\n                    // Optional: stop updating the SeekBar while the user is dragging it\n                    handler.removeCallbacks(updateSeekBarRunnable)\n                }\n\n                override fun onStopTrackingTouch(seekBar: SeekBar?) {\n                    // Optional: resume updating the SeekBar after the user finished dragging it\n                    handler.post(updateSeekBarRunnable)\n                }\n            })\n\n\n            // Start updating the SeekBar\n            handler.post(updateSeekBarRunnable)\n        }catch (e :Exception){e.printStackTrace()}\n\n    }\n\n//    private suspend fun getGoMovieLink(){\n//        val goMovie = GoMovies()\n//        newSubUrl.clear()\n//        lifecycleScope.launch(Dispatchers.IO) {\n//            val data = goMovie.search(season, episode, title,false,year)\n//            val vidLink = data.first\n//            val subLinks = data.second\n//            if(vidLink.isNullOrBlank()){\n////                withContext(Dispatchers.Main){\n////                    Toast.makeText(this@VideoPlayActivity, \"Not Available\",Toast.LENGTH_SHORT).show()\n////                    finish()\n////                }\n//                getSmashLink()\n//            }\n//            else{\n//                if (!subLinks.isNullOrEmpty())newSubUrl.addAll(subLinks)\n//                newVideoUrl.postValue(vidLink!!)\n//            }\n//        }\n//    }\n\n//    private fun getSmashLink()\n//    {\n//        newSubUrl.clear()\n//        val smashSrc = SmashyStream()\n//        lifecycleScope.launch(Dispatchers.IO) {\n//            val links = smashSrc.getLink(false,id, season, episode)\n//            val vidLink = links.first\n//            val subLink = links.second\n//            if(vidLink.isNullOrBlank()){\n//                withContext(Dispatchers.Main){\n//                    Toast.makeText(this@VideoPlayActivity, \"Not Available\",Toast.LENGTH_SHORT).show()\n//                    finish()\n//                }\n//            }\n//            else{\n//                if (!subLink.isNullOrBlank())newSubUrl.add(subLink)\n//                newVideoUrl.postValue(vidLink!!)\n//            }\n//        }\n//    }\n//\n//    private fun getSub(subtitle: SuperstreamUtils.PrivateSubtitleData?){\n//        newSubUrl.clear()\n//        subtitle?.list?.forEach { subList->\n//            if(subList.language == \"English\"){\n//                subList.subtitles.forEach { sub->\n//\n//                    if (newSubUrl.size == 3) {\n//                        return\n//                    }\n//                    if (sub.lang == \"en\" && !sub.file_path.isNullOrBlank()) {\n//                        newSubUrl.add(sub.file_path)\n//                        println(\"${sub.language} : ${sub.file_path}\")\n//                    }\n//\n//\n//                }\n//                return\n//            }\n//        }\n//    }\n\n\n    private fun getNextAnimeEp()\n    {\n        val gogoSrc = GogoAnime()\n        episode+=1\n        if (episode == totalEpisode) {\n            Toast.makeText(this, \"No further episodes\", Toast.LENGTH_SHORT).show()\n            isShowFinished = true\n            episode = totalEpisode-1\n            return\n        }\n        animeUrl = animeEpList?.get(episode)?.url ?: \"\"\n        mainPlayer.visibility = View.GONE\n        playerPause()\n        videoLoading.visibility = View.VISIBLE\n\n        lifecycleScope.launch {\n            newVideoUrl.postValue(gogoSrc.extractVideos(animeUrl))\n        }\n    }\n\n\n    private fun getAuthToken(fileId: List<String>): List<String>{\n        val client = OkHttpClient()\n\n        val mediaType = \"application/json\".toMediaTypeOrNull()\n        val body =\n            \"{\\n  \\\"username\\\": \\\"bokaboy_20\\\",\\n  \\\"password\\\": \\\"d.omh.err.y61.7@gmail.com\\\"\\n}\".toRequestBody(mediaType)\n        try {\n\n\n            val request = Request.Builder()\n                .url(\"https://api.opensubtitles.com/api/v1/login\")\n                .post(body)\n                .addHeader(\"Content-Type\", \"application/json\")\n                .addHeader(\"User-Agent\", \"\")\n                .addHeader(\"Accept\", \"application/json\")\n                .addHeader(\"Api-Key\", openSubtitleAPI)\n                .build()\n            val response = client.newCall(request).execute()\n\n\n\n            if (response.isSuccessful) {\n                val gson = Gson()\n\n                val responseBody = response.body\n\n                val type: Type = object : TypeToken<Map<String?, Any?>?>() {}.type\n                val map: Map<String, Any> = gson.fromJson(responseBody.string(), type)\n                val token = map[\"token\"].toString()\n                Log.i(\"response\", token)\n\n                responseBody.close()\n                val downloadUrlList = mutableListOf<String>()\n                for (element in fileId) {\n                    downloadUrlList.add(getSubtitleURl(token, element))\n                }\n\n                return downloadUrlList.toList()\n            } else\n                Log.i(\"response\", \"unsuccessful\")\n        }catch (e :Exception){\n            e.printStackTrace()\n            return listOf()\n        }\n        return listOf()\n    }\n\n    private fun getSubtitleURl(token:String, fileId: String):String{\n        val client = OkHttpClient()\n\n        val mediaType = \"application/json\".toMediaTypeOrNull()\n        val body = \"{\\n  \\\"file_id\\\": $fileId\\n}\".toRequestBody(mediaType)\n        try{\n            val request = Request.Builder()\n                .url(\"https://api.opensubtitles.com/api/v1/download\")\n                .post(body)\n                .addHeader(\"User-Agent\", \"\")\n                .addHeader(\"Content-Type\", \"application/json\")\n                .addHeader(\"Accept\", \"application/json\")\n                .addHeader(\"Api-Key\", openSubtitleAPI)\n                .addHeader(\"Authorization\", token)\n                .build()\n\n            val response = client.newCall(request).execute()\n            if (response.isSuccessful){\n                val gson = Gson()\n\n                val responseBody = response.body\n\n                val type: Type = object : TypeToken<Map<String?, Any?>?>() {}.type\n                val map: Map<String, Any> = gson.fromJson(responseBody.string(), type)\n                responseBody.close()\n                return map[\"link\"].toString()\n\n            }\n        }catch (e :Exception){\n            e.printStackTrace()\n            return \"\"\n        }\n        return \"\"\n    }\n\n    private fun getSubtitles(tmdbId:String, season:Int = 0, episode:Int = 0) : List<String>{\n        val client = OkHttpClient()\n\n        try{\n            val request : Request\n            if(type == \"movie\") {\n                request = Request.Builder()\n                    .url(\"https://api.opensubtitles.com/api/v1/subtitles?tmdb_id=$tmdbId&type=movie&languages=en&order_by=ratings&page=1\")\n                    .get()\n                    .addHeader(\"User-Agent\", \"\")\n                    .addHeader(\"Api-Key\", openSubtitleAPI)\n                    .build()\n            }\n            else{\n                request = Request.Builder()\n                    .url(\"https://api.opensubtitles.com/api/v1/subtitles?languages=en&order_by=ratings&parent_tmdb_id=$tmdbId&season_number=$season&episode_number=$episode&page=1\")\n                    .get()\n                    .addHeader(\"User-Agent\", \"\")\n                    .addHeader(\"Api-Key\", openSubtitleAPI)\n                    .build()\n            }\n\n            val response = client.newCall(request).execute()\n            if (response.isSuccessful){\n                val gson = Gson()\n                val responseBody = response.body\n                val subtitle: Subtitle = gson.fromJson(responseBody.string(), Subtitle::class.java)\n                responseBody.close()\n                val fileIDs = mutableListOf<String>()\n                val count = if(subtitle.data.size> 3) 3\n                else subtitle.data.size\n\n                for (i in 0 until count){\n                    fileIDs.add(subtitle.data[i].attributes.files[0].file_id)\n                }\n                return fileIDs.toList()\n            }\n        }catch (e :Exception){\n            e.printStackTrace()\n            return listOf()\n        }\n        return listOf()\n    }\n\n\n    private fun playerPause(){\n        player.pause()\n        playPause.setImageResource(R.drawable.icon_play)\n    }\n    private fun playerPlay(){\n        player.play()\n        playPause.setImageResource(R.drawable.netflix_pause_button)\n    }\n\n    override fun onPause(){\n        wakeLock.release()\n        player.pause()\n        playPause.setImageResource(R.drawable.icon_play)\n        super.onPause()\n\n    }\n\n    override fun onDestroy() {\n        handler.removeCallbacks(updateSeekBarRunnable)\n        val currentPosition = player.currentPosition\n        val duration = player.duration\n        val progress = (currentPosition * 100 / duration).toInt()\n\n\n        GlobalScope.launch(Dispatchers.IO) {\n                if (type == \"movie\") {\n                    if (progress in 3..96){\n                        watchHistoryDao.insert(\n                            ContinueWatching(\n                                progress = progress,\n                                imgLink = imgLink!!,\n                                tmdbID = id.toInt(),\n                                title = title,\n                                type = type!!,\n                                origin = mOrigin,\n                                year = year\n                            )\n                        )\n                    }\n                } else if (type == \"tvshow\") {\n                    watchHistoryDao.insert(\n                        ContinueWatching(\n                            progress = progress,\n                            imgLink = imgLink!!,\n                            tmdbID = id.toInt(),\n                            title = title,\n                            season = season,\n                            episode = episode,\n                            type = type!!\n                        )\n                    )\n                }\n                else {\n                    watchHistoryDao.insert(\n                        ContinueWatching(\n                            progress = progress,\n                            imgLink = imgLink!!,\n                            tmdbID = encodeStringToInt(title),\n                            title = title,\n                            season = season,\n                            episode = episode,\n                            type = type!!,\n                            animeEp = animeEpList\n                        )\n                    )\n                }\n\n            }\n\n        Log.i(\"Progress\", progress.toString())\n        player.playWhenReady = false\n        player.stop()\n        player.seekTo(0)\n\n        player.release() // or pause, depending on your requirements\n\n        lifecycleScope.launch (Dispatchers.IO) {\n            for (s in fileList) {\n                val path = Uri.parse(s).path\n                path?.let {\n                    File(path).delete()\n                }\n            }\n        }\n\n        Log.i(\"Finish\", \"Called finish() go back pressed\")\n        super.onDestroy()\n    }\n\n    override fun onDown(p0: MotionEvent): Boolean = false\n\n    override fun onShowPress(p0: MotionEvent) = Unit\n\n    override fun onSingleTapUp(p0: MotionEvent): Boolean = false\n    override fun onScroll(event: MotionEvent?, event1: MotionEvent, dX: Float, dY: Float): Boolean {\n        minSwipeY += dY\n\n        val sWidth = Resources.getSystem().displayMetrics.widthPixels\n\n        if(abs(dX)< abs(dY) && abs(minSwipeY) > 50){\n            if(event!!.x < sWidth/2){\n                brightnessLL.visibility = View.VISIBLE\n                volumeLL.visibility = View.GONE\n                val increase = dY > 0\n                val newValue = if(increase) brightness + 1 else brightness - 1\n\n                if(newValue in 0..30) brightness = newValue\n                brightnessSeek.progress = brightness\n                setScreenBrightness(brightness)\n            }\n            else{\n                brightnessLL.visibility = View.GONE\n                volumeLL.visibility = View.VISIBLE\n\n                val increase = dY > 0\n                val newValue = if(increase) volume + 5 else volume - 5\n                if(newValue in 0..maxVolume) volume = newValue\n                volumeSeek.progress = volume\n                audioManager!!.setStreamVolume(AudioManager.STREAM_MUSIC, volume, 0)\n            }\n            minSwipeY = 0f\n        }\n        return true\n    }\n\n    private fun setScreenBrightness(value: Int){\n        val d = 1.0f/30\n        val lp = this.window.attributes\n        lp.screenBrightness = d * value\n        this.window.attributes = lp\n    }\n\n    private fun episodeNext(){\n        if (episode < totalEpisode) {\n            mainPlayer.visibility = View.GONE\n            playerPause()\n            videoLoading.visibility = View.VISIBLE\n            episode += 1\n        } else {\n            if (season < totalSeasons) {\n                season += 1\n                playerPause()\n                lifecycleScope.launch(Dispatchers.IO) {\n                    totalEpisode = getSeasonEpisodes(id, season)\n                }\n                mainPlayer.visibility = View.GONE\n\n                videoLoading.visibility = View.VISIBLE\n                episode = 1\n            } else {\n                Toast.makeText(\n                    this@VideoPlayActivity,\n                    \"ShowFinished\",\n                    Toast.LENGTH_SHORT\n                ).show()\n                isShowFinished = true\n            }\n        }\n    }\n\n\n\n    private fun superUrlSelector() : List<Track>\n    {\n        var id = 0\n        var selectPos = 0\n        var tracks = urlMaps.map {\n            val selected = it.key == q\n\n            val resolution = Pair(\"\",it.key)\n\n            if(selected)selectPos = id\n            Track(id++,\"super\",resolution,selected)\n        }\n        val selectedQ = tracks.get(selectPos)\n        tracks = tracks - selectedQ\n        tracks = tracks + selectedQ\n        tracks = tracks.reversed()\n        println(tracks)\n        return tracks\n    }\n\n\n    @SuppressLint(\"WakelockTimeout\")\n    override fun onResume() {\n        super.onResume()\n            wakeLock.acquire()\n        if(audioManager == null) audioManager = getSystemService(Context.AUDIO_SERVICE) as AudioManager\n        audioManager!!.requestAudioFocus(this, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN)\n        if(brightness != 0) setScreenBrightness(brightness)\n    }\n\n\n\n    @Deprecated(\"Deprecated in Java\")\n    override fun onBackPressed() {\n        if(subSelectBg.visibility != View.VISIBLE && !qualitySelectBg.isVisible && !openSubll.isVisible)\n        super.onBackPressed()\n        else if (openSubll.isVisible){\n            openSubll.visibility = View.GONE\n            subSelectBg.visibility = View.VISIBLE\n        }\n        else{\n            subSelectBg.visibility = View.GONE\n            qualitySelectBg.visibility = View.GONE\n            mainPlayer.visibility = View.VISIBLE\n            playerPlay()\n        }\n    }\n\n    override fun onLongPress(p0: MotionEvent) = Unit\n    override fun onFling(p0: MotionEvent?, p1: MotionEvent, p2: Float, p3: Float): Boolean  = false\n    override fun onAudioFocusChange(focusChange: Int) {\n        if(focusChange <= 0) playerPause()\n    }\n}"
  },
  {
    "path": "app/src/main/java/com/demomiru/tokeiv2/anime/AnimeAdapter.kt",
    "content": "package com.demomiru.tokeiv2.anime\n\nimport android.content.Context\nimport android.view.LayoutInflater\nimport android.view.View\nimport android.view.ViewGroup\nimport android.widget.ImageView\nimport android.widget.TextView\nimport androidx.recyclerview.widget.DiffUtil\nimport androidx.recyclerview.widget.ListAdapter\nimport androidx.recyclerview.widget.RecyclerView\nimport coil.ImageLoader\nimport coil.disk.DiskCache\nimport coil.load\nimport coil.memory.MemoryCache\nimport com.demomiru.tokeiv2.R\nimport com.demomiru.tokeiv2.utils.GogoAnime\n\nclass AnimeAdapter(context: Context, private val onClick: (GogoAnime.AnimeSearchResponse) -> Unit): ListAdapter<GogoAnime.AnimeSearchResponse, AnimeAdapter.ViewHolder>(\n    DiffCallBack\n) {\n\n    private val imageLoader = ImageLoader.Builder(context)\n        .memoryCache { MemoryCache.Builder(context).maxSizePercent(0.25).build() }\n        .build()\n\n    class ViewHolder(view: View) : RecyclerView.ViewHolder(view){\n        val imageView : ImageView = view.findViewById(R.id.image_view)\n        val title : TextView = view.findViewById(R.id.title_text_view)\n        val dub: TextView = view.findViewById(R.id.tv_show_detail_tv)\n    }\n\n    object DiffCallBack: DiffUtil.ItemCallback<GogoAnime.AnimeSearchResponse>(){\n        override fun areItemsTheSame(\n            oldItem: GogoAnime.AnimeSearchResponse,\n            newItem: GogoAnime.AnimeSearchResponse\n        ): Boolean {\n            return oldItem === newItem\n        }\n\n        override fun areContentsTheSame(\n            oldItem: GogoAnime.AnimeSearchResponse,\n            newItem: GogoAnime.AnimeSearchResponse\n        ): Boolean {\n            return oldItem == newItem\n        }\n    }\n\n    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {\n        val view = LayoutInflater.from(parent.context).inflate(R.layout.item_view, parent,false)\n        return ViewHolder(view)\n\n    }\n\n    override fun onBindViewHolder(holder: ViewHolder, position: Int) {\n        val anime = getItem(position)\n        holder.imageView.load(anime.posterUrl,imageLoader)\n        holder.title.text = anime.name\n        if(anime.dub!=null){\n            holder.dub.visibility = if(anime.dub) View.VISIBLE else View.GONE\n        }\n        holder.itemView.setOnClickListener {\n            onClick(anime)\n        }\n    }\n}\n\nclass AnimeEpisodeAdapter(private val onClick: (GogoAnime.Episode,Int) -> Unit) : ListAdapter<GogoAnime.Episode, AnimeEpisodeAdapter.ViewHolder>(\n    DiffCallBack\n){\n\n    class ViewHolder(itemView : View) : RecyclerView.ViewHolder(itemView){\n        val episodeText : TextView = itemView.findViewById(R.id.episode_no_text)\n    }\n\n    object DiffCallBack : DiffUtil.ItemCallback<GogoAnime.Episode>() {\n        override fun areItemsTheSame(\n            oldItem: GogoAnime.Episode,\n            newItem: GogoAnime.Episode\n        ): Boolean {\n            return oldItem === newItem\n        }\n\n        override fun areContentsTheSame(\n            oldItem: GogoAnime.Episode,\n            newItem: GogoAnime.Episode\n        ): Boolean {\n            return oldItem == newItem\n        }\n    }\n\n    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {\n        val view = LayoutInflater.from(parent.context).inflate(R.layout.episode_item_viem,parent,false)\n        return ViewHolder(view)\n    }\n\n    override fun onBindViewHolder(holder: ViewHolder, position: Int) {\n        val episode = getItem(position)\n        holder.episodeText.text = episode.name\n        holder.itemView.setOnClickListener {\n            onClick(episode,position)\n        }\n    }\n\n\n}"
  },
  {
    "path": "app/src/main/java/com/demomiru/tokeiv2/anime/AnimeDetailsFragment.kt",
    "content": "package com.demomiru.tokeiv2.anime\n\nimport android.annotation.SuppressLint\nimport android.os.Bundle\nimport android.util.Log\nimport androidx.fragment.app.Fragment\nimport android.view.LayoutInflater\nimport android.view.View\nimport android.view.ViewGroup\nimport android.view.animation.AnimationUtils\nimport android.widget.Button\nimport android.widget.ImageView\nimport android.widget.LinearLayout\nimport android.widget.TextView\nimport android.widget.Toast\nimport androidx.constraintlayout.widget.ConstraintLayout\nimport androidx.fragment.app.activityViewModels\nimport androidx.fragment.app.viewModels\nimport androidx.lifecycle.Observer\nimport androidx.lifecycle.lifecycleScope\nimport androidx.navigation.fragment.findNavController\nimport androidx.navigation.fragment.navArgs\nimport androidx.recyclerview.widget.LinearLayoutManager\nimport coil.load\nimport com.demomiru.tokeiv2.R\nimport com.demomiru.tokeiv2.TVShowDetailsArgs\n\nimport com.demomiru.tokeiv2.databinding.FragmentAnimeDetailsBinding\nimport com.demomiru.tokeiv2.utils.ContinueWatchingViewModel\nimport com.demomiru.tokeiv2.utils.ContinueWatchingViewModel2\nimport com.demomiru.tokeiv2.utils.ContinueWatchingViewModelFactory\nimport com.demomiru.tokeiv2.utils.GogoAnime\nimport com.demomiru.tokeiv2.utils.encodeStringToInt\nimport com.demomiru.tokeiv2.utils.passData\nimport com.demomiru.tokeiv2.watching.ContinueWatching\nimport com.demomiru.tokeiv2.watching.ContinueWatchingDatabase\nimport com.google.common.collect.Iterators.getNext\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.launch\nimport kotlinx.coroutines.withContext\n\nclass AnimeDetailsFragment : Fragment() {\n    private val activityViewModel: ContinueWatchingViewModel2 by activityViewModels()\n    private lateinit var viewModelFactory: ContinueWatchingViewModelFactory\n    private val viewModel: ContinueWatchingViewModel by viewModels(\n        factoryProducer = {\n            viewModelFactory\n        }\n    )\n    private lateinit var episodeProgress : ContinueWatching\n    private val database by lazy { ContinueWatchingDatabase.getInstance(requireContext()) }\n    private val watchHistoryDao by lazy { database.watchDao() }\n    private val args : AnimeDetailsFragmentArgs by navArgs()\n\n    private lateinit var binding: FragmentAnimeDetailsBinding\n    private lateinit var sequelBtn : Button\n    private lateinit var prequelBtn : Button\n    private val gogoSrc = GogoAnime()\n    @SuppressLint(\"SetTextI18n\")\n    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {\n\n        super.onViewCreated(view, savedInstanceState)\n        val viewStateObserver = Observer<ContinueWatching?> {watchFrom ->\n            val continueButton =  binding.continueButton\n            if (watchFrom != null) {\n                episodeProgress = watchFrom\n                continueButton.visibility = View.VISIBLE\n                continueButton.text =\n                    \"Continue Watching E${watchFrom.episode+1}\"\n            }\n\n            continueButton.setOnClickListener {\n                startActivity(passData(watchFrom!!, requireContext()))\n            }\n        }\n        viewModel.watchFrom.observe(viewLifecycleOwner,viewStateObserver)\n    }\n\n\n    override fun onCreateView(\n        inflater: LayoutInflater, container: ViewGroup?,\n        savedInstanceState: Bundle?\n    ): View {\n        // Inflate the layout for this fragment\n        binding = FragmentAnimeDetailsBinding.inflate(inflater, container, false)\n        val animeInfo = AnimeInfo(requireContext())\n        sequelBtn = binding.sequelBtn\n        prequelBtn = binding.prequelBtn\n\n        val title = args.title\n        val url = args.url\n        viewModelFactory = ContinueWatchingViewModelFactory(watchHistoryDao, encodeStringToInt(title))\n        val progressBar = binding.progressCircular\n\n        val episodesRc = binding.episodeDisplayRc\n        episodesRc.layoutManager = LinearLayoutManager(requireContext())\n\n\n        val titleTv =binding.titleShow\n        val backdropImg =binding.showBackdrop\n        val posterImg= binding.showPoster\n        val overview = binding.overviewText\n\n        overview.setAnimationDuration(750L)\n        binding.expandText.setOnClickListener {\n            if(overview.isExpanded){\n                overview.collapse()\n                binding.expandText.load(R.drawable.baseline_keyboard_arrow_down_24)\n            }else{\n                overview.expand()\n                binding.expandText.load(R.drawable.baseline_keyboard_arrow_up_24)\n            }\n        }\n\n\n        lifecycleScope.launch (Dispatchers.IO) {\n            val details = animeInfo.getAnimeDetails(title)\n            Log.i(\"anime url\",url)\n            val gogoDetails: GogoAnime.AnimeDetails = try{gogoSrc.load(url)}catch (e:Exception){\n                println(e.printStackTrace())\n                GogoAnime.AnimeDetails()\n            }\n\n            withContext(Dispatchers.Main){\n                println(details.related_anime)\n                val sequel = sequelExist(details.related_anime)\n                if(sequel.second){\n                    sequelBtn.visibility = View.VISIBLE\n                    sequelBtn.setOnClickListener {\n                        if(sequel.first?.node?.title == null) Toast.makeText(requireContext(),\"No sequel available\",Toast.LENGTH_SHORT).show()\n                        else getNext(sequel.first?.node?.title!!)\n                    }\n                }\n\n                val prequel = prequelExist(details.related_anime)\n                if(prequel.second) {\n                    prequelBtn.visibility = View.VISIBLE\n                    prequelBtn.setOnClickListener {\n\n                        if(prequel.first?.node?.title == null) Toast.makeText(requireContext(),\"No prequel available\",Toast.LENGTH_SHORT).show()\n                        else getNext(prequel.first?.node?.title!!)\n                    }\n\n                }\n\n               binding.progressLayout.visibility = View.GONE\n                posterImg.load(gogoDetails.poster)\n                backdropImg.load(gogoDetails.poster)\n                overview.text = details.synopsis.replace(\"[Written by MAL Rewrite]\",\"\")\n                titleTv.text = gogoDetails.title\n                val episodes = gogoDetails.episodes\n\n                val adapter = AnimeEpisodeAdapter{ _, epPos->\n                    startActivity(\n                        passData(\n                           gogoDetails,\n                            requireContext(),\n                            encodeStringToInt(gogoDetails.title?:\"\").toString(),\n                            epPos,\n                            gogoDetails.title?:\"\"\n                        )\n                    )\n                }\n                episodesRc.adapter = adapter\n                adapter.submitList(episodes)\n                val context = episodesRc.context\n                val controller = AnimationUtils.loadLayoutAnimation(\n                    context,\n                    R.anim.layout_animation\n                )\n                episodesRc.layoutAnimation = controller\n                adapter.notifyDataSetChanged()\n                episodesRc.scheduleLayoutAnimation()\n                binding.episodesText.visibility =\n                    View.VISIBLE\n            }\n        }\n        return binding.root\n    }\n\n    private fun sequelExist(related: ArrayList<AnimeInfo.Anime>): Pair<AnimeInfo.Anime?, Boolean>\n    {\n        related.forEach {\n            if (it.relation_type?.contains(\"sequel\") == true){\n                return Pair(it,true)\n            }\n        }\n        return Pair(null,false)\n    }\n\n    private fun prequelExist(related: ArrayList<AnimeInfo.Anime>): Pair<AnimeInfo.Anime?, Boolean>\n    {\n        related.forEach {\n            if (it.relation_type?.contains(\"prequel\") == true){\n                return Pair(it,true)\n            }\n        }\n        return Pair(null,false)\n    }\n\n    private fun getNext(title: String){\n        lifecycleScope.launch {\n            val animeList = gogoSrc.search(title)\n            println(animeList)\n            withContext(Dispatchers.Main){\n                val anime = animeList[0]\n                val action = AnimeDetailsFragmentDirections.actionAnimeDetailsFragmentSelf(anime.name,anime.url)\n                findNavController().navigate(action)\n            }\n        }\n    }\n\n    override fun onResume() {\n        activityViewModel.currentFragment.value = R.id.animeDetailsFragment\n        super.onResume()\n    }\n\n\n\n}"
  },
  {
    "path": "app/src/main/java/com/demomiru/tokeiv2/anime/AnimeFragment.kt",
    "content": "package com.demomiru.tokeiv2.anime\n\nimport android.os.Bundle\nimport android.view.LayoutInflater\nimport android.view.View\nimport android.view.ViewGroup\nimport android.widget.Toast\nimport androidx.fragment.app.Fragment\nimport androidx.fragment.app.activityViewModels\nimport androidx.fragment.app.viewModels\nimport androidx.lifecycle.lifecycleScope\nimport androidx.navigation.fragment.findNavController\nimport androidx.recyclerview.widget.LinearLayoutManager\nimport androidx.recyclerview.widget.RecyclerView\nimport com.demomiru.tokeiv2.R\nimport com.demomiru.tokeiv2.databinding.FragmentAnimeBinding\nimport com.demomiru.tokeiv2.utils.ContinueWatchingViewModel2\nimport com.demomiru.tokeiv2.utils.encodeStringToInt\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.launch\nimport kotlinx.coroutines.withContext\n\nclass AnimeFragment : Fragment() {\n    private val activityViewModel : ContinueWatchingViewModel2 by activityViewModels()\n    private lateinit var winterAnimeRc: RecyclerView\n    private lateinit var fallAnimeRc: RecyclerView\n    private lateinit var springAnimeRc : RecyclerView\n    private lateinit var summerAnimeRc : RecyclerView\n    private lateinit var binding: FragmentAnimeBinding\n\n\n    override fun onCreateView(\n        inflater: LayoutInflater, container: ViewGroup?,\n        savedInstanceState: Bundle?\n    ): View {\n\n        // Inflate the layout for this fragment\n        binding = FragmentAnimeBinding.inflate(inflater, container, false)\n        val animeInfo = AnimeInfo(requireContext())\n\n        winterAnimeRc = binding.winterAnimeRc\n        fallAnimeRc = binding.fallAnimeRc\n        springAnimeRc = binding.springAnimeRc\n        summerAnimeRc = binding.summerAnimeRc\n\n        winterAnimeRc.layoutManager = LinearLayoutManager(requireContext(),\n            LinearLayoutManager.HORIZONTAL,false)\n        fallAnimeRc.layoutManager = LinearLayoutManager(requireContext(),\n            LinearLayoutManager.HORIZONTAL,false)\n        springAnimeRc.layoutManager = LinearLayoutManager(requireContext(),\n            LinearLayoutManager.HORIZONTAL,false)\n        summerAnimeRc.layoutManager = LinearLayoutManager(requireContext(),\n            LinearLayoutManager.HORIZONTAL,false)\n\n//        val action = AnimeFragmentDirections.actionAnimeFragmentToTVShowDetails(\n//            encodeStringToInt(it.name).toString(), title = \"\",animeUrl = it.url)\n//        findNavController().navigate(action)\n\n\n        val wAdapter = AnimeAdapter(requireContext()){\n            val action = AnimeFragmentDirections.actionAnimeFragmentToAnimeDetailsFragment(\n                it.name,it.url)\n            findNavController().navigate(action)\n        }\n        winterAnimeRc.adapter = wAdapter\n\n        val fAdapter = AnimeAdapter(requireContext()){\n            val action = AnimeFragmentDirections.actionAnimeFragmentToAnimeDetailsFragment(\n                it.name,it.url)\n            findNavController().navigate(action)\n        }\n        fallAnimeRc.adapter = fAdapter\n\n        val spAdapter = AnimeAdapter(requireContext()){\n            val action = AnimeFragmentDirections.actionAnimeFragmentToAnimeDetailsFragment(\n                it.name,it.url)\n            findNavController().navigate(action)\n        }\n       springAnimeRc.adapter = spAdapter\n\n        val suAdapter = AnimeAdapter(requireContext()){\n            val action = AnimeFragmentDirections.actionAnimeFragmentToAnimeDetailsFragment(\n                it.name,it.url)\n            findNavController().navigate(action)\n        }\n        summerAnimeRc.adapter = suAdapter\n        try {\n\n                activityViewModel.getAnime(requireContext())\n\n\n                    activityViewModel.winterList.observe(viewLifecycleOwner){winterList->\n                        wAdapter.submitList(winterList)\n                        if(winterList.isNotEmpty()){\n                            binding.loadingAnime.visibility = View.GONE\n                            binding.winterText.visibility = View.VISIBLE\n                            binding.fallText.visibility = View.VISIBLE\n                            binding.springText.visibility = View.VISIBLE\n                            binding.summerText.visibility = View.VISIBLE\n                        }\n                    }\n                    activityViewModel.fallList.observe(viewLifecycleOwner){fallList->\n                        fAdapter.submitList(fallList)\n                    }\n\n                    activityViewModel.springList.observe(viewLifecycleOwner){springList->\n                        spAdapter.submitList(springList)\n                    }\n\n                    activityViewModel.summerList.observe(viewLifecycleOwner){summerList->\n                        suAdapter.submitList(summerList)\n                    }\n\n        }catch (e:Exception){\n            e.printStackTrace()\n        }\n\n        return binding.root\n    }\n\n    override fun onResume() {\n        activityViewModel.currentFragment.value = R.id.animeFragment\n        super.onResume()\n    }\n\n\n\n}"
  },
  {
    "path": "app/src/main/java/com/demomiru/tokeiv2/anime/AnimeInfo.kt",
    "content": "package com.demomiru.tokeiv2.anime\n\nimport android.content.Context\nimport com.demomiru.tokeiv2.BuildConfig\nimport com.demomiru.tokeiv2.utils.GogoAnime\nimport com.google.gson.Gson\n\nimport com.lagradost.nicehttp.Requests\nimport okhttp3.Cache\nimport okhttp3.CacheControl\nimport okhttp3.Interceptor\nimport okhttp3.OkHttpClient\nimport java.io.File\nimport java.util.concurrent.TimeUnit\n\nclass AnimeInfo(context: Context) {\n    private val cache = Cache(\n        File(context.cacheDir, \"http_cache\"),\n        50L * 1024L * 1024L // 50 MiB\n    )\n\n    private val okHttpClient = OkHttpClient.Builder()\n        .cache(cache)\n        .build()\n\n    private val app = Requests(okHttpClient)\n    private val gson = Gson()\n    private val headers = mapOf(\"X-MAL-CLIENT-ID\" to BuildConfig.MAL_API)\n    private val proxy = BuildConfig.PROXY_URL\n    suspend fun getSeasonalAnimeInfo(choice: Int) : List<GogoAnime.AnimeSearchResponse>{\n        return when (choice) {\n            1 -> fallAnimeInfo()\n            2 -> winterAnimeInfo()\n            3 -> springAnimeInfo()\n            else -> summerAnimeInfo()\n        }\n    }\n\n    suspend fun fallAnimeInfo() : List<GogoAnime.AnimeSearchResponse>{\n        val fall = app.get(\"${proxy}https://gogotaku.info/season/fall-2023-anime\", cacheTime = 1, cacheUnit = TimeUnit.DAYS).document\n            .select(\"div.main_body div.page_content ul.items.full li\")\n        val listFall: MutableList<GogoAnime.AnimeSearchResponse> = mutableListOf()\n        for (li in fall){\n            val imgLink = li.select(\"div.img a img.lazy\").attr(\"data-original\")\n            val title = li.select(\"div.name a\").attr(\"title\")\n            val gogoLink = li.select(\"div.name a\").attr(\"href\")\n            listFall.add(GogoAnime.AnimeSearchResponse(name = title, posterUrl = imgLink,url = \"https://gogoanimehd.io$gogoLink\", apiName = \"\"))\n//            println(\"Img: $imgLink\")\n//            println(\"Title: $title\")\n//            println(\"animeUrl: https://gogoanimehd.io$gogoLink\")\n        }\n        return listFall.toList()\n    }\n\n    suspend fun winterAnimeInfo() : List<GogoAnime.AnimeSearchResponse>{\n        val winter = app.get(\"${proxy}https://gogotaku.info/season/winter-2023-anime\", cacheTime = 1, cacheUnit = TimeUnit.DAYS).document\n            .select(\"div.main_body div.page_content ul.items.full li\")\n        val listWinter: MutableList<GogoAnime.AnimeSearchResponse> = mutableListOf()\n        for (li in winter){\n            val imgLink = li.select(\"div.img a img.lazy\").attr(\"data-original\")\n            val title = li.select(\"div.name a\").attr(\"title\")\n            val gogoLink = li.select(\"div.name a\").attr(\"href\")\n            listWinter.add(GogoAnime.AnimeSearchResponse(name = title, posterUrl = imgLink,url = \"https://gogoanimehd.io$gogoLink\", apiName = \"\"))\n//            println(\"Img: $imgLink\")\n//            println(\"Title: $title\")\n//            println(\"animeUrl: https://gogoanimehd.io$gogoLink\")\n        }\n        return listWinter.toList()\n    }\n\n    suspend fun springAnimeInfo() : List<GogoAnime.AnimeSearchResponse>{\n        val spring = app.get(\"${proxy}https://gogotaku.info/season/spring-2023-anime\", cacheTime = 1, cacheUnit = TimeUnit.DAYS).document\n            .select(\"div.main_body div.page_content ul.items.full li\")\n        val listSpring: MutableList<GogoAnime.AnimeSearchResponse> = mutableListOf()\n        for (li in spring){\n            val imgLink = li.select(\"div.img a img.lazy\").attr(\"data-original\")\n            val title = li.select(\"div.name a\").attr(\"title\")\n            val gogoLink = li.select(\"div.name a\").attr(\"href\")\n            listSpring.add(GogoAnime.AnimeSearchResponse(name = title, posterUrl = imgLink,url = \"https://gogoanimehd.io$gogoLink\", apiName = \"\"))\n//            println(\"Img: $imgLink\")\n//            println(\"Title: $title\")\n//            println(\"animeUrl: https://gogoanimehd.io$gogoLink\")\n        }\n        return listSpring.toList()\n    }\n\n    suspend fun summerAnimeInfo() : List<GogoAnime.AnimeSearchResponse>{\n        val summer = app.get(\"${proxy}https://gogotaku.info/season/summer-2023-anime\", cacheTime = 1, cacheUnit = TimeUnit.DAYS).document\n            .select(\"div.main_body div.page_content ul.items.full li\")\n        val listSummer: MutableList<GogoAnime.AnimeSearchResponse> = mutableListOf()\n        for (li in summer){\n            val imgLink = li.select(\"div.img a img.lazy\").attr(\"data-original\")\n            val title = li.select(\"div.name a\").attr(\"title\")\n            val gogoLink = li.select(\"div.name a\").attr(\"href\")\n            listSummer.add(GogoAnime.AnimeSearchResponse(name = title, posterUrl = imgLink,url = \"https://gogoanimehd.io$gogoLink\", apiName = \"\"))\n//            println(\"Img: $imgLink\")\n//            println(\"Title: $title\")\n//            println(\"animeUrl: https://gogoanimehd.io$gogoLink\")\n        }\n        return listSummer.toList()\n    }\n\n    suspend fun getAnimeDetails(query:String): Related{\n\n//        val search = app.get(\"https://api.consumet.org/meta/anilist/$query?page=1\").toString()\n        val search = app.get(\"https://myanimelist.net/search/all?cat=all&q=$query\").document.select(\"div.title a.hoverinfo_trigger\")\n//        val search = app.get(\"https://api.myanimelist.net/v2/anime?q=$query&limit=1\",\n//            headers = headers).toString()\n//        val anime = gson.fromJson(search,Data::class.java)\n\n        val id = search[0].attr(\"href\").substringAfter(\"anime/\").substringBefore(\"/\")\n        println(id)\n\n        val animeDetails = app.get(\"https://api.myanimelist.net/v2/anime/${id}?fields=id,title,main_picture,alternative_titles,start_date,end_date,synopsis,mean,rank,popularity,num_list_users,num_scoring_users,nsfw,created_at,updated_at,media_type,status,genres,my_list_status,num_episodes,start_season,broadcast,source,average_episode_duration,rating,pictures,background,related_anime,related_manga,recommendations,studios,statistics\",\n            headers = headers).toString()\n\n\n        return gson.fromJson(animeDetails,Related::class.java)\n\n    }\n\n\n\n    data class Related(\n        val main_picture: MainPic,\n        val related_anime: ArrayList<Anime>,\n        val synopsis: String\n    )\n    data class MainPic(\n        val medium: String,\n        val large : String\n    )\n    data class Data(\n        val results: ArrayList<AnimeAni>\n    )\n\n    data class AnimeAni(\n        val id: Int,\n        val malId: Int,\n    )\n    data class Anime(\n        val node: AnimeDetails,\n        val relation_type : String? = null\n    )\n    data class AnimeDetails(\n        val id: Int,\n        val title: String,\n    )\n\n}"
  },
  {
    "path": "app/src/main/java/com/demomiru/tokeiv2/extractors/CorrectTitleSelection.kt",
    "content": "package com.demomiru.tokeiv2.extractors\n\nimport android.annotation.SuppressLint\nimport android.app.Dialog\nimport android.content.res.Resources\nimport android.os.Bundle\nimport android.view.LayoutInflater\nimport android.view.View\nimport android.view.ViewGroup\nimport android.view.WindowManager\nimport android.widget.FrameLayout\nimport android.widget.ImageView\nimport android.widget.TextView\nimport androidx.recyclerview.widget.DiffUtil\nimport androidx.recyclerview.widget.GridLayoutManager\nimport androidx.recyclerview.widget.ListAdapter\nimport androidx.recyclerview.widget.RecyclerView\nimport coil.load\nimport com.demomiru.tokeiv2.Movie\nimport com.demomiru.tokeiv2.MovieAdapter\nimport com.demomiru.tokeiv2.R\nimport com.demomiru.tokeiv2.utils.yearExtract\nimport com.google.android.material.bottomsheet.BottomSheetBehavior\nimport com.google.android.material.bottomsheet.BottomSheetDialog\nimport com.google.android.material.bottomsheet.BottomSheetDialogFragment\n\n// TODO: Rename parameter arguments, choose names that match\n// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER\nprivate const val ARG_PARAM1 = \"param1\"\nprivate const val ARG_PARAM2 = \"param2\"\nclass CorrectTitleSelection: BottomSheetDialogFragment() {\n    // TODO: Rename and change types of parameters\n    private var param1: String? = null\n    private var param2: String? = null\n\n\n\n    override fun onCreate(savedInstanceState: Bundle?) {\n        super.onCreate(savedInstanceState)\n        arguments?.let {\n            param1 = it.getString(ARG_PARAM1)\n            param2 = it.getString(ARG_PARAM2)\n        }\n    }\n\n    override fun onCreateView(\n        inflater: LayoutInflater, container: ViewGroup?,\n        savedInstanceState: Bundle?\n    ): View? {\n        // Inflate the layout for this fragment\n\n        //Create a Recycler View with Grid Layout to show prMovies results\n\n        val view =  inflater.inflate(R.layout.fragment_correct_title_selection, container, false)\n\n        val width = Resources.getSystem().displayMetrics.widthPixels\n        val dpi = Resources.getSystem().displayMetrics.densityDpi\n        val grid = (width*160)/(165*dpi)\n        val rcadapter = ResultsAdapter{\n\n        }\n//        rc.apply {\n//            layoutManager = GridLayoutManager(requireContext(), grid)\n//            adapter = rcadapter\n//        }\n        return view\n    }\n\n    companion object {\n        /**\n         * Use this factory method to create a new instance of\n         * this fragment using the provided parameters.\n         *\n         * @param param1 Parameter 1.\n         * @param param2 Parameter 2.\n         * @return A new instance of fragment CorrectTitleSelection.\n         */\n        // TODO: Rename and change types and number of parameters\n        @JvmStatic\n        fun newInstance(param1: String, param2: String) =\n            CorrectTitleSelection().apply {\n                arguments = Bundle().apply {\n                    putString(ARG_PARAM1, param1)\n                    putString(ARG_PARAM2, param2)\n                }\n            }\n    }\n\n    override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {\n        val dialog = super.onCreateDialog(savedInstanceState) as BottomSheetDialog\n\n        dialog.setOnShowListener { dialogInterface ->\n            val bottomSheetDialog = dialogInterface as BottomSheetDialog\n            val bottomSheet = bottomSheetDialog.findViewById<View>(com.google.android.material.R.id.design_bottom_sheet) as FrameLayout?\n            bottomSheet?.let {\n                val behavior = BottomSheetBehavior.from(it)\n                behavior.state = BottomSheetBehavior.STATE_EXPANDED\n                behavior.peekHeight = 0\n            }\n        }\n        return dialog\n    }\n    override fun onStart() {\n        super.onStart()\n        val bottomSheet = dialog?.findViewById<View>(com.google.android.material.R.id.design_bottom_sheet) as FrameLayout\n        val layoutParams = bottomSheet.layoutParams\n        layoutParams.height = WindowManager.LayoutParams.MATCH_PARENT\n        bottomSheet.layoutParams = layoutParams\n    }\n}\n\nclass ResultsAdapter(private val clickHandler : (SearchResponse) -> Unit) :\n    ListAdapter<SearchResponse, ResultsAdapter.ViewHolder>(differCallback) {\n\n    class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {\n        val imageView: ImageView = itemView.findViewById(R.id.image_view)\n        val titleTextView: TextView = itemView.findViewById(R.id.title_text_view)\n    }\n\n    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {\n        val view = LayoutInflater.from(parent.context).inflate(R.layout.item_view,parent,false)\n        return ViewHolder(view)\n    }\n\n    companion object {\n        val differCallback = object : DiffUtil.ItemCallback<SearchResponse>() {\n            override fun areItemsTheSame(oldItem: SearchResponse, newItem: SearchResponse): Boolean {\n                return oldItem === newItem\n            }\n\n            override fun areContentsTheSame(oldItem: SearchResponse, newItem: SearchResponse): Boolean {\n                return oldItem == newItem\n            }\n        }\n    }\n\n\n\n    @SuppressLint(\"SetTextI18n\")\n    override fun onBindViewHolder(holder: ViewHolder, position: Int) {\n        val movie = getItem(position)\n        holder.titleTextView.text = movie.title\n        holder.imageView.load(movie.image)\n        holder.itemView.setOnClickListener {\n            clickHandler(movie)\n        }\n    }\n\n}\n\n"
  },
  {
    "path": "app/src/main/java/com/demomiru/tokeiv2/extractors/PrMovies.kt",
    "content": "package com.demomiru.tokeiv2.extractors\n\nimport android.os.Bundle\nimport androidx.appcompat.app.AppCompatActivity\nimport androidx.lifecycle.lifecycleScope\nimport com.demomiru.tokeiv2.R\nimport com.google.gson.Gson\nimport com.lagradost.nicehttp.Requests\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.launch\nimport java.lang.Exception\n\nclass PrMovies {\n    private val app = Requests()\n\n    private var mainUrl = \"https://prmovies.best\"\n    private var name = \"Prmovies\"\n\n\n\n    private val gson = Gson()\n    private suspend fun search(query: String): List<SearchResponse>{\n        val document = app.get(\"$mainUrl/?s=$query\").document\n\n        val search = document.select(\"div.ml-item\")\n        val searchItems = search.map{\n            val ty = it.selectFirst(\".qtip-title\")?.text()\n            SearchResponse(\n                it.selectFirst(\"a\")?.attr(\"href\"),\n                ty,\n                ty?.substringAfter(\"(\")?.substringBefore(\")\"),\n                it.selectFirst(\"img\")?.attr(\"data-original\")\n            )\n        }\n        return searchItems\n    }\n\n\n    suspend fun loadLinks(\n        data:String\n    ): PrFile {\n        val vidLink =  app.get(data).document.select(\"div.movieplay iframe\").map { it.attr(\"src\") }\n            .map { source ->\n                when {\n                    source.startsWith(\"https://minoplres.xyz/\") -> app.get(\n                        source,\n                        referer = \"$mainUrl/\"\n                    ).toString().substringAfter(\"sources: [\").substringBefore(\"]\")\n\n                    else -> \"\"\n                }\n\n            }\n        return gson.fromJson(vidLink[0],PrFile::class.java)\n\n    }\n\n    suspend fun getPrMovieLink(query: String): List<SearchResponse>{\n//        val query = \"ImMATURE\"\n        return try {\n            val searchItems = search(query)\n            if(searchItems.size > 5)\n                searchItems.dropLast(searchItems.size - 5)\n            else\n                searchItems\n        }catch (e: Exception){\n            listOf()\n        }\n        }\n    }\n\ndata class SearchResponse(\n    val link: String? = null,\n    val title: String? = null,\n    val year: String? = null,\n    val image: String? = null,\n)\n\n\ndata class PrFile (val file: String?)"
  },
  {
    "path": "app/src/main/java/com/demomiru/tokeiv2/extractors/Vidplay.kt",
    "content": "package com.demomiru.tokeiv2.extractors\n\nimport androidx.lifecycle.lifecycleScope\nimport com.demomiru.tokeiv2.utils.Video3\nimport com.demomiru.tokeiv2.utils.getBaseClient\nimport com.google.gson.Gson\nimport com.google.gson.reflect.TypeToken\nimport com.lagradost.nicehttp.Requests\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.launch\nimport kotlinx.coroutines.withContext\nimport org.json.JSONArray\nimport java.net.URLDecoder\nimport java.net.URLEncoder\nimport java.nio.charset.StandardCharsets\nimport java.util.Base64\nimport javax.crypto.Cipher\nimport javax.crypto.spec.SecretKeySpec\n\nprivate val app = Requests(baseClient = getBaseClient())\nprivate val gson = Gson()\n\n\nclass VidplayExtractor {\n\n    private val url = \"https://vidplay.site\"\n\n    private val referer = \"https://vidplay.site/\"\n    private suspend fun getKeys(): List<String> {\n        val url = \"https://raw.githubusercontent.com/Claudemirovsky/worstsource-keys/keys/keys.json\"\n        val res = app.get(url).toString()\n        return gson.fromJson(res, object : TypeToken<List<String>>() {}.type)\n    }\n\n    private suspend fun getEncodedId(sourceUrl: String): String {\n        val id = sourceUrl.split(\"/e/\")[1].split(\"?\")[0]\n        val keyList = getKeys()\n\n        val c1 = Cipher.getInstance(\"RC4\")\n        c1.init(Cipher.ENCRYPT_MODE, SecretKeySpec(keyList[0].toByteArray(), \"RC4\"))\n\n        val c2 = Cipher.getInstance(\"RC4\")\n        c2.init(Cipher.ENCRYPT_MODE, SecretKeySpec(keyList[1].toByteArray(), \"RC4\"))\n\n        var input = id.toByteArray()\n        input = c1.doFinal(input)\n        input = c2.doFinal(input)\n\n        return Base64.getEncoder().encodeToString(input).replace(\"/\", \"_\")\n    }\n\n    private suspend fun getFuTokenKey(sourceUrl: String): String {\n        val id = getEncodedId(sourceUrl)\n        val res = app.get(\"${url}/futoken\", referer = withContext(Dispatchers.IO) {\n            URLEncoder.encode(sourceUrl, \"UTF-8\")\n        }).toString()\n        val fuKey = Regex(\"var\\\\s+k\\\\s*=\\\\s*'([^']+)'\").find(res)?.groupValues?.get(1) ?: \"\"\n        val a = mutableListOf<Int>()\n        for (i in id.indices) {\n            a.add(fuKey[i % fuKey.length].toInt() + id[i].toInt())\n        }\n        return \"${fuKey},${a.joinToString(\",\")}\"\n    }\n\n    private suspend fun getFileUrl(sourceUrl: String): String {\n        val futoken = getFuTokenKey(sourceUrl)\n        val url = \"${this.url}/mediainfo/$futoken?${sourceUrl.split(\"?\")[1]}\"\n        return url\n    }\n\n    suspend fun extractUrl(url: String): String {\n        val fileUrl = getFileUrl(\"${url}&autostart=true\")\n        println(fileUrl)\n        val res = app.get(fileUrl, referer = url).toString()\n        val sourceRes = gson.fromJson(res, VidPlaySource::class.java)\n        return sourceRes.result.sources[0].file\n\n    }\n}\n\ndata class VidPlaySource(\n    val status: Int,\n    val result: Src,\n){\n    data class Src(\n        val sources: ArrayList<File>\n    ){\n        data class File(\n            val file:String,\n        )\n    }\n}\n\ndata class Sources(\n    val status: Int,\n    val result: ArrayList<Source>,\n){\n    data class Source(\n        val id : String,\n        val title: String,\n    )\n}\n\ndata class SourceObject(\n    val status: Int,\n    val result: Url,\n){\n    data class Url(\n        val url: String,\n    )\n}\n\ndata class VidPlaySub(\n    val file: String,\n    val label: String,\n)\n\n\nclass Vidplay {\n\n\n\n    private val url = \"https://vidsrc.to/embed/\"\n\n    private val mainUrl = \"https://vidsrc.to/\"\n\n//    private vidStreamExtractor = new VidstreamExtractor();\n//\n//    private fileMoonExtractor = new FileMoonExtractor();\n//\n    private val vidPlayExtractor = VidplayExtractor()\n\n    private val key = \"8z5Ag5wgagfsOuhz\"\n\n    private fun decodeBase64UrlSafe(str: String): ByteArray {\n        val standardizedInput = str.replace('_', '/').replace('-', '+')\n        return Base64.getDecoder().decode(standardizedInput)\n    }\n\n    private fun decode(str: ByteArray): ByteArray {\n        val keyBytes = key.toByteArray()\n\n        var j = 0\n        val s = ByteArray(256) { it.toByte() }\n\n        for (i in s.indices) {\n            j = (j + s[i].toInt() + keyBytes[i % keyBytes.size].toInt()) and 0xff\n            val temp = s[i]\n            s[i] = s[j]\n            s[j] = temp\n        }\n\n        val decoded = ByteArray(str.size)\n        var i = 0\n        var k = 0\n        for (index in str.indices) {\n            i = (i + 1) and 0xff\n            k = (k + s[i].toInt()) and 0xff\n            val temp = s[i]\n            s[i] = s[k]\n            s[k] = temp\n            val t = (s[i].toInt() + s[k].toInt()) and 0xff\n            decoded[index] = (str[index].toInt() xor s[t].toInt()).toByte()\n        }\n\n        return decoded\n    }\n\n    private fun decryptSourceUrl(sourceUrl: String): String {\n        val encoded = decodeBase64UrlSafe(sourceUrl)\n        val decoded = decode(encoded)\n        val decodedText = String(decoded, StandardCharsets.UTF_8)\n        return URLDecoder.decode(URLDecoder.decode(decodedText, \"UTF-8\"), \"UTF-8\")\n    }\n\n    suspend fun getVidPlayUrl(isMovie: Boolean, season: Int, episode: Int, id: String): Pair<String?,String?>{\n        val mainUrl = if(isMovie)\n            \"${url}movie/${id}\"\n        else\n            \"${url}tv/${id}/${season}/${episode}\"\n        val res = app.get(mainUrl).document\n//            println(res)\n        val dataId = res.selectFirst(\"ul.episodes > li > a\")?.attr(\"data-id\")\n            ?: throw Exception(\"Data ID not found\")\n        println(dataId)\n        val sourceRes = app.get(\n//                \"${url}ajax/embed/episode/${dataId}/sources\",\n            \"https://vidsrc.to/ajax/embed/episode/$dataId/sources\",\n            headers =  mapOf(\n                \"X-Requested-With\" to\n                        \"XMLHttpRequest\"\n            ),\n            referer = mainUrl\n        ).toString()\n        val sources = gson.fromJson(sourceRes,Sources::class.java)\n        if(sources.status != 200) throw Exception(\"No sources found\")\n        var videoUrl : String? = null\n        val sourceUrls = sources.result.forEach {\n            if(it.title == \"Vidplay\"){\n                val encryptedUrl = app.get(\n                    \"https://vidsrc.to/ajax/embed/source/${it.id}\",\n                ).toString()\n                val url = gson.fromJson(encryptedUrl,SourceObject::class.java).result.url\n                println(url)\n                val decryptedUrl = decryptSourceUrl(url)\n                videoUrl = vidPlayExtractor.extractUrl(decryptedUrl)\n            }\n        }\n        val subtitlesRes = app.get(\n            \"https://vidsrc.to/ajax/embed/episode/${dataId}/subtitles\",\n        ).toString()\n        var subs : String? = null\n        val subtitles = mutableMapOf<String,String>()\n        val subJSONArray = JSONArray(subtitlesRes)\n        for( i in 0 until subJSONArray.length())\n        {\n            val subObject = subJSONArray.getJSONObject(i).toString()\n            val sub = gson.fromJson(subObject,VidPlaySub::class.java)\n            subtitles[sub.label] = sub.file\n        }\n\n        subs = gson.toJson(subtitles)\n        if (subs.length <3)subs = null\n        return Pair(videoUrl,subs)\n\n    }\n\n}\n\n"
  },
  {
    "path": "app/src/main/java/com/demomiru/tokeiv2/history/QueryRepository.kt",
    "content": "package com.demomiru.tokeiv2.history\n\nimport android.view.View\nimport android.widget.Toast\nimport androidx.annotation.WorkerThread\nimport androidx.core.content.ContentProviderCompat.requireContext\nimport androidx.core.content.ContextCompat.startActivity\nimport androidx.lifecycle.LiveData\nimport androidx.lifecycle.MutableLiveData\nimport com.demomiru.tokeiv2.BuildConfig\nimport com.demomiru.tokeiv2.Movie\nimport com.demomiru.tokeiv2.MovieAdapter\nimport com.demomiru.tokeiv2.MovieService\nimport com.demomiru.tokeiv2.TMDBService\nimport com.demomiru.tokeiv2.TVShowResponse\nimport com.demomiru.tokeiv2.TVshow\nimport com.demomiru.tokeiv2.history.SearchHistory\nimport com.demomiru.tokeiv2.history.SearchHistoryDao\nimport com.demomiru.tokeiv2.utils.addRecyclerAnimation\nimport com.demomiru.tokeiv2.utils.passData\nimport com.demomiru.tokeiv2.utils.retrofitBuilder\nimport com.google.gson.Gson\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.flow.Flow\nimport kotlinx.coroutines.withContext\nimport okhttp3.OkHttpClient\nimport okhttp3.Request\nimport retrofit2.create\n\nclass QueryRepository(private val queryDao: SearchHistoryDao) {\n\n    private val _allQueries = MutableLiveData<List<SearchHistory>>()\n    val allQueries : LiveData<List<SearchHistory>> = _allQueries\n\n\n//    fun loadData(){\n//        _allQueries.postValue(queryDao.getSearchHistory())\n//    }\n    private val retrofit = retrofitBuilder()\n\n    private val movieService = retrofit.create(MovieService::class.java)\n    private val tvService = retrofit.create(TMDBService::class.java)\n\n    fun loadData(): List<SearchHistory>{\n        return queryDao.getSearchHistory()\n    }\n\n    @WorkerThread\n    fun deleteRecord(query: SearchHistory){\n        queryDao.deleteRecord(query.query)\n    }\n\n    @WorkerThread\n    suspend fun insert(query: SearchHistory) {\n        queryDao.insert(query)\n    }\n\n    @WorkerThread\n    suspend fun delete(query: SearchHistory) {\n        queryDao.delete(query)\n    }\n\n    @WorkerThread\n    fun deleteAll(){\n        queryDao.deleteAll()\n    }\n\n    @WorkerThread\n    suspend fun movieSearch(query:String): List<Movie>{\n        val searchResults = movieService.searchMovie(\n            query,\n            BuildConfig.TMDB_API_KEY,\n            \"en-US\"\n        )\n\n        return if (searchResults.isSuccessful) {\n            searchResults.body()?.results ?: emptyList()\n        } else\n            emptyList()\n    }\n\n    @WorkerThread\n    suspend fun tvSearch(query:String): List<TVshow>{\n        val gson = Gson()\n        val searchResults = tvService.searchShow(\n            query,\n            BuildConfig.TMDB_API_KEY,\n            \"en-US\"\n        )\n//        val client = OkHttpClient()\n//\n//        val request = Request.Builder()\n//            .url(\"https://api.themoviedb.org/3/search/tv?query=${query}&include_adult=true&language=en-US&page=1\")\n//            .get()\n//            .addHeader(\"accept\", \"application/json\")\n//            .addHeader(\"api_key\", BuildConfig.TMDB_API_KEY)\n//            .build()\n//\n//        val response = client.newCall(request).execute()\n//        return if(response.isSuccessful){\n//            gson.fromJson(response.body.string(),TVShowResponse::class.java).results\n//        }else{\n//            emptyList()\n//        }\n        return if (searchResults.isSuccessful) {\n            searchResults.body()?.results ?: emptyList()\n        } else\n            emptyList()\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/com/demomiru/tokeiv2/history/SearchApp.kt",
    "content": "package com.demomiru.tokeiv2.history\n\nimport android.app.Application\n\nclass SearchApp : Application() {\n    val db by lazy {\n        SearchDatabase.getInstance(this)\n    }\n}"
  },
  {
    "path": "app/src/main/java/com/demomiru/tokeiv2/history/SearchDatabase.kt",
    "content": "package com.demomiru.tokeiv2.history\n\nimport android.content.Context\nimport androidx.room.Database\nimport androidx.room.Room\nimport androidx.room.RoomDatabase\n\n@Database(entities = [SearchHistory::class], version = 3)\nabstract class SearchDatabase : RoomDatabase(){\n\n    abstract fun searchDao() : SearchHistoryDao\n\n    companion object{\n\n        @Volatile\n        private var INSTANCE: SearchDatabase? = null\n\n        fun getInstance(context : Context) : SearchDatabase{\n            synchronized(this){\n                var instance = INSTANCE\n\n                if (instance == null){\n                    instance = Room.databaseBuilder(\n                        context.applicationContext,\n                        SearchDatabase::class.java,\n                        \"search_history_database\"\n                    ).fallbackToDestructiveMigration().build()\n\n                    INSTANCE = instance\n                }\n                return instance\n            }\n        }\n    }\n}"
  },
  {
    "path": "app/src/main/java/com/demomiru/tokeiv2/history/SearchHistory.kt",
    "content": "package com.demomiru.tokeiv2.history\n\nimport androidx.room.ColumnInfo\nimport androidx.room.Entity\nimport androidx.room.Index\nimport androidx.room.PrimaryKey\n\n@Entity(tableName = \"search_history\",indices = [Index(value = [\"query\"], unique = true)])\ndata class SearchHistory (\n    @PrimaryKey(autoGenerate = true)\n    val id:Int = 0 ,\n    @ColumnInfo(name = \"query\")\n    val query:String = \"\",\n)"
  },
  {
    "path": "app/src/main/java/com/demomiru/tokeiv2/history/SearchHistoryAdapter.kt",
    "content": "package com.demomiru.tokeiv2.history\n\nimport android.view.LayoutInflater\nimport android.view.View\nimport android.view.ViewGroup\nimport android.widget.ImageView\nimport android.widget.TextView\nimport androidx.recyclerview.widget.RecyclerView\nimport com.demomiru.tokeiv2.R\nimport com.demomiru.tokeiv2.TVshow\n\n\nclass SearchHistoryAdapter(private val searchHistory : List<String>,\n                           private val clickHandler : (String) -> Unit\n//                           private val deleteRecordClick : (String) -> Unit\n\n):\nRecyclerView.Adapter<SearchHistoryAdapter.ViewHolder>()\n{\n    class ViewHolder(view: View) : RecyclerView.ViewHolder(view){\n        val searchText:TextView  = view.findViewById(R.id.search_text)\n        val deleteRecord: ImageView = view.findViewById(R.id.delete_record)\n    }\n\n    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {\n        val view = LayoutInflater.from(parent.context).inflate(R.layout.search_item,parent,false)\n        return ViewHolder(view)\n    }\n\n    override fun getItemCount(): Int {\n        return searchHistory.size\n    }\n\n    override fun onBindViewHolder(holder: ViewHolder, position: Int) {\n        holder.searchText.text = searchHistory[position]\n        holder.deleteRecord.setOnClickListener {\n            clickHandler(searchHistory[position])\n        }\n        holder.itemView.setOnClickListener {\n            clickHandler(searchHistory[position])\n        }\n    }\n}"
  },
  {
    "path": "app/src/main/java/com/demomiru/tokeiv2/history/SearchHistoryAdapter2.kt",
    "content": "package com.demomiru.tokeiv2.history\n\nimport android.view.LayoutInflater\nimport android.view.View\nimport android.view.ViewGroup\n\nimport android.widget.ImageView\n\nimport android.widget.TextView\nimport androidx.recyclerview.widget.DiffUtil\nimport androidx.recyclerview.widget.ListAdapter\nimport androidx.recyclerview.widget.RecyclerView\nimport com.demomiru.tokeiv2.R\nimport com.demomiru.tokeiv2.history.SearchHistory\n\nclass SearchHistoryAdapter2(private val onClick :(SearchHistory,Boolean)->Unit):\n    ListAdapter<SearchHistory, SearchHistoryAdapter2.ViewHolder>(SearchDiffCallBack) {\n    class ViewHolder(view: View) : RecyclerView.ViewHolder(view){\n        private val searchText:TextView  = view.findViewById(R.id.search_text)\n\n        val deleteRecord: ImageView = view.findViewById(R.id.delete_record)\n        fun bind(query: SearchHistory) {\n            searchText.text = query.query\n        }\n    }\n    object SearchDiffCallBack : DiffUtil.ItemCallback<SearchHistory>() {\n        override fun areItemsTheSame(oldItem: SearchHistory, newItem: SearchHistory): Boolean {\n            return oldItem === newItem\n        }\n\n        override fun areContentsTheSame(oldItem: SearchHistory, newItem: SearchHistory): Boolean {\n            return oldItem == newItem\n        }\n    }\n\n    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {\n        val view = LayoutInflater.from(parent.context).inflate(R.layout.search_item,parent,false)\n        return ViewHolder(view)\n    }\n\n\n    override fun onBindViewHolder(holder: ViewHolder, position: Int) {\n        val query = getItem(position)\n        holder.bind(query)\n        holder.deleteRecord.setOnClickListener {\n            onClick(query,false)\n        }\n        holder.itemView.setOnClickListener {\n            onClick(query,true)\n        }\n    }\n}\n\n"
  },
  {
    "path": "app/src/main/java/com/demomiru/tokeiv2/history/SearchHistoryDao.kt",
    "content": "package com.demomiru.tokeiv2.history\n\nimport androidx.room.Dao\nimport androidx.room.Delete\nimport androidx.room.Insert\nimport androidx.room.OnConflictStrategy\nimport androidx.room.Query\nimport kotlinx.coroutines.flow.Flow\n\n@Dao\ninterface SearchHistoryDao {\n\n    @Insert(onConflict = OnConflictStrategy.REPLACE)\n    suspend fun insert(searchHistory: SearchHistory)\n\n    @Delete\n    suspend fun delete(searchHistory: SearchHistory)\n\n    @Query(\"DELETE FROM search_history WHERE `query`=:query\")\n    fun deleteRecord(query: String)\n\n    @Query(\"SELECT COUNT(*) FROM search_history\")\n    fun getLastID() : Int\n\n    @Query(\"SELECT * FROM search_history ORDER BY id DESC\")\n    fun getSearchHistory(): List<SearchHistory>\n\n    @Query(\"DELETE FROM search_history\")\n    fun deleteAll()\n}"
  },
  {
    "path": "app/src/main/java/com/demomiru/tokeiv2/subtitles/SubTrackAdapter.kt",
    "content": "package com.demomiru.tokeiv2.subtitles\n\n\nimport android.annotation.SuppressLint\nimport android.view.LayoutInflater\nimport android.view.View\nimport android.view.ViewGroup\nimport android.widget.CheckedTextView\n\nimport androidx.media3.exoplayer.source.SingleSampleMediaSource\nimport androidx.recyclerview.widget.RecyclerView\nimport com.demomiru.tokeiv2.R\n\ndata class SubtitleConfig(\n    val subConfig : SingleSampleMediaSource,\n    var isChecked : Boolean = false,\n    val language : String = \"\",\n)\n\nclass SubTrackAdapter(private val subList: List<SubtitleConfig>, private val position: Int,\nprivate val onClick : (SubtitleConfig) -> Unit\n                      ): RecyclerView.Adapter<SubTrackAdapter.ViewHolder> (){\n    private var selectedPosition = position\n\n    private fun setSelectedPosition(position: Int) {\n        selectedPosition = position\n        notifyDataSetChanged()\n    }\n\n    class ViewHolder(view: View) : RecyclerView.ViewHolder(view){\n        val subTitle : CheckedTextView = view.findViewById(R.id.sub_text_view)\n    }\n\n    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {\n        val view = LayoutInflater.from(parent.context).inflate(R.layout.sub_view,parent,false)\n        return ViewHolder(view)\n    }\n\n    override fun getItemCount(): Int {\n        return subList.size\n    }\n\n    @SuppressLint(\"SetTextI18n\", \"NotifyDataSetChanged\")\n    override fun onBindViewHolder(holder: ViewHolder, position: Int) {\n        val sub = subList[position]\n//        holder.subTitle.text = \"$title Subtitle ${position + 1}\"\n        holder.subTitle.text = sub.language\n        holder.subTitle.isChecked = position == selectedPosition\n\n        holder.itemView.setOnClickListener {\n            setSelectedPosition(holder.bindingAdapterPosition)\n            onClick(sub)\n        }\n    }\n\n}"
  },
  {
    "path": "app/src/main/java/com/demomiru/tokeiv2/subtitles/Subtitles.kt",
    "content": "package com.demomiru.tokeiv2.subtitles\n\n\n\ndata class Subtitle(\n    val data: List<Sub>\n)\n\ndata class Sub(\n    val id : String,\n    val type:String,\n    val attributes: Attribute\n)\n\ndata class Attribute(\n    val ratings:String,\n    val files: List<SubFile>\n)\ndata class SubFile(\n    val file_id:String\n)\n"
  },
  {
    "path": "app/src/main/java/com/demomiru/tokeiv2/tracks/TrackAdapter.kt",
    "content": "package com.demomiru.tokeiv2.tracks\n\nimport android.annotation.SuppressLint\nimport android.view.LayoutInflater\nimport android.view.View\nimport android.view.ViewGroup\nimport android.widget.CheckedTextView\nimport android.widget.ImageView\nimport android.widget.TextView\nimport androidx.recyclerview.widget.DiffUtil\nimport androidx.recyclerview.widget.ListAdapter\nimport androidx.recyclerview.widget.RecyclerView\nimport com.demomiru.tokeiv2.R\nimport com.demomiru.tokeiv2.history.SearchHistory\nimport com.demomiru.tokeiv2.history.SearchHistoryAdapter2\nimport com.demomiru.tokeiv2.utils.ExtractedData\n\n\ndata class Track(val id: Int, val format: String, val resolution: Pair<String, String>, var selected: Boolean)\n\nclass TrackAdapter(private val tracks: List<Track>,private val onTrackSelected: (Track) -> Unit) : RecyclerView.Adapter<TrackAdapter.TrackViewHolder>() {\n\n    inner class TrackViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {\n        val trackResolution: CheckedTextView = itemView.findViewById(R.id.track_quality)\n    }\n    private var selectedPosition = 0\n\n    private fun setSelectedPosition(position: Int) {\n        selectedPosition = position\n        notifyDataSetChanged()\n    }\n\n\n    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TrackViewHolder {\n        val view = LayoutInflater.from(parent.context).inflate(R.layout.track_item, parent, false)\n        return TrackViewHolder(view)\n    }\n\n    @SuppressLint(\"SetTextI18n\")\n    override fun onBindViewHolder(holder: TrackViewHolder, position: Int) {\n        val track = tracks[position]\n        if (track.format != \"Auto\" && track.format!=\"super\")\n            holder.trackResolution.text = \"${track.resolution.first} x ${track.resolution.second}\"\n        else if( track.format == \"super\")\n            holder.trackResolution.text = track.resolution.second\n        else\n            holder.trackResolution.text = \"Auto\"\n        holder.trackResolution.isChecked = position == selectedPosition\n        holder.itemView.setOnClickListener {\n            setSelectedPosition(holder.bindingAdapterPosition)\n            onTrackSelected(track)\n        }\n    }\n\n    override fun getItemCount() = tracks.size\n}\n\nclass SourceAdapter(private val onClick :(ExtractedData)->Unit):\n    ListAdapter<ExtractedData, SourceAdapter.ViewHolder>(SearchDiffCallBack) {\n\n    private var selectedPosition = 0\n\n    private fun setSelectedPosition(position: Int) {\n        selectedPosition = position\n        notifyDataSetChanged()\n    }\n    inner class ViewHolder(view: View) : RecyclerView.ViewHolder(view){\n        val sourceTv: CheckedTextView = itemView.findViewById(R.id.track_quality)\n    }\n    object SearchDiffCallBack : DiffUtil.ItemCallback<ExtractedData>() {\n        override fun areItemsTheSame(oldItem: ExtractedData, newItem: ExtractedData): Boolean {\n            return oldItem === newItem\n        }\n\n        override fun areContentsTheSame(oldItem: ExtractedData, newItem: ExtractedData): Boolean {\n            return oldItem == newItem\n        }\n    }\n\n    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {\n        val view = LayoutInflater.from(parent.context).inflate(R.layout.track_item,parent,false)\n        return ViewHolder(view)\n    }\n\n\n    override fun onBindViewHolder(holder: ViewHolder, position: Int) {\n        val source = getItem(position)\n        holder.sourceTv.isChecked = position == selectedPosition\n        holder.sourceTv.text = \"Source : ${source.source}\"\n        holder.itemView.setOnClickListener {\n            setSelectedPosition(holder.bindingAdapterPosition)\n            onClick(source)\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/com/demomiru/tokeiv2/utils/DudeFilmsUtils.kt",
    "content": "package com.demomiru.tokeiv2.utils\n\nimport android.util.Log\nimport com.demomiru.tokeiv2.BuildConfig\nimport com.demomiru.tokeiv2.Keys\nimport com.demomiru.tokeiv2.MovieFile\nimport com.demomiru.tokeiv2.MovieIMDB\nimport com.demomiru.tokeiv2.Season\nimport com.demomiru.tokeiv2.TvIMDB\nimport com.google.gson.Gson\nimport com.lagradost.nicehttp.Requests\nimport okio.GzipSource\nimport okio.buffer\nimport org.json.JSONArray\nimport java.nio.charset.StandardCharsets\nimport java.util.Base64\nimport kotlin.system.exitProcess\n\n\n//https://lordhd.eu/\n//TODO integrate lordhd.eu\n\nsuspend fun getMovieImdb(tmdbID: String) : String{\n    val requests = Requests()\n    val headers = mapOf(\n        \"accept\" to \" application/json\",\n        \"Authorization\" to \"Bearer ${BuildConfig.TMDB_TOKEN}\"\n\n    )\n    val gson = Gson()\n    val movieImdb = requests.get(\"https://api.themoviedb.org/3/movie/$tmdbID?append_to_response=external_ids&language=en-US\",\n        headers = headers\n    ).okhttpResponse\n    val response = movieImdb.body.string()\n    val imdbID = gson.fromJson(response, MovieIMDB::class.java)\n    return imdbID.external_ids.imdb_id\n//       Log.i(\"ImdbID\", imdbID.imdb_id)\n}\n\nsuspend fun getTvImdb(tmdbID: String): String{\n    val requests = Requests()\n    val headers = mapOf(\n        \"accept\" to \" application/json\",\n        \"Authorization\" to \"Bearer ${BuildConfig.TMDB_TOKEN}\"\n\n    )\n\n    val tvImdb = requests.get(\"https://api.themoviedb.org/3/tv/$tmdbID?append_to_response=external_ids&language=en-US\",\n        headers = headers\n    ).okhttpResponse\n    val gson = Gson()\n    val response = tvImdb.body.string()\n//    Log.i(\"response\", response)\n    val imdbID = gson.fromJson(response, TvIMDB::class.java)\n    println(imdbID.languages[0])\n    return if(imdbID.origin_country[0] == \"IN\")\n        imdbID.external_ids.imdb_id\n    else\n        \"\"\n}\n\nsuspend fun getTvIMDB(tmdbID: String): String{\n    val requests = Requests()\n    val headers = mapOf(\n        \"accept\" to \" application/json\",\n        \"Authorization\" to \"Bearer ${BuildConfig.TMDB_TOKEN}\"\n\n    )\n\n    val tvImdb = requests.get(\"https://api.themoviedb.org/3/tv/$tmdbID?append_to_response=external_ids&language=en-US\",\n        headers = headers\n    ).okhttpResponse\n    val gson = Gson()\n    val response = tvImdb.body.string()\n//    Log.i(\"response\", response)\n    val imdbID = gson.fromJson(response, TvIMDB::class.java)\n    return imdbID.external_ids.imdb_id\n\n}\n\n//val origin = \"https://log-training-i-254.site\"\n\nprivate val proxy = BuildConfig.PROXY_URL\n\nsuspend fun getMovieLink(imdbId : String): String {\n\n//    val origin = \"https://hurl-party-i-256.site\"\n    val origin = \"https://gerrickle-franchans-i-267.site\"\n    val requests = Requests(baseClient = getBaseClient())\n    val encoded = Base64.getEncoder().encodeToString(\n        (imdbId + \"-\" + System.currentTimeMillis()).toByteArray(\n            StandardCharsets.UTF_8\n        )\n    )\n    try {\n    val doc2 = requests.get(\n        \"$origin/pb/$encoded\", referer =\n        \"https://dudefilms.bio/\"\n    ).document.getElementsByTag(\"script\")\n\n//    val notAvailable = doc.toString().contains(\"Video Not Found\")\n//    if (notAvailable) return \"\"\n//    val doc2 = doc.getElementsByTag(\"script\")\n\n    if (doc2.size < 2) return \"\"\n\n    val script = doc2[5].toString()\n    val regex = Regex(\"\"\"let pc = (.*?);\"\"\")\n    val matchResult = regex.find(script)\n\n    if (matchResult != null) {\n        val jsonInsideHDVBPlayer = matchResult.groupValues[1]\n        Log.i(\"Keys And Hash\", jsonInsideHDVBPlayer)\n        val gson = Gson()\n        val fileKeys: Keys = gson.fromJson(jsonInsideHDVBPlayer, Keys::class.java)\n        Log.i(\"file:\", fileKeys.file)\n\n//        val srcUrl = \"https://hurl-party-i-256.site\"\n        val srcUrl = \"https://gerrickle-franchans-i-267.site\"\n        val absoluteUrl = srcUrl + fileKeys.file\n        val headers = mapOf(\n            \"Accept\" to \"*/*\",\n            \"Accept-Encoding\" to \"gzip, deflate, br\",\n            \"Accept-Language\" to \"en-US,en;q=0.9\",\n            \"Content-Length\" to \"0\",\n            \"Content-Type\" to \"application/x-www-form-urlencoded\",\n            \"Origin\" to \"https://hurl-party-i-256.site\",\n            \"User-Agent\" to \"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36\",\n            \"X-Csrf-Token\" to fileKeys.key\n        )\n\n        val referer = \"$origin/pb/$encoded\"\n        val doc3 = requests.post(\n            absoluteUrl,\n            referer = referer,\n            headers = headers\n        ).okhttpResponse\n        val responseBody = doc3.body\n        val contentEncoding = doc3.header(\"Content-Encoding\")\n\n        if (contentEncoding == \"gzip\") {\n            val gzippedSource = GzipSource(responseBody.source())\n            val decompressedString = gzippedSource.buffer().readUtf8()\n            val jsonArray = JSONArray(decompressedString)\n//            println(jsonArray)\n            val jsonObject = jsonArray.getJSONObject(0).toString()\n            val movieDetails = gson.fromJson(jsonObject, MovieFile::class.java)\n            val movieId = movieDetails.file\n            return requests.post(\n                \"$origin/playlist/$movieId.txt\",\n                referer = referer,\n                headers = headers\n            ).toString()\n        }\n\n    }\n    else{\n        println(\"match result issue\")\n        return \"\"\n    } }catch(e : Exception){\n        println(e.printStackTrace())\n        return \"\"\n    }\n    return \"\"\n}\n\nsuspend fun getTvLink(imdbId: String, s : Int, e: Int) : String{\n//    val origin = \"https://hurl-party-i-256.site\"\n    val origin = \"https://firtorent-yult-i-274.site/\"\n    val requests = Requests(baseClient = getBaseClient())\n    val encoded = Base64.getEncoder().encodeToString(\n        (imdbId + \"-\" + System.currentTimeMillis()).toByteArray(\n            StandardCharsets.UTF_8\n        )\n    )\n\n    val doc2 = requests.get(\n        \"$origin/pb/$encoded\", referer =\n        \"https://dudefilms.bio/\"\n    ).document.getElementsByTag(\"script\")\n\n    if (doc2.size < 2) return \"\"\n    val script = doc2[7].toString()\n    val regex =\n        Regex(\"\"\"HDVBPlayer\\((.*?)\\);\"\"\")\n    val matchResult = regex.find(script)\n\n    if (matchResult != null) {\n        val jsonInsideHDVBPlayer = matchResult.groupValues[1]\n        Log.i(\"Keys And Hash\", jsonInsideHDVBPlayer)\n        val gson = Gson()\n        val fileKeys: Keys = gson.fromJson(jsonInsideHDVBPlayer, Keys::class.java)\n        Log.i(\"file:\", fileKeys.file)\n\n//        val srcUrl = \"https://hurl-party-i-256.site\"\n        val srcUrl = origin\n        val absoluteUrl = srcUrl + fileKeys.file\n        val headers = mapOf(\n            \"Accept\" to \"*/*\",\n            \"Accept-Encoding\" to \"gzip, deflate, br\",\n            \"Accept-Language\" to \"en-US,en;q=0.9\",\n            \"Content-Length\" to \"0\",\n            \"Content-Type\" to \"application/x-www-form-urlencoded\",\n            \"Origin\" to origin,\n            \"User-Agent\" to \"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36\",\n            \"X-Csrf-Token\" to fileKeys.key\n        )\n\n        val referer = \"$origin/pb/$encoded\"\n        val doc3 = requests.post(\n            absoluteUrl,\n            referer = referer,\n            headers = headers\n        ).okhttpResponse\n        val responseBody = doc3.body\n        val contentEncoding = doc3.header(\"Content-Encoding\")\n\n        if (contentEncoding == \"gzip\") {\n            // Decompress the gzipped response\n            val gzippedSource = GzipSource(responseBody.source())\n            val decompressedString = gzippedSource.buffer().readUtf8()\n            val jsonArray = JSONArray(decompressedString)\n            val seasons = arrayListOf<Season>()\n            for (i in 0 until jsonArray.length()){\n                val jO = jsonArray.getJSONObject(i).toString()\n                val eD = gson.fromJson(\n                    jO\n                        .replace(\"[]\", \"\"), Season::class.java\n                )\n                seasons.add(eD)\n            }\n//            println(seasons)\n\n            val episodeDetails = seasons.find {\n                it.id.toInt() == (s+1)\n            } ?: return \"\"\n\n//            val jsonObject = jsonArray.getJSONObject(s).toString()\n//            Log.i(\"json\", jsonObject)\n//            val episodeDetails = gson.fromJson(\n//                jsonObject\n//                    .replace(\"[]\", \"\"), Season::class.java\n//            )\n\n//match episode also\n//            val episode = episodeDetails.folder[e].folder[0].file.replace(\"~\", \"\")\n            val episodes = episodeDetails.folder.map {\n                Pair(it.episode,it.folder[0].file.replace(\"~\",\"\"))\n            }\n            val episode = episodes.find {\n                it.first == \"${e+1}\"\n            }?.second ?: return \"\"\n\n            Log.i(\"episode\", episode)\n            val doc4 = requests.post(\n                \"$origin/playlist/$episode.txt\",\n                headers = headers,\n                referer = referer\n            ).toString()\n            Log.i(\"Video Link\", doc4)\n            return doc4\n        }\n    }\n    else {\n        return \"\"\n    }\n    return \"\"\n}\nsuspend fun getHiTvSeasons(imdbId: String) : Int{\n    val origin = \"https://hurl-party-i-256.site\"\n    val requests = Requests(baseClient = getBaseClient())\n    val encoded = Base64.getEncoder().encodeToString(\n        (imdbId + \"-\" + System.currentTimeMillis()).toByteArray(\n            StandardCharsets.UTF_8\n        )\n    )\n\n    val doc2 = requests.get(\n        \"$origin/pb/$encoded\", referer =\n        \"https://dudefilms.bio/\"\n    ).document.getElementsByTag(\"script\")\n\n    if (doc2.size < 2) exitProcess(0)\n    val script = doc2[7].toString()\n    val regex =\n        Regex(\"\"\"HDVBPlayer\\((.*?)\\);\"\"\")\n    val matchResult = regex.find(script)\n\n    if (matchResult != null) {\n        val jsonInsideHDVBPlayer = matchResult.groupValues[1]\n        Log.i(\"Keys And Hash\", jsonInsideHDVBPlayer)\n        val gson = Gson()\n        val fileKeys: Keys = gson.fromJson(jsonInsideHDVBPlayer, Keys::class.java)\n        Log.i(\"file:\", fileKeys.file)\n\n        val srcUrl = \"https://hurl-party-i-256.site\"\n        val absoluteUrl = srcUrl + fileKeys.file\n        val headers = mapOf(\n            \"Accept\" to \"*/*\",\n            \"Accept-Encoding\" to \"gzip, deflate, br\",\n            \"Accept-Language\" to \"en-US,en;q=0.9\",\n            \"Content-Length\" to \"0\",\n            \"Content-Type\" to \"application/x-www-form-urlencoded\",\n            \"Origin\" to \"https://hurl-party-i-256.site\",\n            \"User-Agent\" to \"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36\",\n            \"X-Csrf-Token\" to fileKeys.key\n        )\n\n        val referer = \"$origin/pb/$encoded\"\n        val doc3 = requests.post(\n            absoluteUrl,\n            referer = referer,\n            headers = headers\n        ).okhttpResponse\n        val responseBody = doc3.body\n        val contentEncoding = doc3.header(\"Content-Encoding\")\n\n        if (contentEncoding == \"gzip\") {\n            // Decompress the gzipped response\n            val gzippedSource = GzipSource(responseBody.source())\n            val decompressedString = gzippedSource.buffer().readUtf8()\n            val jsonArray = JSONArray(decompressedString)\n            return jsonArray.length()\n        }\n    }\n    else {\n        return 0\n    }\n    return 0\n}\n"
  },
  {
    "path": "app/src/main/java/com/demomiru/tokeiv2/utils/Extractor.kt",
    "content": "package com.demomiru.tokeiv2.utils\n\nimport JsUnpacker\nimport android.net.Uri\nimport androidx.media3.common.MimeTypes\nimport androidx.media3.exoplayer.source.SingleSampleMediaSource\nimport com.demomiru.tokeiv2.extractors.Vidplay\nimport com.demomiru.tokeiv2.subtitles.SubtitleConfig\nimport com.google.gson.Gson\nimport com.lagradost.nicehttp.Requests\nimport com.lagradost.nicehttp.addGenericDns\nimport com.lagradost.nicehttp.ignoreAllSSLErrors\nimport okhttp3.Cache\nimport okhttp3.OkHttpClient\nimport java.io.File\nimport java.net.URI\n\nprivate val appCache = Cache(File(\"cacheDir\", \"okhttpcache\"), 10 * 1024 * 1024)\nprivate val proxy = \"https://hello-world-aged-resonance-fc8f.bokaflix.workers.dev/?apiUrl=\"\nprivate fun OkHttpClient.Builder.addCloudFlareDns() = (\n        addGenericDns(\n            \"https://cloudflare-dns.com/dns-query\",\n            // https://www.cloudflare.com/ips/\n            listOf(\n                \"1.1.1.1\",\n                \"1.0.0.1\",\n                \"2606:4700:4700::1111\",\n                \"2606:4700:4700::1001\"\n            )\n        ))\nprivate val baseClient = OkHttpClient.Builder()\n    .followRedirects(true)\n    .followSslRedirects(true)\n    .ignoreAllSSLErrors()\n    .cache(\n        appCache\n    ).addCloudFlareDns().build()\n\ndata class ExtractedData(\n    val videoUrl: String? = null,\n    val subs: List<String> = listOf(),\n    val source: String,\n    val isSuper: Boolean = false,\n)\n\nfun String.createSlug(): String {\n    return this.replace(Regex(\"[^\\\\w ]+\"), \"\").replace(\" \", \"-\").lowercase()\n}\n\nfun getBaseUrl(url: String): String {\n    return URI(url).let {\n        \"${it.scheme}://${it.host}\"\n    }\n}\n\nprivate val packedRegex = Regex(\"\"\"eval\\(function\\(p,a,c,k,e,.*\\)\\)\"\"\")\nfun getPacked(string: String): String? {\n    return packedRegex.find(string)?.value}\nfun getAndUnpack(string: String): String {\n    val packedText = getPacked(string)\n    return JsUnpacker(packedText).unpack() ?: string\n}\n\nclass Extractor (private val origin: String){\n\n\n    private val gson = Gson()\n    private val extractorPriority = mapOf(\n//        \"hi\" to listOf(1,5,3,4),\n//        \"en\" to listOf(1,5,2,3),\n//        \"\" to listOf(1,5,2,3)\n        \"hi\" to listOf(6,5,4,1,3),\n        \"en\" to listOf(6,5,4,1,3),\n        \"\" to listOf(6,5,4,1,3)\n    )\n    private val eList = if(origin in extractorPriority.keys) extractorPriority[origin] else extractorPriority[\"\"]\n    var i = 0\n\n    suspend fun loadExtractor(title: String, id: String, year: String = \"1970\", s: Int, ep: Int, isMovie: Boolean, next:Int = 6): ExtractedData{\n        println(origin)\n        return when(next){\n//            2 -> goMovieExtractor(title,s,ep,id,year,isMovie)\n//            2-> zoeChipExtractor(title,s,ep,id,year,isMovie)\n//            2-> nowTvExtractor(title,s,ep,id,year,isMovie)\n            1 -> superStreamExtractor(title,s,ep,id,year,isMovie)\n            3 -> smashyExtractor(title,s,ep,id,year,isMovie)\n//            4 -> dudeFilmExtractor(title,s,ep,id,year,isMovie)\n            4-> vidSrcExtractor(title,s,ep,id,year,isMovie)\n            5 -> vidSrcExtractor(title,s,ep,id,year,isMovie)\n            6 -> vidPlayExtractor(title,year,s,ep,id,isMovie)\n            else -> ExtractedData(source = \"\")\n        }\n    }\n\n    private suspend fun zoeChipExtractor(title: String, s: Int, ep: Int, id: String, year: String, isMovie: Boolean,srcChange: Boolean = false): ExtractedData {\n        val slug = title.createSlug()\n        val app = Requests()\n        val zoechipAPI =\"https://zoechip.org\"\n        var m3u8url = \"\"\n        try {\n\n            val url = if (isMovie) {\n                \"$zoechipAPI/film/${title.createSlug()}-$year\"\n            } else {\n                \"$zoechipAPI/episode/$slug-season-$s-episode-$ep\"\n            }\n\n            val mid = app.get(\"$proxy$url\").document.selectFirst(\"div#show_player_ajax\")?.attr(\"movie-id\")\n                ?: throw Exception(\"no zoechip found\")\n\n            val server = app.post(\n                \"$proxy$zoechipAPI/wp-admin/admin-ajax.php\", data = mapOf(\n                    \"action\" to \"lazy_player\",\n                    \"movieID\" to mid,\n                ), referer = url, headers = mapOf(\n                    \"X-Requested-With\" to \"XMLHttpRequest\"\n                )\n            ).document.selectFirst(\"ul.nav a:contains(Filemoon)\")?.attr(\"data-server\")\n                ?: throw Exception(\"no zoechip found\")\n\n            val res = app.get(\"$proxy$server\", referer = \"$zoechipAPI/\")\n            val host = getBaseUrl(res.url)\n            val script =\n                res.document.select(\"script:containsData(function(p,a,c,k,e,d))\").last()?.data()\n            val unpacked = getAndUnpack(script ?: throw Exception(\"no zoechip found\"))\n\n            val m3u8 = Regex(\"file:\\\\s*\\\"(.*?m3u8.*?)\\\"\").find(unpacked)?.groupValues?.getOrNull(1)\n            m3u8url = m3u8 ?: throw Exception(\"no zoechip found\")\n        }catch (e: Exception){\n            return if(!srcChange)  loadExtractor(title, id, year, s, ep, isMovie,eList!![++i]) else ExtractedData(source = \"\")\n        }\n        println(m3u8url)\n        return ExtractedData(m3u8url, listOf(),\"zoechip\",false)\n    }\n\n\n    suspend fun loadExtractorNext(title: String, id: String, s: Int, ep: Int, source: String?) : ExtractedData{\n        return when(source){\n            \"superstream\" -> superStreamExtractor(title,s,ep,id,\"\",false)\n            \"gomovies\" -> goMovieExtractor(title,s,ep,id,\"\",false)\n             \"smashy\" -> smashyExtractor(title,s,ep,id,\"\",false)\n             \"dudefilms\" ->  dudeFilmExtractor(title,s,ep,id,\"\",false)\n            \"vidsrc\"   -> vidSrcExtractor(title,s,ep,id,\"\",false)\n            \"vidplay\"   -> vidPlayExtractor(title,\"\",s,ep,id,false)\n//            \"nowtv\" -> nowTvExtractor(title,s,ep,id,\"\",false)\n            else-> ExtractedData(source = \"\")\n        }\n    }\n\n    suspend fun loadSourceChange(title: String, id:String,s:Int, ep: Int,year: String,isMovie: Boolean, source: String? = null) : List<ExtractedData>{\n        val listSources = mutableListOf<ExtractedData>()\n        listSources.add(vidPlayExtractor(title,year,s,ep,id,isMovie,true))\n        listSources.add(superStreamExtractor(title,s,ep,id,year,isMovie,true))\n        listSources.add(vidSrcExtractor(title,s,ep,id,year,isMovie,true))\n        listSources.add(goMovieExtractor(title,s,ep,id,year,isMovie,true))\n        listSources.add(smashyExtractor(title,s,ep,id,year,isMovie,true))\n        listSources.add(dudeFilmExtractor(title,s,ep,id,year,isMovie))\n//        listSources.add(zoeChipExtractor(title,s,ep,id,year,isMovie,true))\n\n\n        listSources.removeIf{\n            it.videoUrl.isNullOrBlank()\n        }\n        if(origin == \"hi\")\n            listSources.removeIf{\n                it.source == \"gomovies\"\n            }\n        if(source!=null)\n            listSources.removeIf {\n                it.source == source\n            }\n        println(listSources)\n        return listSources.toList()\n    }\n\n\n\n    private suspend fun superStreamExtractor(title: String,s:Int, ep: Int, id: String, year: String, isMovie: Boolean,srcChange: Boolean = false) : ExtractedData{\n        val superStream = SuperstreamUtils()\n        var videoUrl: String? = null\n        val subUrl : MutableList<String> = mutableListOf()\n        try {\n            val mainData = superStream.search(title)\n            val item = mainData.data.list[0]\n            val superId =\n                if (item.title == title && item.year.toString() == year) item.id else if(!isMovie && item.title == title) item.id else throw Exception(\n                    \"No super stream found\"\n                )\n            val movieLinks = superStream.loadLinks(isMovie, superId!!,s,ep)\n            println(movieLinks)\n            val urlMaps: MutableMap<String, String> = mutableMapOf()\n            movieLinks.data?.list?.forEach {\n                if (!it.path.isNullOrBlank()) {\n                    urlMaps[it.quality!!] = it.path\n                    if (it.quality == \"720p\") {\n                        val subtitle = superStream.loadSubtile(isMovie, it.fid!!, superId, s,ep).data\n                        subUrl.add(getSub2(subtitle))\n                        return@forEach\n                    }\n                }\n            }\n\n            if(urlMaps.isNotEmpty())\n                videoUrl = gson.toJson(urlMaps)\n            if(videoUrl.isNullOrBlank()){\n\n//                    isSuper = false\n                throw Exception(\"No super stream found\")\n//                   return loadExtractor(title,id,year,s,ep,isMovie, eList!![++i])\n            }\n        }catch(e:Exception) {\n            e.printStackTrace()\n            return if(!srcChange)loadExtractor(title, id, year,s,ep,isMovie,eList!![++i]) else ExtractedData(source = \"\")\n        }\n        println(\"Superstream\")\n        return ExtractedData(videoUrl,subUrl,\"superstream\",true)\n    }\n\n\n    private fun getSub(subtitle: SuperstreamUtils.PrivateSubtitleData?): List<String>{\n        val subUrl: MutableList<String> = mutableListOf()\n        subtitle?.list?.forEach { subList->\n            if(subList.language == \"English\"){\n                subList.subtitles.forEach { sub->\n\n                    if (subUrl.size == 3) {\n                        return subUrl\n                    }\n                    if (sub.lang == \"en\" && !sub.file_path.isNullOrBlank()) {\n                        subUrl.add(sub.file_path)\n//                            println(\"${sub.language} : ${sub.file_path}\")\n                    }\n                }\n                return subUrl\n            }\n        }\n        return listOf()\n    }\n\n    private fun getSub2(subtitle: SuperstreamUtils.PrivateSubtitleData?): String{\n        val subUrl: MutableMap<String,String> = mutableMapOf()\n        subtitle?.list?.forEach { subList ->\n            if(subList.language == null) return@forEach\n            var subsString = \"\"\n            subList.subtitles.forEach { sub ->\n                if (!sub.file_path.isNullOrBlank()) subsString += \"${sub.file_path},\"\n            }\n            subsString = subsString.substringBeforeLast(\",\")\n            subUrl[subList.language] = subsString\n        }\n        return gson.toJson(subUrl)\n    }\n\n    suspend fun nowTvExtractor(title: String, s: Int, ep: Int, id: String, year: String, movie: Boolean,srcChange: Boolean = false): ExtractedData {\n\n        val app = Requests()\n        val referer = \"https://bflix.gs/\"\n        val nowTvAPI = \"https://myfilestorage.xyz\"\n        suspend fun String.isSuccess(): Boolean {\n            return app.get(this, referer = referer).isSuccessful\n        }\n\n        var url =\n            if (movie) \"$nowTvAPI/$id.mp4\" else \"$nowTvAPI/tv/$id/s${s}e${ep}.mp4\"\n        print(\"NowTv\")\n        if (!url.isSuccess()) {\n            url = if (movie) {\n                val imdb = getMovieImdb(id)\n                val temp = \"$nowTvAPI/$imdb.mp4\"\n                if (temp.isSuccess()) temp else \"$nowTvAPI/$id-1.mp4\"\n            } else {\n                val imdb = getTvIMDB(id)\n                \"$nowTvAPI/tv/$imdb/s${s}e${ep}.mp4\"\n            }\n            if (!app.get(url, referer = referer).isSuccessful) {return if(!srcChange)   loadExtractor(title, id, year, s, ep, movie,eList!![++i]) else ExtractedData(source = \"\")}\n            else return ExtractedData(url, listOf(),\"nowtv\",false)\n\n        } else\n           return ExtractedData(url, listOf(),\"nowtv\",false)\n    }\n\n\n\n    private suspend fun vidSrcExtractor(title: String, s: Int,ep:Int, id: String,year:String,isMovie: Boolean,srcChange: Boolean = false): ExtractedData{\n        val vidSrc = VidSrc()\n        val videoUrl: String?\n        val subUrl: ArrayList<String> = arrayListOf()\n        try {\n            val links =  vidSrc.getLink(id,isMovie,s,ep)\n            val vidLink = links.first\n            val subLink = links.second\n            if(vidLink.isNullOrBlank()) throw Exception(\"No vidsrc found\")\n            else {\n                if (!subLink.isNullOrBlank())subUrl.add(subLink)\n                videoUrl = vidLink\n            }\n        }catch (e:Exception){\n            e.printStackTrace()\n            return if(!srcChange)  loadExtractor(title, id, year, s, ep, isMovie,eList!![++i]) else ExtractedData(source = \"\")\n        }\n        return ExtractedData(videoUrl,subUrl,\"vidsrc\",false)\n\n    }\n\n    private suspend fun goMovieExtractor(title: String,s: Int, ep: Int, id: String,year: String,isMovie: Boolean,srcChange: Boolean = false): ExtractedData{\n        val goMovie = GoMovies()\n        var videoUrl: String? = null\n        val subUrl : ArrayList<String> = arrayListOf()\n\n        try{\n            val data = goMovie.search(s,ep,title,isMovie,year)\n            val vidLink = data.first\n            val subLinks = data.second\n            if(vidLink.isNullOrBlank()){\n//                return loadExtractor(title, id, year, s, ep, isMovie,eList!![++i])\n                throw Exception(\"No go movies found\")\n            }\n            else{\n                if (!subLinks.isNullOrEmpty())subUrl.add(subLinks)\n                videoUrl = vidLink\n            }\n        }catch (e:Exception){\n            return if(!srcChange)   loadExtractor(title, id, year, s, ep, isMovie,eList!![++i]) else ExtractedData(source = \"\")\n        }\n        println(\"GoMovies\")\n        return ExtractedData(videoUrl,subUrl,\"gomovies\",false)\n    }\n\n    private suspend fun smashyExtractor(title: String,s: Int, ep: Int, id: String,year: String,isMovie: Boolean,srcChange: Boolean = false): ExtractedData{\n        var videoUrl : String? = null\n        val subUrl : ArrayList<String> = arrayListOf()\n        val smashSrc = SmashyStream()\n        try{\n            val links = smashSrc.getLink(isMovie,id, s, ep,origin)\n            val vidLink = links.first\n            val subLink = links.second\n            if(vidLink.isNullOrBlank()){\n//                return if (origin == \"hi\")\n//                    loadExtractor(title,id,year,s,ep,isMovie,eList!![++i])\n//                else\n//                    loadExtractor(title,id,year,s,ep,isMovie,0)\n                throw Exception(\"No smashy stream found\")\n            }\n            else{\n                if (!subLink.isNullOrBlank())subUrl.add(subLink)\n                videoUrl = vidLink\n            }\n\n\n        }catch (e: Exception){\n            return if(!srcChange) {\n                if (origin == \"hi\")\n                    loadExtractor(title,id,year,s,ep,isMovie,eList!![++i])\n                else\n                    loadExtractor(title,id,year,s,ep,isMovie,0)\n            }else ExtractedData(source = \"\")\n        }\n        println(\"Smashy\")\n        return ExtractedData(videoUrl,subUrl,\"smashy\",false)\n    }\n\n    private suspend fun vidPlayExtractor(title: String, year :String,s: Int, ep: Int, id: String, isMovie: Boolean, srcChange: Boolean = false): ExtractedData{\n        var videoUrl: String? = null\n        val subUrl : ArrayList<String> = arrayListOf()\n        val vidPlay = Vidplay()\n        try {\n            val links = vidPlay.getVidPlayUrl(isMovie,s,ep,id)\n            val vidLink = links.first\n            val subLink = links.second\n            if(vidLink.isNullOrBlank()){\n                throw Exception(\"No vidplay found\")\n            }\n            else{\n                if (!subLink.isNullOrBlank())subUrl.add(subLink)\n                videoUrl = vidLink\n            }\n\n        }catch (e: Exception){\n            return if(!srcChange)   loadExtractor(title, id, year, s, ep, isMovie,eList!![++i]) else ExtractedData(source = \"\")\n        }\n        return ExtractedData(videoUrl,subUrl,\"vidplay\",false)\n    }\n\n    //TODO\n    private suspend fun dudeFilmExtractor(title: String, s: Int, ep: Int, id: String, year: String, movie: Boolean): ExtractedData {\n        var videoUrl : String? = null\n        try {\n            videoUrl = if (movie) {\n                val imdb = getMovieImdb(id)\n                getMovieLink(imdb)\n            } else {\n                val imdb = getTvImdb(id)\n                getTvLink(imdb, s-1, ep-1)\n            }\n        }  catch (e: Exception){\n            return ExtractedData(source = \"\")\n        }\n        println(\"DudeFilms\")\n        return ExtractedData(videoUrl, listOf(),\"dudefilms\",false)\n    }\n}"
  },
  {
    "path": "app/src/main/java/com/demomiru/tokeiv2/utils/GoMovies.kt",
    "content": "package com.demomiru.tokeiv2.utils\n\nimport android.util.Base64\nimport com.demomiru.tokeiv2.BuildConfig\nimport com.google.gson.Gson\nimport com.google.gson.reflect.TypeToken\nimport com.lagradost.nicehttp.Requests\nimport org.json.JSONArray\nimport org.jsoup.nodes.Element\nimport org.jsoup.select.Elements\nimport java.nio.charset.StandardCharsets\nimport java.security.MessageDigest\nimport javax.crypto.Cipher\nimport javax.crypto.spec.IvParameterSpec\nimport javax.crypto.spec.SecretKeySpec\n\nclass GoMovies{\n\n    class AES {\n\n        fun decrypt(encrypted: String, password: String): String {\n            val keySize = 8\n            val ivSize = 4\n            val cipherText = Base64.decode(encrypted, Base64.DEFAULT)\n            val prefix = ByteArray(8)\n            System.arraycopy(cipherText, 0, prefix, 0, 8)\n            val salt = ByteArray(8)\n            System.arraycopy(cipherText, 8, salt, 0, 8)\n            val trueCipherText = ByteArray(cipherText.size - 16)\n            System.arraycopy(cipherText, 16, trueCipherText, 0, cipherText.size - 16)\n            val javaKey = ByteArray(keySize * 4)\n            val javaIv = ByteArray(ivSize * 4)\n            evpKDF(\n                password.toByteArray(StandardCharsets.UTF_8),\n                keySize,\n                ivSize,\n                salt,\n                javaKey,\n                javaIv\n            )\n            val aesCipherForEncryption = Cipher.getInstance(\"AES/CBC/PKCS5Padding\")\n            val ivSpec = IvParameterSpec(javaIv)\n            aesCipherForEncryption.init(Cipher.DECRYPT_MODE, SecretKeySpec(javaKey, \"AES\"), ivSpec)\n            val byteMsg = aesCipherForEncryption.doFinal(trueCipherText)\n            return String(byteMsg, StandardCharsets.UTF_8)\n        }\n\n        private fun evpKDF(\n            password: ByteArray,\n            keySize: Int,\n            ivSize: Int,\n            salt: ByteArray,\n            resultKey: ByteArray,\n            resultIv: ByteArray\n        ): ByteArray {\n            return evpKDF(password, keySize, ivSize, salt, 1, \"MD5\", resultKey, resultIv)\n        }\n\n        private fun evpKDF(\n            password: ByteArray,\n            keySize: Int,\n            ivSize: Int,\n            salt: ByteArray,\n            iterations: Int,\n            hashAlgorithm: String,\n            resultKey: ByteArray,\n            resultIv: ByteArray\n        ): ByteArray {\n            val targetKeySize = keySize + ivSize\n            val derivedBytes = ByteArray(targetKeySize * 4)\n            var numberOfDerivedWords = 0\n            var block: ByteArray? = null\n            val hasher = MessageDigest.getInstance(hashAlgorithm)\n            while (numberOfDerivedWords < targetKeySize) {\n                if (block != null) {\n                    hasher.update(block)\n                }\n                hasher.update(password)\n                block = hasher.digest(salt)\n                hasher.reset()\n                for (i in 1 until iterations) {\n                    block = hasher.digest(block)\n                    hasher.reset()\n                }\n                System.arraycopy(\n                    block, 0, derivedBytes, numberOfDerivedWords * 4,\n                    minOf(block?.size!!, (targetKeySize - numberOfDerivedWords) * 4)\n                )\n                numberOfDerivedWords += block.size / 4\n            }\n            System.arraycopy(derivedBytes, 0, resultKey, 0, keySize * 4)\n            System.arraycopy(derivedBytes, keySize * 4, resultIv, 0, ivSize * 4)\n            return derivedBytes\n        }\n\n    }\n\n    private val aes = AES()\n    private val gson = Gson()\n    private val app = Requests(baseClient = getBaseClient())\n    private val proxy = BuildConfig.PROXY_URL\n    private val headers = mapOf(\"X-Requested-With\" to \"XMLHttpRequest\")\n    private val baseUrl = \"https://gomovies.sx\"\n    suspend fun search(s: Int, ep:Int ,query: String,isMovie: Boolean,y :String) : Pair<String?,String?>{\n        val squery = query.lowercase().replace(\" \",\"-\")\n        val sources: Elements\n\n        val searchRes = app.get(\n            \"${proxy}https://gomovies.sx/search/${squery}\",\n            headers = headers\n        ).document\n\n        val search = searchRes.select(\"div.flw-item h2 a\")\n        val year = searchRes.select(\"div.flw-item div.fd-infor\").map{\n            it.getElementsByTag(\"span\")[0].text()\n        }\n\n        var mediaId = \"\"\n        var i = 0\n        for (se in search) {\n            if (se.attr(\"title\") == query && onConflict(se,isMovie,year, y,i)) {\n                mediaId = se.attr(\"href\").substringAfter(\"gomovies-\")\n                println(mediaId)\n                break\n            }\n            i++\n        }\n\n        if (mediaId == \"\") return Pair( null, null)\n        if(!isMovie) {\n            val seasons = app.get(\n                \"${proxy}https://gomovies.sx/ajax/v2/tv/seasons/${mediaId}\", headers = headers\n            ).document.select(\".ss-item\")\n\n//        for (s in seasons) {\n//            println(s)\n//        }\n            val dataId = seasons[s - 1].attr(\"data-id\")\n\n            val episodes = app.get(\n                \"${proxy}$baseUrl/ajax/season/episodes/${dataId}\", headers = headers\n            ).document.select(\".eps-item\")\n\n//            for (ep in episodes)\n//                println(ep)\n\n            val epDataId = episodes[ep - 1].attr(\"data-id\")\n\n            sources = app.get(\n                \"${proxy}$baseUrl/ajax/episode/servers/$epDataId\",\n                headers = headers\n            ).document.select(\"li.nav-item a\")\n        }else{\n            sources = app.get(\n                \"${proxy}$baseUrl/ajax/episode/list/$mediaId\",\n                headers = headers\n            ).document.select(\"li.nav-item a\")\n        }\n        var upCloudId = \"\"\n        for (source in sources) {\n            if (source.attr(\"title\").contains(\"UpCloud\")) upCloudId = if(!isMovie)source.attr(\"data-id\") else source.attr(\"data-linkid\")\n        }\n        if (upCloudId == \"\") return Pair( null, null)\n//        println(\"upcloudid below\")\n//        println(upCloudId)\n\n        val upCloudSource = app.get(\"${proxy}$baseUrl/ajax/sources/$upCloudId\").toString()\n        val upcloudSrc = gson.fromJson(upCloudSource, UpCloud::class.java)\n//        println(upcloudSrc.link)\n        upcloudSrc.link = upcloudSrc.link?.replace(\"?z=\", \"\")\n        val upDataID = upcloudSrc.link?.substringAfter(\"embed-4/\")\n        val streamRes = app.get(\n            \"https://rabbitstream.net/ajax/embed-4/getSources?id=${upDataID}\",\n            headers = headers,\n            referer = \"https://rabbitstream.net\"\n        ).toString()\n\n        val stream = gson.fromJson(streamRes, StreamRes::class.java)\n//        println(stream)\n\n        val sub = getSubs2(stream.tracks)\n\n\n        val scriptJs = app.get(\"https://rabbitstream.net/js/player/prod/e4-player.min.js\").toString()\n//        println(decryptionKeyResponse)\n\n//        val listType = object : TypeToken<List<List<Int>>>() {}.type\n        val decryptionKey: List<Pair<Int,Int>>? = extractKey(scriptJs)\n        if (decryptionKey.isNullOrEmpty()) println(\"Cant extract key\")\n//        println(decryptionKey)\n\n        var extractedKey = \"\"\n        var strippedSources = stream.sources\n        var totalledOffset = 0\n        decryptionKey?.forEach { pair ->\n            val start = pair.first + totalledOffset;\n            val end = start + pair.second;\n            extractedKey += stream.sources.slice(start until end)\n            strippedSources = strippedSources.replace(\n                stream.sources.substring(start, end),\n                \"\"\n            )\n            totalledOffset += pair.second\n        }\n        val key = extractedKey\n        val data = strippedSources\n        val decryptedStream = aes.decrypt(data, key)\n//        println(decryptedStream)\n        val jsonArray = JSONArray(decryptedStream)\n        val videoSrc = gson.fromJson(jsonArray.getJSONObject(0).toString(),VidFile::class.java)\n        println(videoSrc)\n        return Pair(videoSrc.file, sub)\n\n    }\n    private fun onConflict(item : Element, movie: Boolean, year: List<String>, y: String, i: Int): Boolean {\n        return if(movie && item.attr(\"href\").contains(\"/movie/\") && year[i] == y ) true\n        else !movie && item.attr(\"href\").contains(\"/tv/\")\n    }\n\n    private fun extractKey(script: String): List<Pair<Int, Int>>? {\n        val startOfSwitch = script.lastIndexOf(\"switch\")\n        val endOfCases = script.indexOf(\"partKeyStartPosition\")\n        val switchBody = script.slice(startOfSwitch until endOfCases)\n\n        val nums = mutableListOf<Pair<Int, Int>>()\n        val matches = Regex(\":[a-zA-Z0-9]+=([a-zA-Z0-9]+),[a-zA-Z0-9]+=([a-zA-Z0-9]+);\").findAll(switchBody)\n        for (match in matches) {\n            val innerNumbers = mutableListOf<Int>()\n            for (varMatch in listOf(match.groupValues[1], match.groupValues[2])) {\n                val regex = Regex(\"${varMatch}=0x([a-zA-Z0-9]+)\")\n                val varMatches = regex.findAll(script).toList()\n                val lastMatch = varMatches.lastOrNull()\n                if (lastMatch == null) {\n                    return null\n                }\n                val number = Integer.parseInt(lastMatch.groupValues[1], 16)\n                innerNumbers.add(number)\n            }\n\n            nums.add(Pair(innerNumbers[0], innerNumbers[1]))\n        }\n\n        return nums\n    }\n\n\n    data class StreamRes(\n\n        val server: Int,\n        val sources: String,\n        val tracks: ArrayList<Track>\n    )\n\n    data class Track(\n        val file: String,\n        val kind: String,\n        val label: String\n    )\n\n    data class UpCloud(\n        val type: String?,\n        var link: String?,\n        val sources: ArrayList<String>?,\n        val tracks: ArrayList<String>?,\n        val title: String?\n    )\n\n    data class VidFile(\n        val file: String?,\n        val type: String?\n    )\n\n    private fun getSubs(tracks: ArrayList<Track>?): ArrayList<String>? {\n        if(tracks == null) return null\n        return if (tracks.size == 1){\n            arrayListOf(tracks[0].file)\n        } else{\n            val subs = arrayListOf<String>()\n            for(track in tracks){\n                if(track.label.contains(\"English\"))\n                    subs.add(track.file)\n            }\n            subs\n        }\n    }\n\n    private fun getSubs2(tracks: ArrayList<Track>?): String? {\n        if(tracks == null) return null\n        val subUrl : MutableMap<String,String> = mutableMapOf()\n        tracks.forEach {\n            subUrl[it.label] = it.file\n        }\n        return gson.toJson(subUrl)\n    }\n}"
  },
  {
    "path": "app/src/main/java/com/demomiru/tokeiv2/utils/GogoAnime.kt",
    "content": "package com.demomiru.tokeiv2.utils\n\nimport android.annotation.SuppressLint\nimport android.os.Parcel\nimport android.os.Parcelable\n\nimport android.util.Log\nimport com.demomiru.tokeiv2.watching.VideoData\n\nimport com.fasterxml.jackson.annotation.JsonProperty\nimport com.google.gson.Gson\nimport com.lagradost.nicehttp.Requests\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.withContext\nimport org.jsoup.Jsoup\nimport org.jsoup.nodes.Document\nimport java.io.Serializable\nimport java.net.URI\nimport java.util.Base64\nimport javax.crypto.Cipher\nimport javax.crypto.spec.IvParameterSpec\nimport javax.crypto.spec.SecretKeySpec\nimport kotlin.math.ceil\n\nclass GogoAnime{\n\n    private val gson = Gson()\n    private val app = Requests()\n    private fun getKey(id: String): String? {\n        return normalSafeApiCall {\n            id.map {\n                it.code.toString(16)\n            }.joinToString(\"\").substring(0, 32)\n        }\n    }\n\n    private fun <T> normalSafeApiCall(apiCall: () -> T): T? {\n        return try {\n            apiCall.invoke()\n        } catch (throwable: Throwable) {\n            logError(throwable)\n            return null\n        }\n    }\n\n    private fun logError(throwable: Throwable) {\n        Log.d(\"ApiError\", \"-------------------------------------------------------------------\")\n        Log.d(\"ApiError\", \"safeApiCall: \" + throwable.localizedMessage)\n        Log.d(\"ApiError\", \"safeApiCall: \" + throwable.message)\n        throwable.printStackTrace()\n        Log.d(\"ApiError\", \"-------------------------------------------------------------------\")\n    }\n\n\n    val qualityRegex = Regex(\"(\\\\d+)P\")\n\n    // https://github.com/saikou-app/saikou/blob/3e756bd8e876ad7a9318b17110526880525a5cd3/app/src/main/java/ani/saikou/anime/source/extractors/GogoCDN.kt#L60\n    // No Licence on the function\n    private fun cryptoHandler(\n        string: String,\n        iv: String,\n        secretKeyString: String,\n        encrypt: Boolean = true\n    ): String {\n        //println(\"IV: $iv, Key: $secretKeyString, encrypt: $encrypt, Message: $string\")\n        val ivParameterSpec = IvParameterSpec(iv.toByteArray())\n        val secretKey = SecretKeySpec(secretKeyString.toByteArray(), \"AES\")\n        val cipher = Cipher.getInstance(\"AES/CBC/PKCS5Padding\")\n        return if (!encrypt) {\n            cipher.init(Cipher.DECRYPT_MODE, secretKey, ivParameterSpec)\n            String(cipher.doFinal(base64DecodeArray(string)))\n        } else {\n            cipher.init(Cipher.ENCRYPT_MODE, secretKey, ivParameterSpec)\n            base64Encode(cipher.doFinal(string.toByteArray()))\n        }\n    }\n\n    private fun String.decodeHex(): ByteArray {\n        check(length % 2 == 0) { \"Must have an even length\" }\n        return chunked(2)\n            .map { it.toInt(16).toByte() }\n            .toByteArray()\n    }\n\n    private fun base64Decode(encodedString: String): String {\n        return try {\n            val decodedBytes = android.util.Base64.decode(encodedString, android.util.Base64.DEFAULT)\n            val decodedString = String(decodedBytes, Charsets.UTF_8)\n            decodedString\n        } catch (e: Exception) {\n            e.printStackTrace()\n            \"\"\n        }\n    }\n\n\n    suspend fun extractVidstream(\n        iframeUrl: String,\n        mainApiName: String,\n        iv: String?,\n        secretKey: String?,\n        secretDecryptKey: String?,\n        isUsingAdaptiveKeys: Boolean,\n        isUsingAdaptiveData: Boolean,\n        iframeDocument: Document? = null\n    ): String{\n\n        if ((iv == null || secretKey == null || secretDecryptKey == null) && !isUsingAdaptiveKeys)\n            return \"\"\n\n        val id = Regex(\"id=([^&]+)\").find(iframeUrl)!!.value.removePrefix(\"id=\")\n\n        var document: Document? = iframeDocument\n        val foundIv =\n            iv ?: (document ?: app.get(iframeUrl).document.also { document = it })\n                .select(\"\"\"div.wrapper[class*=container]\"\"\")\n                .attr(\"class\").split(\"-\").lastOrNull() ?: return \"\"\n        val foundKey = secretKey ?: getKey(base64Decode(id) + foundIv) ?: return \"\"\n        val foundDecryptKey = secretDecryptKey ?: foundKey\n\n        val uri = URI(iframeUrl)\n        val mainUrl = \"https://\" + uri.host\n\n        val encryptedId = cryptoHandler(id, foundIv, foundKey)\n        val encryptRequestData = if (isUsingAdaptiveData) {\n            // Only fetch the document if necessary\n            val realDocument = document ?: app.get(iframeUrl).document\n            val dataEncrypted =\n                realDocument.select(\"script[data-name='episode']\").attr(\"data-value\")\n            val headers = cryptoHandler(dataEncrypted, foundIv, foundKey, false)\n            \"id=$encryptedId&alias=$id&\" + headers.substringAfter(\"&\")\n        } else {\n            \"id=$encryptedId&alias=$id\"\n        }\n\n        val jsonResponse =\n            app.get(\n                \"$mainUrl/encrypt-ajax.php?$encryptRequestData\",\n                headers = mapOf(\"X-Requested-With\" to \"XMLHttpRequest\")\n            )\n        val dataencrypted =\n            jsonResponse.text.substringAfter(\"{\\\"data\\\":\\\"\").substringBefore(\"\\\"}\")\n        val datadecrypted = cryptoHandler(dataencrypted, foundIv, foundDecryptKey, false)\n        val sources = gson.fromJson(datadecrypted, GogoSources::class.java)\n\n        sources.source?.forEach {\n            if(it.file.isBlank())\n                return@forEach\n             return it.file\n//            Log.i(\"inside extract\",it.file)\n        }\n        sources.sourceBk?.forEach {\n//            invokeGogoSource(it, callback)\n            if(it.file.isBlank())\n                return@forEach\n            return it.file\n//            Log.i(\"inside extract sourceBk\",it.file)\n        }\n        return \"\"\n    }\n\n    private var mainUrl = \"https://anitaku.to\"\n//        \"https://gogoanime.lu\"\n    private var name = \"GogoAnime\"\n    private val hasQuickSearch = false\n    private val hasMainPage = true\n\n\n    val headers = mapOf(\n        \"authority\" to \"ajax.gogocdn.net\",\n        \"sec-ch-ua\" to \"\\\"Google Chrome\\\";v=\\\"89\\\", \\\"Chromium\\\";v=\\\"89\\\", \\\";Not A Brand\\\";v=\\\"99\\\"\",\n        \"accept\" to \"text/html, */*; q=0.01\",\n        \"dnt\" to \"1\",\n        \"sec-ch-ua-mobile\" to \"?0\",\n        \"user-agent\" to \"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36\",\n        \"origin\" to mainUrl,\n        \"sec-fetch-site\" to \"cross-site\",\n        \"sec-fetch-mode\" to \"cors\",\n        \"sec-fetch-dest\" to \"empty\",\n        \"referer\" to \"$mainUrl/\"\n    )\n    val parseRegex =\n        Regex(\"\"\"<li>\\s*\\n.*\\n.*<a\\s*href=[\"'](.*?-episode-(\\d+))[\"']\\s*title=[\"'](.*?)[\"']>\\n.*?img src=\"(.*?)\"\"\"\")\n\n\n    suspend fun search(query: String): ArrayList<AnimeSearchResponse> {\n        val link = \"$mainUrl/search.html?keyword=$query\"\n        val html = app.get(link).text\n        val doc = Jsoup.parse(html)\n\n        val episodes = doc.select(\"\"\".last_episodes li\"\"\").mapNotNull {\n            AnimeSearchResponse(\n                it.selectFirst(\".name\")?.text()?.replace(\" (Dub)\", \"\") ?: return@mapNotNull null,\n                fixUrl(it.selectFirst(\".name > a\")?.attr(\"href\") ?: return@mapNotNull null),\n                this.name,\n                0,\n                it.selectFirst(\"img\")?.attr(\"src\"),\n                it.selectFirst(\".released\")?.text()?.split(\":\")?.getOrNull(1)?.trim()\n                    ?.toIntOrNull(),\n                it.selectFirst(\".name\")?.text()?.contains(\"Dub\")\n            )\n        }\n\n        return ArrayList(episodes)\n    }\n\n    private fun fixUrl(url: String): String {\n        if (url.startsWith(\"http\") ||\n            // Do not fix JSON objects when passed as urls.\n            url.startsWith(\"{\\\"\")\n        ) {\n            return url\n        }\n        if (url.isEmpty()) {\n            return \"\"\n        }\n\n        val startsWithNoHttp = url.startsWith(\"//\")\n        if (startsWithNoHttp) {\n            return \"https:$url\"\n        } else {\n            if (url.startsWith('/')) {\n                return mainUrl + url\n            }\n            return \"$mainUrl/$url\"\n        }\n    }\n\n    private fun getProperAnimeLink(uri: String): String {\n        if (uri.contains(\"-episode\")) {\n            val split = uri.split(\"/\")\n            val slug = split[split.size - 1].split(\"-episode\")[0]\n            return \"$mainUrl/category/$slug\"\n        }\n        return uri\n    }\n\n    data class AnimeDetails(\n        val title: String? = null,\n        val poster: String? = null,\n        val description: String? = null,\n        val genre: ArrayList<String>? = null,\n        val year: Int? = null,\n        val status: String? = null,\n        val nativeName: String? = null,\n        val type: String? = null,\n        val episodes : List<Episode>? = null\n    ): Parcelable {\n\n        constructor(parcel: Parcel) : this(\n            parcel.readString(),\n            parcel.readString(),\n            parcel.readString(),\n            parcel.createStringArrayList(),\n            parcel.readValue(Int::class.java.classLoader) as? Int,\n            parcel.readString(),\n            parcel.readString(),\n            parcel.readString(),\n            parcel.createTypedArrayList(Episode.CREATOR)\n        )\n\n        override fun writeToParcel(parcel: Parcel, flags: Int) {\n            parcel.writeString(title)\n            parcel.writeString(poster)\n            parcel.writeString(description)\n            parcel.writeStringList(genre)\n            parcel.writeValue(year)\n            parcel.writeString(status)\n            parcel.writeString(nativeName)\n            parcel.writeString(type)\n            parcel.writeTypedList(episodes)\n        }\n\n        override fun describeContents(): Int {\n            return 0\n        }\n\n        companion object CREATOR : Parcelable.Creator<AnimeDetails> {\n            override fun createFromParcel(parcel: Parcel): AnimeDetails {\n                return AnimeDetails(parcel)\n            }\n\n            override fun newArray(size: Int): Array<AnimeDetails?> {\n                return arrayOfNulls(size)\n            }\n        }\n    }\n\n    suspend fun load(url: String): AnimeDetails {\n        val link = getProperAnimeLink(url)\n\n        val episodeloadApi = \"https://ajax.gogocdn.net/ajax/load-list-episode\"\n        val doc = app.get(link).document\n\n        val animeBody = doc.selectFirst(\".anime_info_body_bg\")\n        val title = animeBody?.selectFirst(\"h1\")!!.text()\n        val poster = animeBody.selectFirst(\"img\")?.attr(\"src\")\n        var description: String? = null\n        val genre = ArrayList<String>()\n        var year: Int? = null\n        var status: String? = null\n        var nativeName: String? = null\n        var type: String? = null\n\n        animeBody.select(\"p.type\").forEach { pType ->\n            when (pType.selectFirst(\"span\")?.text()?.trim()) {\n                \"Plot Summary:\" -> {\n                    description = pType.text().replace(\"Plot Summary:\", \"\").trim()\n                }\n\n                \"Genre:\" -> {\n                    genre.addAll(pType.select(\"a\").map {\n                        it.attr(\"title\")\n                    })\n                }\n\n                \"Released:\" -> {\n                    year = pType.text().replace(\"Released:\", \"\").trim().toIntOrNull()\n                }\n\n                \"Status:\" -> {\n                    status = pType.text().replace(\"Status:\", \"\").trim()\n                }\n\n                \"Other name:\" -> {\n                    nativeName = pType.text().replace(\"Other name:\", \"\").trim()\n                }\n\n                \"Type:\" -> {\n                    type = pType.text().replace(\"type:\", \"\").trim()\n                }\n            }\n        }\n\n\n        val animeId = doc.selectFirst(\"#movie_id\")!!.attr(\"value\")\n        val params = mapOf(\"ep_start\" to \"0\", \"ep_end\" to \"2000\", \"id\" to animeId)\n\n        val episodes = app.get(episodeloadApi, params = params).document.select(\"a\").map {\n            Episode(\n                fixUrl(it.attr(\"href\").trim()),\n                \"Episode \" + it.selectFirst(\".name\")?.text()?.replace(\"EP\", \"\")?.trim()\n            )\n        }.reversed()\n        return AnimeDetails(\n            title,\n            poster,\n            description,\n            genre,\n            year,\n            status,\n            nativeName,\n            type,\n            episodes\n        )\n    }\n\n    private fun fixUrlNull(url: String?): String? {\n        if (url.isNullOrEmpty()) {\n            return null\n        }\n        return fixUrl(url)\n    }\n\n    suspend fun extractVideos(\n        uri: String,\n    ) : String {\n        val doc = app.get(uri).document\n        var url = \"\"\n        val iframe = fixUrlNull(doc.selectFirst(\"div.play-video > iframe\")?.attr(\"src\")) ?: return \"\"\n        val link = iframe.replace(\"streaming.php\", \"download\")\n        val page = app.get(link, headers = mapOf(\"Referer\" to iframe))\n        page.document.select(\".dowload > a\").forEach {\n            if (it.hasAttr(\"download\")) {\n                val qual = if (it.text()\n                        .contains(\"HDP\")\n                ) \"1080\" else qualityRegex.find(it.text())?.destructured?.component1()\n                    .toString()\n            }else {\n                url = it.attr(\"href\")\n\n            }\n            Log.i(\"inside page\",it.attr(\"href\"))\n        }\n\n        val streamingResponse = app.get(iframe, headers = mapOf(\"Referer\" to iframe))\n        val streamingDocument = streamingResponse.document\n        streamingDocument.select(\".list-server-items > .linkserver\")\n            .forEach { element ->\n                val status = element.attr(\"data-status\") ?: return@forEach\n                if (status != \"1\") return@forEach\n                val data = element.attr(\"data-video\") ?: return@forEach\n            }\n        val iv = \"3134003223491201\"\n        val secretKey = \"37911490979715163134003223491201\"\n        val secretDecryptKey = \"54674138327930866480207815084989\"\n        return extractVidstream(\n            iframe,\n            this.name,\n            iv,\n            secretKey,\n            secretDecryptKey,\n            isUsingAdaptiveKeys = false,\n            isUsingAdaptiveData = true\n        )\n\n\n    }\n\n    data class Episode(\n        val url : String,\n        val name: String\n    ): Parcelable {\n\n        constructor(parcel: Parcel) : this(\n            parcel.readString() ?: \"\",\n            parcel.readString() ?: \"\"\n        )\n\n        override fun writeToParcel(parcel: Parcel, flags: Int) {\n            parcel.writeString(url)\n            parcel.writeString(name)\n        }\n\n        override fun describeContents(): Int {\n            return 0\n        }\n\n        companion object CREATOR : Parcelable.Creator<Episode> {\n            override fun createFromParcel(parcel: Parcel): Episode {\n                return Episode(parcel)\n            }\n\n            override fun newArray(size: Int): Array<Episode?> {\n                return arrayOfNulls(size)\n            }\n        }\n    }\n\n    data class AnimeSearchResponse(\n        val name: String,\n        val url: String,\n        val apiName: String,\n        var type: Int? = null,\n\n        var posterUrl: String? = null,\n        var year: Int? = null,\n        val dub: Boolean? = false,\n\n//        var otherName: String? = null,\n//        var episodes: MutableList<String> = mutableListOf(),\n//\n//        var id: Int? = null,\n//        var quality: String? = null,\n//        var posterHeaders: Map<String, String>? = null,\n    )\n\n\n    @SuppressLint(\"NewApi\")\n    private fun base64DecodeArray(string: String): ByteArray {\n        return try {\n            android.util.Base64.decode(string, android.util.Base64.DEFAULT)\n        } catch (e: Exception) {\n            Base64.getDecoder().decode(string)\n        }\n    }\n\n    @SuppressLint(\"NewApi\")\n    private fun base64Encode(array: ByteArray): String {\n        return try {\n            String(android.util.Base64.encode(array, android.util.Base64.NO_WRAP), Charsets.ISO_8859_1)\n        } catch (e: Exception) {\n            String(Base64.getEncoder().encode(array))\n        }\n    }\n\n    fun onCreate() {\n//        lifecycleScope.launch {\n//            val searchResults = search(\"Link Click\")\n//            println(searchResults)\n//            val episodeResults = load(searchResults[0].url)\n//            println(episodeResults)\n//            val episodeStream = extractVideos(episodeResults.episodes[0].url)\n//        }\n    }\n\n\n    data class GogoSources(\n        @JsonProperty(\"source\") val source: List<GogoSource>?,\n        @JsonProperty(\"sourceBk\") val sourceBk: List<GogoSource>?,\n        //val track: List<Any?>,\n        //val advertising: List<Any?>,\n        //val linkiframe: String\n    )\n\n    data class GogoSource(\n        @JsonProperty(\"file\") val file: String,\n        @JsonProperty(\"label\") val label: String?,\n        @JsonProperty(\"type\") val type: String?,\n        @JsonProperty(\"default\") val default: String? = null\n    )\n}\n\n//lifecycleScope.launch {\n//    val gogoSrc = GogoAnime()\n//    val videoUrl = gogoSrc.extractVideos(it.url)\n//\n//    withContext(Dispatchers.Main) {\n//        val ep = ceil(it.name.replace(\"Episode \", \"\").toDouble()).toInt()\n//        val data = VideoData(\n//            0,\n//            animeDetails.poster!!,\n//            0,\n//            null,\n//            animeDetails.title!!,\n//            ep,\n//            1,\n//            \"anime\",\n//            videoUrl,\n//            null,\n//            listOf(),\n//            episodes?.size\n//        )\n//        val intent = passVideoData(\n//            data, requireContext()\n//        )\n//        intent.putExtra(\"animeUrl\", it.url)\n//        startActivity(intent)\n//    }\n//}"
  },
  {
    "path": "app/src/main/java/com/demomiru/tokeiv2/utils/OpenSubtitle.kt",
    "content": "package com.demomiru.tokeiv2.utils\n\nimport android.content.Context\nimport android.net.Uri\nimport android.view.LayoutInflater\nimport android.view.View\nimport android.view.ViewGroup\nimport android.widget.CheckedTextView\nimport androidx.media3.common.C\nimport androidx.media3.common.MediaItem\nimport androidx.media3.common.MimeTypes\nimport androidx.media3.datasource.DefaultDataSourceFactory\nimport androidx.media3.exoplayer.source.SingleSampleMediaSource\nimport androidx.recyclerview.widget.DiffUtil\nimport androidx.recyclerview.widget.RecyclerView\nimport com.demomiru.tokeiv2.R\nimport com.demomiru.tokeiv2.subtitles.SubtitleConfig\nimport com.google.gson.Gson\nimport com.lagradost.nicehttp.Requests\nimport okhttp3.MediaType.Companion.toMediaType\nimport okhttp3.RequestBody.Companion.toRequestBody\nimport okio.GzipSource\nimport okio.buffer\nimport org.checkerframework.checker.units.qual.s\nimport org.json.JSONArray\nimport java.io.File\nimport java.io.FileInputStream\nimport java.io.FileOutputStream\nimport java.io.IOException\nimport java.util.Locale\n\ndata class Languages(\n    val data: ArrayList<Data> = arrayListOf()\n){\n    data class Data(\n        val language_code: String,\n        val language_name: String\n    )\n}\n\ndata class DownloadSub(\n    val link: String,\n    val file_name: String,\n    val remaining: String\n)\n\n\ndata class SubRest(\n    val SubDownloadLink: String,\n    val SubFileName:String,\n)\n\n\n\nclass OpenSubtitle(private val applicationContext: Context) {\n    private val app = Requests()\n    private val gson = Gson()\n\n    private val headers = mapOf(\n        \"Api-Key\" to \"XeM3ngDLQIPF6ySf37z6PIIzTbAMIb8x\",\n        \"Content-Type\" to \"application/json\",\n        \"Accept\" to \"application/json\",\n        \"User-Agent\" to \"Tokeiv2\"\n//        \"User-Agent\" to \"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:101.0) Gecko/20100101 Firefox/101.0\"\n    )\n\n    val sHeaders = mapOf(\n        \"User-Agent\" to \"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:101.0) Gecko/20100101 Firefox/101.0\",\n        \"X-User-Agent\" to \"trailers.to-UA\"\n    )\n\n    val subUrl : MutableList<String> = mutableListOf()\n\n    suspend fun getLang() : Map<String,String>{\n           val langs =\n               app.get(\"https://api.opensubtitles.com/api/v1/infos/languages\", headers = headers)\n                   .toString()\n           val res = gson.fromJson(langs, Languages::class.java)\n\n           val langMap = mutableMapOf<String, String>()\n           res.data.forEach {\n               langMap[it.language_name] = it.language_name.substring(0, 3)\n                   .lowercase(Locale.getDefault())\n           }\n           return langMap\n    }\n\n\n    private fun makeSRT(content:String, lang: String, fileName:String) {\n        val context: Context = applicationContext\n\n        try {\n            // Create a temporary file in the app's internal cache directory\n            val tempFile = File(context.cacheDir, \"$fileName.srt\")\n            FileOutputStream(tempFile).use { outputStream ->\n                outputStream.write(content.toByteArray())\n            }\n\n            // You now have a temporary file in the app's internal cache directory\n            // You can use tempFile to reference it further\n        } catch (e: IOException) {\n            e.printStackTrace()\n        }\n    }\n\n    fun getSRT(file: String) : Uri?{\n        val context: Context = applicationContext\n\n        try {\n            // Specify the name of the temporary file\n\n            // Create a File object for the temporary file\n            val tempFile = File(context.cacheDir, \"$file.srt\")\n\n            // Check if the file exists before attempting to read it\n            if (tempFile.exists()) {\n                // Read the contents of the file\n                val content = FileInputStream(tempFile).bufferedReader().use { it.readText() }\n\n                // Display the content (e.g., in a TextView)\n                return Uri.fromFile(tempFile)\n//                println(content)\n            } else {\n                // The file does not exist\n                // Handle this case as needed\n\n            }\n        } catch (e: IOException) {\n            e.printStackTrace()\n        }\n        return null\n    }\n//\n//    suspend fun getSampleSource(uri: Uri?){\n//        val subtitleMediaSource =\n//            SingleSampleMediaSource.Factory(DefaultDataSourceFactory(this@VideoPlayActivity,\"user-agent\")).createMediaSource(\n//                MediaItem.SubtitleConfiguration.Builder(oS.getSRT(it[0])!!)\n//                    .setMimeType(MimeTypes.APPLICATION_SUBRIP)\n//                    .setLanguage(\"en\")\n//                    .setSelectionFlags(C.SELECTION_FLAG_DEFAULT)\n//                    .build(),\n//                C.TIME_UNSET\n//            )\n//        subtitleConfig.add(SubtitleConfig(subtitleMediaSource, language = it[0]))\n//    }\n\n    suspend fun searchSubs(id:String, langCode: String, s: Int = 1, e: Int = 1 ,isMovie: Boolean = true): List<SubRest>{\n//        val searchResults = app.get(\"https://api.opensubtitles.com/api/v1/subtitles?tmdb_id=$id&type=$type&languages=$langCode&order_by=download_count\",\n//            headers = headers).toString()\n\n        val subs = arrayListOf<SubRest>()\n        val getUrl = if(isMovie)\"https://rest.opensubtitles.org/search/imdbid-$id/sublanguageid-$langCode\" else  \"https://rest.opensubtitles.org/search/episode-$e/imdbid-$id/season-$s/sublanguageid-$langCode\"\n        val searchResults = app.get(getUrl, headers = sHeaders).toString()\n        val jsonArray = JSONArray(searchResults)\n        for( i in 0 until jsonArray.length())\n        {\n            subs.add(gson.fromJson(jsonArray.getJSONObject(i).toString(), SubRest::class.java))\n        }\n        println(subs)\n        return subs.toList()\n    }\n\n//    suspend fun getSub(fileId: String): String{\n//\n//        val mediaType = \"application/json\".toMediaType()\n//        val body = \"{\\r\\n  \\\"file_id\\\": ${fileId}\\r\\n}\".toRequestBody(mediaType)\n//        val res = app.post(\"https://api.opensubtitles.com/api/v1/download\",headers = headers ,requestBody = body).toString()\n//        val download = gson.fromJson(res,DownloadSub::class.java)\n//        println(download.remaining)\n//        return download.link\n//\n//    }\n\n    suspend fun getSub2(link:String, lang: String,fileName: String){\n        val res = app.get(link).okhttpResponse\n        val gzippedSource = GzipSource(res.body.source())\n        val decompressedString = gzippedSource.buffer().readUtf8()\n        makeSRT(decompressedString,lang, fileName)\n    }\n}\n\nclass SubAdapter(private val onClick :(String)->Unit):\n    androidx.recyclerview.widget.ListAdapter<SubRest, SubAdapter.ViewHolder>(SearchDiffCallBack) {\n\n    private var selectedPosition = -1\n\n    private fun setSelectedPosition(position: Int) {\n        selectedPosition = position\n        notifyDataSetChanged()\n    }\n    inner class ViewHolder(view: View) : RecyclerView.ViewHolder(view){\n        val subTv: CheckedTextView = itemView.findViewById(R.id.track_quality)\n    }\n    object SearchDiffCallBack : DiffUtil.ItemCallback<SubRest>() {\n        override fun areItemsTheSame(oldItem: SubRest, newItem: SubRest): Boolean {\n            return oldItem === newItem\n        }\n\n        override fun areContentsTheSame(oldItem: SubRest, newItem: SubRest): Boolean {\n            return oldItem == newItem\n        }\n    }\n\n    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {\n        val view = LayoutInflater.from(parent.context).inflate(R.layout.track_item,parent,false)\n        return ViewHolder(view)\n    }\n\n\n    override fun onBindViewHolder(holder: ViewHolder, position: Int) {\n        val sub = getItem(position)\n        holder.subTv.isChecked = position == selectedPosition\n        holder.subTv.text = sub.SubFileName\n        holder.itemView.setOnClickListener {\n            setSelectedPosition(holder.bindingAdapterPosition)\n            onClick(sub.SubDownloadLink)\n        }\n    }\n}\n\n"
  },
  {
    "path": "app/src/main/java/com/demomiru/tokeiv2/utils/SmashyStream.kt",
    "content": "package com.demomiru.tokeiv2.utils\n\n\nimport android.icu.text.CaseMap.Title\nimport com.demomiru.tokeiv2.BuildConfig\nimport com.google.gson.Gson\nimport com.lagradost.nicehttp.Requests\n\n\ndata class Video1(\n    val sourceUrls: ArrayList<String> = arrayListOf(),\n    val subtitleUrls: String? = null\n)\n\ndata class Video3(\n    val sourceUrls: ArrayList<Sources> = arrayListOf(),\n){\n    data class Sources(\n        val file: String,\n        val title: String,\n    )\n}\nclass SmashyStream{\n\n    private val app = Requests(baseClient = getBaseClient())\n    private val gson = Gson()\n    private val proxy = BuildConfig.PROXY_URL\n    suspend fun getLink(isMovie: Boolean = false,id: String,s: Int,e:Int,src:String =\"en\") : Pair<String?,String?>{\n        val getUrl = if(!isMovie) \"https://embed.smashystream.com/playere.php?tmdb=$id&season=$s&episode=$e\" else \"https://embed.smashystream.com/playere.php?tmdb=$id\"\n        try {\n            val sources =\n                app.get(\n                    \"${proxy}$getUrl\",\n                    referer = \"https://smashystream.xyz/\"\n                ).document\n                    .select(\"div.dropdown-menu a.server.dropdown-item\").map {\n                        it.attr(\"data-url\")\n                    }\n            println(sources)\n\n            val srcUrl = if(src == \"en\")sources.find {\n                it.contains(\"video1\")\n            }!!\n            else sources.find {\n                it.contains(\"video3\")\n            }!!\n\n            val streamRes = app.get(\n                srcUrl,\n                referer = getUrl\n            ).toString()\n//                .document.getElementsByTag(\"script\")\n            println(streamRes)\n\n            if(src == \"en\") {\n                val streamParsed = gson.fromJson(streamRes, Video1::class.java)\n                if (streamParsed.sourceUrls[0] == \"null\")\n                    return Pair(null, null)\n\n                var subSource: String? = null\n                if (streamParsed.subtitleUrls != null) {\n                    val subSources = streamParsed.subtitleUrls.split(\",\").toMutableList()\n                    subSources.remove(\"\")\n                    val langToUrlMap = mutableMapOf<String, String>()\n                    for (subSource in subSources) {\n                        val lang =\n                            subSource.substring(subSource.indexOf(\"[\") + 1, subSource.indexOf(\"]\"))\n                        val url = subSource.substring(subSource.indexOf(\"]\") + 1).replace(\"\\\\\", \"\")\n                        langToUrlMap[lang] = url\n                    }\n                    subSource = gson.toJson(langToUrlMap)\n\n//                    langToUrlMap.forEach {\n//                        if (it.key.contains(\"English\"))\n//                            subSource = it.value\n//                    }\n                    println(\"Sub: $subSource\")\n                }\n                return Pair(streamParsed.sourceUrls[0], subSource)\n            }else\n            {\n                val streamParsed = gson.fromJson(streamRes, Video3::class.java)\n                return Pair(streamParsed.sourceUrls[0].file,null)\n            }\n        }catch (e: Exception){\n            e.printStackTrace()\n            return Pair(null,null)\n        }\n    }\n}"
  },
  {
    "path": "app/src/main/java/com/demomiru/tokeiv2/utils/SuperstreamUtils.kt",
    "content": "package com.demomiru.tokeiv2.utils\n\n\nimport android.util.Base64\n\nimport com.demomiru.tokeiv2.utils.SuperstreamUtils.CipherUtils.getVerify\nimport com.fasterxml.jackson.annotation.JsonProperty\nimport com.google.gson.Gson\nimport com.lagradost.nicehttp.NiceResponse\nimport com.lagradost.nicehttp.Requests\n\nimport java.nio.charset.StandardCharsets\nimport java.security.MessageDigest\nimport java.security.NoSuchAlgorithmException\nimport javax.crypto.Cipher\nimport javax.crypto.spec.IvParameterSpec\nimport javax.crypto.spec.SecretKeySpec\n\nclass SuperstreamUtils() {\n    private val app = Requests(baseClient = getBaseClient())\n    private val unixTime = System.currentTimeMillis()/1000L\n    private val gson = Gson()\n//    private var episode: Int? = null\n//    private var season : Int? = null\n\n    private fun base64Decode(encodedString: String): String {\n        return try {\n            val decodedBytes = Base64.decode(encodedString, Base64.DEFAULT)\n            val decodedString = String(decodedBytes, Charsets.UTF_8)\n            decodedString\n        } catch (e: Exception) {\n            e.printStackTrace()\n            \"\"\n        }\n    }\n\n    private val headers = mapOf(\n        \"Platform\" to \"android\",\n        \"Accept\" to \"charset=utf-8\",\n    )\n\n    private fun randomToken(): String {\n        return (0..31).joinToString(\"\") {\n            (('0'..'9') + ('a'..'f')).random().toString()\n        }\n    }\n    private val token = randomToken()\n\n    private val iv = base64Decode(\"d0VpcGhUbiE=\")\n    private val key = base64Decode(\"MTIzZDZjZWRmNjI2ZHk1NDIzM2FhMXc2\")\n\n    private val baseApiUrl = base64Decode(\"aHR0cHM6Ly9zaG93Ym94LnNoZWd1Lm5ldA==\")\n    private val apiUrl =\n        \"$baseApiUrl${base64Decode(\"L2FwaS9hcGlfY2xpZW50L2luZGV4Lw==\")}\"\n\n    private val secondApiUrl =\n        base64Decode(\"aHR0cHM6Ly9tYnBhcGkuc2hlZ3UubmV0L2FwaS9hcGlfY2xpZW50L2luZGV4Lw==\")\n\n    private val appKey = base64Decode(\"bW92aWVib3g=\")\n    private val appId = base64Decode(\"Y29tLnRkby5zaG93Ym94\")\n    private val appIdSecond = base64Decode(\"Y29tLm1vdmllYm94cHJvLmFuZHJvaWQ=\")\n    private val appVersion = \"14.7\"\n    private val appVersionCode = \"160\"\n\n    private object CipherUtils {\n        private const val ALGORITHM = \"DESede\"\n        private const val TRANSFORMATION = \"DESede/CBC/PKCS5Padding\"\n        fun encrypt(str: String, key: String, iv: String): String? {\n            return try {\n                val cipher: Cipher = Cipher.getInstance(TRANSFORMATION)\n                val bArr = ByteArray(24)\n                val bytes: ByteArray = key.toByteArray()\n                var length = if (bytes.size <= 24) bytes.size else 24\n                System.arraycopy(bytes, 0, bArr, 0, length)\n                while (length < 24) {\n                    bArr[length] = 0\n                    length++\n                }\n                cipher.init(\n                    Cipher.ENCRYPT_MODE,\n                    SecretKeySpec(bArr, ALGORITHM),\n                    IvParameterSpec(iv.toByteArray())\n                )\n\n                String(Base64.encode(cipher.doFinal(str.toByteArray()), 2), StandardCharsets.UTF_8)\n            } catch (e: Exception) {\n                e.printStackTrace()\n                null\n            }\n        }\n\n        // Useful for deobfuscation\n        fun decrypt(str: String, key: String, iv: String): String? {\n            return try {\n                val cipher: Cipher = Cipher.getInstance(TRANSFORMATION)\n                val bArr = ByteArray(24)\n                val bytes: ByteArray = key.toByteArray()\n                var length = if (bytes.size <= 24) bytes.size else 24\n                System.arraycopy(bytes, 0, bArr, 0, length)\n                while (length < 24) {\n                    bArr[length] = 0\n                    length++\n                }\n                cipher.init(\n                    Cipher.DECRYPT_MODE,\n                    SecretKeySpec(bArr, ALGORITHM),\n                    IvParameterSpec(iv.toByteArray())\n                )\n                val inputStr = Base64.decode(str.toByteArray(), Base64.DEFAULT)\n                cipher.doFinal(inputStr).decodeToString()\n            } catch (e: Exception) {\n                e.printStackTrace()\n                null\n            }\n        }\n\n        fun md5(str: String): String? {\n            return MD5Util.md5(str)?.let { HexDump.toHexString(it).lowercase() }\n        }\n\n        fun getVerify(str: String?, str2: String, str3: String): String? {\n            if (str != null) {\n                return md5(md5(str2) + str3 + str)\n            }\n            return null\n        }\n    }\n\n    private object MD5Util {\n        fun md5(str: String): ByteArray? {\n            return this.md5(str.toByteArray())\n        }\n\n        fun md5(bArr: ByteArray?): ByteArray? {\n            return try {\n                val digest = MessageDigest.getInstance(\"MD5\")\n                digest.update(bArr ?: return null)\n                digest.digest()\n            } catch (e: NoSuchAlgorithmException) {\n                e.printStackTrace()\n                null\n            }\n        }\n    }\n\n    private object HexDump {\n        private val HEX_DIGITS = charArrayOf(\n            '0',\n            '1',\n            '2',\n            '3',\n            '4',\n            '5',\n            '6',\n            '7',\n            '8',\n            '9',\n            'A',\n            'B',\n            'C',\n            'D',\n            'E',\n            'F'\n        )\n        fun toHexString(bArr: ByteArray, i: Int = 0, i2: Int = bArr.size): String {\n            val cArr = CharArray(i2 * 2)\n            var i3 = 0\n            for (i4 in i until i + i2) {\n                val b = bArr[i4].toInt()\n                val i5 = i3 + 1\n                val cArr2 = HEX_DIGITS\n                cArr[i3] = cArr2[b ushr 4 and 15]\n                i3 = i5 + 1\n                cArr[i5] = cArr2[b and 15]\n            }\n            return String(cArr)\n        }\n    }\n\n    suspend fun queryApi(query: String, useAlternativeApi: Boolean): NiceResponse {\n        val encryptedQuery = CipherUtils.encrypt(query, key, iv)!!\n        val appKeyHash = CipherUtils.md5(appKey)!!\n        val newBody =\n            \"\"\"{\"app_key\":\"$appKeyHash\",\"verify\":\"${\n                getVerify(\n                    encryptedQuery,\n                    appKey,\n                    key\n                )\n            }\",\"encrypt_data\":\"$encryptedQuery\"}\"\"\"\n        val base64Body = String(Base64.encode(newBody.toByteArray(), Base64.DEFAULT))\n\n        val data = mapOf(\n            \"data\" to base64Body,\n            \"appid\" to \"27\",\n            \"platform\" to \"android\",\n            \"version\" to appVersionCode,\n            // Probably best to randomize this\n            \"medium\" to \"Website&token$token\"\n        )\n\n        val url = if (useAlternativeApi) secondApiUrl else apiUrl\n        return app.post(url, headers = headers, data = data, timeout = 120L)\n    }\n\n    private fun getExpiryDate(): Long {\n        // Current time + 12 hours\n        return unixTime + 60 * 60 * 12\n    }\n\n    suspend fun search(query: String): DataJSON{\n        val hideNsfw = 0\n        val apiQuery =\n            // Originally 8 pagelimit\n            \"\"\"{\"childmode\":\"$hideNsfw\",\n                |\"app_version\":\"$appVersion\",\n                |\"appid\":\"$appIdSecond\",\n                |\"module\":\"Search4\",\n                |\"channel\":\"Website\",\n                |\"page\":\"1\",\n                |\"lang\":\"en\",\n                |\"type\":\"all\",\n                |\"keyword\":\"$query\",\n                |\"pagelimit\":\"20\",\n                |\"expired_date\":\n                |\"${getExpiryDate()}\",\n                |\"platform\":\"android\"}\"\"\".trimMargin()\n\n        val response = queryApi(apiQuery,true).toString()\n        return gson.fromJson(response,DataJSON::class.java)\n\n//        return queryApi(apiQuery, true)\n    }\n\n    data class Data(\n        @JsonProperty(\"id\") val id: Int? = null,\n        @JsonProperty(\"mid\") val mid: Int? = null,\n        @JsonProperty(\"box_type\") val boxType: Int? = null,\n        @JsonProperty(\"title\") val title: String? = null,\n        @JsonProperty(\"poster_org\") val posterOrg: String? = null,\n        @JsonProperty(\"poster\") val poster: String? = null,\n        @JsonProperty(\"cats\") val cats: String? = null,\n        @JsonProperty(\"year\") val year: Int? = null,\n        @JsonProperty(\"imdb_rating\") val imdbRating: String? = null,\n        @JsonProperty(\"quality_tag\") val qualityTag: String? = null,\n    )\n\n    data class MainData(\n        @JsonProperty(\"data\") val data: ArrayList<Data> = arrayListOf()\n    )\n\n     data class PostJSON(\n        @JsonProperty(\"id\") val id: Int? = null,\n        @JsonProperty(\"title\") val title: String? = null,\n        @JsonProperty(\"year\") val year: Int? = null,\n        @JsonProperty(\"poster\") val poster: String? = null,\n        @JsonProperty(\"poster_2\") val poster2: String? = null,\n        @JsonProperty(\"box_type\") val boxType: Int? = null,\n        @JsonProperty(\"imdb_rating\") val imdbRating: String? = null,\n        @JsonProperty(\"quality_tag\") val quality_tag: String? = null,\n    )\n\n     data class ListJSON(\n        @JsonProperty(\"code\") val code: Int? = null,\n        @JsonProperty(\"type\") val type: String? = null,\n        @JsonProperty(\"name\") val name: String? = null,\n        @JsonProperty(\"box_type\") val boxType: Int? = null,\n        @JsonProperty(\"list\") val list: ArrayList<PostJSON> = arrayListOf(),\n    )\n\n     data class DataJSON(\n        @JsonProperty(\"data\") val data: ListJSON\n    )\n//\n//    private suspend inline fun <reified T : Any> queryApiParsed(\n//        query: String,\n//        useAlternativeApi: Boolean = true\n//    ): T {\n//        return queryApi(query, useAlternativeApi).parsed()\n//    }\n\n\n    suspend fun load(isMovie:Boolean, id: Int): NiceResponse {\n//        val isMovie = loadData.type == ResponseTypes.Movies.value\n        val hideNsfw = 0\n        val apiQuery =\n            if (isMovie) { // 1 = Movie\n\n                \"\"\"{\"childmode\":\"$hideNsfw\",\"uid\":\"\",\"app_version\":\"$appVersion\",\"appid\":\"$appIdSecond\",\"module\":\"Movie_detail\",\"channel\":\"Website\",\"mid\":\"$id\",\"lang\":\"en\",\"expired_date\":\"${getExpiryDate()}\",\"platform\":\"android\",\"oss\":\"\",\"group\":\"\"}\"\"\"\n\n            }else{//2 Series\n\n                \"\"\"{\"childmode\":\"$hideNsfw\",\"uid\":\"\",\"app_version\":\"$appVersion\",\"appid\":\"$appIdSecond\",\"module\":\"TV_detail_1\",\"display_all\":\"1\",\"channel\":\"Website\",\"lang\":\"en\",\"expired_date\":\"${getExpiryDate()}\",\"platform\":\"android\",\"tid\":\"$id\"}\"\"\"\n            }\n        return queryApi(apiQuery,false)\n    }\n\n    suspend fun loadLinks(isMovie: Boolean,id: Int,season: Int = 1,episode: Int = 1): LinkDataProp {\n//        val parsed = parseJson<LinkData>(data)\n\n        // No childmode when getting links\n        // New api does not return video links :(\n        val query = if (isMovie) {\n            \"\"\"{\"childmode\":\"0\",\"uid\":\"\",\"app_version\":\"11.5\",\"appid\":\"$appId\",\"module\":\"Movie_downloadurl_v3\",\"channel\":\"Website\",\"mid\": \"$id\",\"lang\":\"\",\"expired_date\":\"${getExpiryDate()}\",\"platform\":\"android\",\"oss\":\"1\",\"group\":\"\"}\"\"\"\n        } else {\n//            val episode = parsed.episode ?: throw RuntimeException(\"No episode number!\")\n//            val season = parsed.season ?: throw RuntimeException(\"No season number!\")\n            \"\"\"{\"childmode\":\"0\",\"app_version\":\"11.5\",\"module\":\"TV_downloadurl_v3\",\"channel\":\"Website\",\"episode\":\"$episode\",\"expired_date\":\"${getExpiryDate()}\",\"platform\":\"android\",\"tid\":\"$id\",\"oss\":\"1\",\"uid\":\"\",\"appid\":\"$appId\",\"season\":\"$season\",\"lang\":\"en\",\"group\":\"\"}\"\"\"\n        }\n        return try {\n            val tvlinks = queryApi(query, false).toString()\n            gson.fromJson(tvlinks, LinkDataProp::class.java)\n        } catch (e: Exception) {\n            e.printStackTrace()\n            LinkDataProp()\n        }\n    //        return queryApi(query, false)\n    }\n\n    suspend fun loadSubtile(isMovie: Boolean, fid:Int, id:Int,season: Int = 1, episode: Int = 1) : SubtitleDataProp{\n        val subtitleQuery = if (isMovie) {\n            \"\"\"{\"childmode\":\"0\",\"fid\":\"$fid\",\"uid\":\"\",\"app_version\":\"11.5\",\"appid\":\"$appId\",\"module\":\"Movie_srt_list_v2\",\"channel\":\"Website\",\"mid\":\"$id\",\"lang\":\"en\",\"expired_date\":\"${getExpiryDate()}\",\"platform\":\"android\"}\"\"\"\n        } else {\n            \"\"\"{\"childmode\":\"0\",\"fid\":\"$fid\",\"app_version\":\"11.5\",\"module\":\"TV_srt_list_v2\",\"channel\":\"Website\",\"episode\":\"$episode\",\"expired_date\":\"${getExpiryDate()}\",\"platform\":\"android\",\"tid\":\"$id\",\"uid\":\"\",\"appid\":\"$appId\",\"season\":\"$season\",\"lang\":\"en\"}\"\"\"\n        }\n//        return queryApi(subtitleQuery,true)\n        val response = queryApi(subtitleQuery,true).toString()\n        return gson.fromJson(response,SubtitleDataProp::class.java)\n\n    }\n\n    data class MovieData(\n        @JsonProperty(\"id\") val id: Int? = null,\n        @JsonProperty(\"title\") val title: String? = null,\n        @JsonProperty(\"director\") val director: String? = null,\n        @JsonProperty(\"writer\") val writer: String? = null,\n        @JsonProperty(\"actors\") val actors: String? = null,\n        @JsonProperty(\"runtime\") val runtime: Int? = null,\n        @JsonProperty(\"poster\") val poster: String? = null,\n        @JsonProperty(\"description\") val description: String? = null,\n        @JsonProperty(\"cats\") val cats: String? = null,\n        @JsonProperty(\"year\") val year: Int? = null,\n        @JsonProperty(\"imdb_id\") val imdbId: String? = null,\n        @JsonProperty(\"imdb_rating\") val imdbRating: String? = null,\n        @JsonProperty(\"trailer\") val trailer: String? = null,\n        @JsonProperty(\"released\") val released: String? = null,\n        @JsonProperty(\"content_rating\") val contentRating: String? = null,\n        @JsonProperty(\"tmdb_id\") val tmdbId: Int? = null,\n        @JsonProperty(\"tomato_meter\") val tomatoMeter: Int? = null,\n        @JsonProperty(\"poster_org\") val posterOrg: String? = null,\n        @JsonProperty(\"trailer_url\") val trailerUrl: String? = null,\n        @JsonProperty(\"imdb_link\") val imdbLink: String? = null,\n        @JsonProperty(\"box_type\") val boxType: Int? = null,\n        @JsonProperty(\"recommend\") val recommend: List<Data> = listOf(),\n    )\n\n     data class MovieDataProp(\n        @JsonProperty(\"data\") val data: MovieData? = MovieData()\n    )\n\n     data class LinkData(\n        val id: Int,\n        val type: Int,\n        val season: Int?,\n        val episode: Int?\n    )\n\n\n     data class LinkDataProp(\n        @JsonProperty(\"code\") val code: Int? = null,\n        @JsonProperty(\"msg\") val msg: String? = null,\n        @JsonProperty(\"data\") val data: ParsedLinkData? = ParsedLinkData()\n    )\n\n     data class LinkList(\n        @JsonProperty(\"path\") val path: String? = null,\n        @JsonProperty(\"quality\") val quality: String? = null,\n        @JsonProperty(\"real_quality\") val realQuality: String? = null,\n        @JsonProperty(\"format\") val format: String? = null,\n        @JsonProperty(\"size\") val size: String? = null,\n        @JsonProperty(\"size_bytes\") val sizeBytes: Long? = null,\n        @JsonProperty(\"count\") val count: Int? = null,\n        @JsonProperty(\"dateline\") val dateline: Long? = null,\n        @JsonProperty(\"fid\") val fid: Int? = null,\n        @JsonProperty(\"mmfid\") val mmfid: Int? = null,\n        @JsonProperty(\"h265\") val h265: Int? = null,\n        @JsonProperty(\"hdr\") val hdr: Int? = null,\n        @JsonProperty(\"filename\") val filename: String? = null,\n        @JsonProperty(\"original\") val original: Int? = null,\n        @JsonProperty(\"colorbit\") val colorbit: Int? = null,\n        @JsonProperty(\"success\") val success: Int? = null,\n        @JsonProperty(\"timeout\") val timeout: Int? = null,\n        @JsonProperty(\"vip_link\") val vipLink: Int? = null,\n        @JsonProperty(\"fps\") val fps: Int? = null,\n        @JsonProperty(\"bitstream\") val bitstream: String? = null,\n        @JsonProperty(\"width\") val width: Int? = null,\n        @JsonProperty(\"height\") val height: Int? = null\n    )\n\n  data class ParsedLinkData(\n        @JsonProperty(\"seconds\") val seconds: Int? = null,\n        @JsonProperty(\"quality\") val quality: ArrayList<String> = arrayListOf(),\n        @JsonProperty(\"list\") val list: ArrayList<LinkList> = arrayListOf()\n    )\n\n\n    data class SeriesDataProp(\n        @JsonProperty(\"code\") val code: Int? = null,\n        @JsonProperty(\"msg\") val msg: String? = null,\n        @JsonProperty(\"data\") val data: SeriesData? = SeriesData()\n    )\n\n   data class SeriesSeasonProp(\n        @JsonProperty(\"code\") val code: Int? = null,\n        @JsonProperty(\"msg\") val msg: String? = null,\n        @JsonProperty(\"data\") val data: ArrayList<SeriesEpisode>? = arrayListOf()\n    )\n//    data class PlayProgress (\n//\n//  @JsonProperty(\"over\"      ) val over     : Int? = null,\n//  @JsonProperty(\"seconds\"   ) val seconds  : Int? = null,\n//  @JsonProperty(\"mp4_id\"    ) val mp4Id    : Int? = null,\n//  @JsonProperty(\"last_time\" ) val lastTime : Int? = null\n//\n//)\n\n    data class SeriesEpisode(\n        @JsonProperty(\"id\") val id: Int? = null,\n        @JsonProperty(\"tid\") val tid: Int? = null,\n        @JsonProperty(\"mb_id\") val mbId: Int? = null,\n        @JsonProperty(\"imdb_id\") val imdbId: String? = null,\n        @JsonProperty(\"imdb_id_status\") val imdbIdStatus: Int? = null,\n        @JsonProperty(\"srt_status\") val srtStatus: Int? = null,\n        @JsonProperty(\"season\") val season: Int? = null,\n        @JsonProperty(\"episode\") val episode: Int? = null,\n        @JsonProperty(\"state\") val state: Int? = null,\n        @JsonProperty(\"title\") val title: String? = null,\n        @JsonProperty(\"thumbs\") val thumbs: String? = null,\n        @JsonProperty(\"thumbs_bak\") val thumbsBak: String? = null,\n        @JsonProperty(\"thumbs_original\") val thumbsOriginal: String? = null,\n        @JsonProperty(\"poster_imdb\") val posterImdb: Int? = null,\n        @JsonProperty(\"synopsis\") val synopsis: String? = null,\n        @JsonProperty(\"runtime\") val runtime: Int? = null,\n        @JsonProperty(\"view\") val view: Int? = null,\n        @JsonProperty(\"download\") val download: Int? = null,\n        @JsonProperty(\"source_file\") val sourceFile: Int? = null,\n        @JsonProperty(\"code_file\") val codeFile: Int? = null,\n        @JsonProperty(\"add_time\") val addTime: Int? = null,\n        @JsonProperty(\"update_time\") val updateTime: Int? = null,\n        @JsonProperty(\"released\") val released: String? = null,\n        @JsonProperty(\"released_timestamp\") val releasedTimestamp: Long? = null,\n        @JsonProperty(\"audio_lang\") val audioLang: String? = null,\n        @JsonProperty(\"quality_tag\") val qualityTag: String? = null,\n        @JsonProperty(\"3d\") val _3d: Int? = null,\n        @JsonProperty(\"remark\") val remark: String? = null,\n        @JsonProperty(\"pending\") val pending: String? = null,\n        @JsonProperty(\"imdb_rating\") val imdbRating: String? = null,\n        @JsonProperty(\"display\") val display: Int? = null,\n        @JsonProperty(\"sync\") val sync: Int? = null,\n        @JsonProperty(\"tomato_meter\") val tomatoMeter: Int? = null,\n        @JsonProperty(\"tomato_meter_count\") val tomatoMeterCount: Int? = null,\n        @JsonProperty(\"tomato_audience\") val tomatoAudience: Int? = null,\n        @JsonProperty(\"tomato_audience_count\") val tomatoAudienceCount: Int? = null,\n        @JsonProperty(\"thumbs_min\") val thumbsMin: String? = null,\n        @JsonProperty(\"thumbs_org\") val thumbsOrg: String? = null,\n        @JsonProperty(\"imdb_link\") val imdbLink: String? = null,\n//        @JsonProperty(\"quality_tags\") val qualityTags: ArrayList<String> = arrayListOf(),\n//  @JsonProperty(\"play_progress\"         ) val playProgress        : PlayProgress?     = PlayProgress()\n\n    )\n\n     data class SeriesLanguage(\n        @JsonProperty(\"title\") val title: String? = null,\n        @JsonProperty(\"lang\") val lang: String? = null\n    )\n\n     data class SeriesData(\n        @JsonProperty(\"id\") val id: Int? = null,\n        @JsonProperty(\"mb_id\") val mbId: Int? = null,\n        @JsonProperty(\"title\") val title: String? = null,\n        @JsonProperty(\"display\") val display: Int? = null,\n        @JsonProperty(\"state\") val state: Int? = null,\n        @JsonProperty(\"vip_only\") val vipOnly: Int? = null,\n        @JsonProperty(\"code_file\") val codeFile: Int? = null,\n        @JsonProperty(\"director\") val director: String? = null,\n        @JsonProperty(\"writer\") val writer: String? = null,\n        @JsonProperty(\"actors\") val actors: String? = null,\n        @JsonProperty(\"add_time\") val addTime: Int? = null,\n        @JsonProperty(\"poster\") val poster: String? = null,\n        @JsonProperty(\"poster_imdb\") val posterImdb: Int? = null,\n        @JsonProperty(\"banner_mini\") val bannerMini: String? = null,\n        @JsonProperty(\"description\") val description: String? = null,\n        @JsonProperty(\"imdb_id\") val imdbId: String? = null,\n        @JsonProperty(\"cats\") val cats: String? = null,\n        @JsonProperty(\"year\") val year: Int? = null,\n        @JsonProperty(\"collect\") val collect: Int? = null,\n        @JsonProperty(\"view\") val view: Int? = null,\n        @JsonProperty(\"download\") val download: Int? = null,\n        @JsonProperty(\"update_time\") val updateTime: String? = null,\n        @JsonProperty(\"released\") val released: String? = null,\n        @JsonProperty(\"released_timestamp\") val releasedTimestamp: Int? = null,\n        @JsonProperty(\"episode_released\") val episodeReleased: String? = null,\n        @JsonProperty(\"episode_released_timestamp\") val episodeReleasedTimestamp: Int? = null,\n        @JsonProperty(\"max_season\") val maxSeason: Int? = null,\n        @JsonProperty(\"max_episode\") val maxEpisode: Int? = null,\n        @JsonProperty(\"remark\") val remark: String? = null,\n        @JsonProperty(\"imdb_rating\") val imdbRating: String? = null,\n        @JsonProperty(\"content_rating\") val contentRating: String? = null,\n        @JsonProperty(\"tmdb_id\") val tmdbId: Int? = null,\n        @JsonProperty(\"tomato_url\") val tomatoUrl: String? = null,\n        @JsonProperty(\"tomato_meter\") val tomatoMeter: Int? = null,\n        @JsonProperty(\"tomato_meter_count\") val tomatoMeterCount: Int? = null,\n        @JsonProperty(\"tomato_meter_state\") val tomatoMeterState: String? = null,\n        @JsonProperty(\"reelgood_url\") val reelgoodUrl: String? = null,\n        @JsonProperty(\"audience_score\") val audienceScore: Int? = null,\n        @JsonProperty(\"audience_score_count\") val audienceScoreCount: Int? = null,\n        @JsonProperty(\"no_tomato_url\") val noTomatoUrl: Int? = null,\n        @JsonProperty(\"order_year\") val orderYear: Int? = null,\n        @JsonProperty(\"episodate_id\") val episodateId: String? = null,\n        @JsonProperty(\"weights_day\") val weightsDay: Double? = null,\n        @JsonProperty(\"poster_min\") val posterMin: String? = null,\n        @JsonProperty(\"poster_org\") val posterOrg: String? = null,\n        @JsonProperty(\"banner_mini_min\") val bannerMiniMin: String? = null,\n        @JsonProperty(\"banner_mini_org\") val bannerMiniOrg: String? = null,\n        @JsonProperty(\"trailer_url\") val trailerUrl: String? = null,\n        @JsonProperty(\"years\") val years: ArrayList<Int> = arrayListOf(),\n        @JsonProperty(\"season\") val season: ArrayList<Int> = arrayListOf(),\n        @JsonProperty(\"history\") val history: ArrayList<String> = arrayListOf(),\n        @JsonProperty(\"imdb_link\") val imdbLink: String? = null,\n        @JsonProperty(\"episode\") val episode: ArrayList<SeriesEpisode> = arrayListOf(),\n//        @JsonProperty(\"is_collect\") val isCollect: Int? = null,\n        @JsonProperty(\"language\") val language: ArrayList<SeriesLanguage> = arrayListOf(),\n        @JsonProperty(\"box_type\") val boxType: Int? = null,\n        @JsonProperty(\"year_year\") val yearYear: String? = null,\n        @JsonProperty(\"season_episode\") val seasonEpisode: String? = null\n    )\n\n    data class SubtitleDataProp(\n        val code: Int? = null,\n        val msg: String? = null,\n        val data: PrivateSubtitleData? = PrivateSubtitleData()\n    )\n\n    data class Subtitles(\n        val sid: Int? = null,\n        val tid: String? = null,\n        val file_path: String? = null,\n        val lang: String? = null,\n        val language: String? = null,\n        val delay: Int? = null,\n        val point: String? = null,\n        val order: Int? = null,\n        val admin_order: Int? = null,\n        val myselect: Int? = null,\n        val add_time: Long? = null,\n        val count: Int? = null\n    )\n\n    data class SubtitleList(\n        val language: String? = null,\n        val subtitles: ArrayList<Subtitles> = arrayListOf()\n    )\n\n    data class PrivateSubtitleData(\n        val select: ArrayList<String> = arrayListOf(),\n        val list: ArrayList<SubtitleList> = arrayListOf()\n    )\n\n}"
  },
  {
    "path": "app/src/main/java/com/demomiru/tokeiv2/utils/VidSrc.kt",
    "content": "package com.demomiru.tokeiv2.utils\n\nimport com.google.gson.Gson\nimport com.lagradost.nicehttp.Requests\nimport org.checkerframework.checker.units.qual.s\nimport java.util.Base64\n\nclass VidSrc {\n    private val app = Requests(baseClient = getBaseClient())\n    private val gson = Gson()\n    private val url = \"https://vidsrc.me/\"\n\n    private val referer = \"https://vidsrc.stream/\"\n\n    private val origin = \"https://vidsrc.stream\"\n\n    private val embedUrl = \"${url}embed/\"\n    private val subtitleUrl = \"https://rest.opensubtitles.org/search/imdbid-\"\n\n    private fun getHashBasedOnIndex(hash: String, index: String): String {\n        var result = \"\"\n        for (i in hash.indices step 2) {\n            val j = hash.substring(i, i + 2)\n            result += (j.toInt(16) xor index[(i / 2) % index.length].code).toChar()\n        }\n        return result\n    }\n\n    suspend fun getLink(tid:String, isMovie:Boolean, s:Int, ep:Int): Pair<String?,String?>{\n        val url = if(isMovie)\"${embedUrl}movie?tmdb=$tid\" else \"${embedUrl}tv?tmdb=$tid&season=$s&episode=$ep\"\n        var videoUrl : String? = null\n        var subUrl: String? = null\n        val absoluteUrl = app.get(url).document.select(\"iframe#player_iframe\").attr(\"src\")\n        val srcRcpRes = app.get(\"https:$absoluteUrl\",referer = url).document\n        val id = srcRcpRes.select(\"body\").attr(\"data-i\")\n        val hash = srcRcpRes.select(\"div#hidden\").attr(\"data-h\")\n\n        if (id.isNullOrBlank() || hash.isNullOrBlank()) return Pair(null,null)\n\n        val sourceUrl = getHashBasedOnIndex(hash, id)\n        val script = app.get(\"https:${sourceUrl}\", referer = \"https:$absoluteUrl\" ).document.selectFirst(\"script:containsData(Playerjs)\")?.data()\n//        val pattern = Regex(\"\"\"file:\"(.*?)\"\"\"\")\n        val video = script?.substringAfter(\"file:\\\"#9\")?.substringBefore(\"\\\"\")\n            ?.replace(Regex(\"/@#@\\\\S+?=?=\"), \"\")?.let {\n                base64Decode(it)}\n//        val subs = script.substringAfterLast(\"default_subtitles = \\\"\").substringBefore(\"\\\";\")\n//        if (subs != script) {\n//            val subSources = subs.split(\",\").toMutableList()\n//            subSources.remove(\"\")\n//            val langToUrlMap = mutableMapOf<String, String>()\n//            for (subSource in subSources) {\n//                val lang =\n//                    subSource.substring(subSource.indexOf(\"[\") + 1, subSource.indexOf(\"]\"))\n//                val url = subSource.substring(subSource.indexOf(\"]\") + 1).replace(\"\\\\\", \"\")\n//                langToUrlMap[lang] = \"https://vidsrc.stream$url\"\n//            }\n//            subUrl = gson.toJson(langToUrlMap)\n//            if(subUrl.length<3) subUrl = null\n//        }\n//\n//\n//        val matchResult = pattern.find(script)\n//        val matchedGroup = matchResult?.groups?.get(1)?.value\n//\n//        val replaced = matchedGroup?.replace(Regex(\"\"\"\\/\\/\\S+?=\"\"\")) { \"\" }\n//        val finalResult = replaced?.replace(\"#2\", \"\")\n//        val bytes = Base64.getDecoder().decode(finalResult)\n//        val finalUrl = String(bytes, Charsets.UTF_8)\n        if(video?.contains(\".m3u8\") == true) videoUrl = video\n        return Pair(videoUrl,subUrl)\n    }\n\n    private fun base64Decode(encodedString: String) : String{\n        return try {\n            val decodedBytes = android.util.Base64.decode(encodedString, android.util.Base64.DEFAULT)\n            val decodedString = String(decodedBytes, Charsets.UTF_8)\n            decodedString\n        } catch (e: Exception) {\n            e.printStackTrace()\n            \"\"\n        }\n    }\n}"
  },
  {
    "path": "app/src/main/java/com/demomiru/tokeiv2/utils/VidSrcUtils.kt",
    "content": "package com.demomiru.tokeiv2.utils\n\nimport android.os.Handler\nimport android.os.Looper\nimport android.os.SystemClock\nimport android.util.Log\nimport android.view.MotionEvent\nimport android.webkit.WebView\nimport com.demomiru.tokeiv2.BuildConfig\nimport com.demomiru.tokeiv2.ImdbEpisode\nimport com.demomiru.tokeiv2.TvIMDB\nimport com.google.gson.Gson\nimport com.lagradost.nicehttp.Requests\n\nfun clickMiddle(webView : WebView,time: Long)\n{\n    val middleX = webView.width / 2\n    val middleY = webView.height / 2\n    val downTime = SystemClock.uptimeMillis()\n    val eventTime = SystemClock.uptimeMillis() + 100\n    val metaState = 0\n    val downEvent = MotionEvent.obtain(\n        downTime,\n        eventTime,\n        MotionEvent.ACTION_DOWN,\n        middleX.toFloat(),\n        middleY.toFloat(),\n        metaState\n    )\n\n    val upEvent = MotionEvent.obtain(\n        downTime + 2000,\n        eventTime + 1000,\n        MotionEvent.ACTION_UP,\n        middleX.toFloat(),\n        middleY.toFloat(),\n        metaState\n    )\n\n\n    Handler(Looper.getMainLooper()).postDelayed({\n        webView.dispatchTouchEvent(downEvent)\n        webView.dispatchTouchEvent(upEvent)\n    }, time)\n}\n\nsuspend fun getTvSeasons(tmdbID: String): Int {\n    val requests = Requests()\n    val headers = mapOf(\n        \"accept\" to \" application/json\",\n        \"Authorization\" to \"Bearer ${BuildConfig.TMDB_TOKEN}\"\n\n    )\n\n    val tvImdb = requests.get(\n        \"https://api.themoviedb.org/3/tv/$tmdbID?language=en-US\",\n        headers = headers\n    ).okhttpResponse\n    val gson = Gson()\n    val response = tvImdb.body.string()\n//    Log.i(\"response\", response)\n    val imdbID = gson.fromJson(response, TvIMDB::class.java)\n    return imdbID.number_of_seasons.toInt()\n}\n\nsuspend fun getSeasonEpisodes(tmdbID: String, season: Int): Int {\n    val requests = Requests()\n    val headers = mapOf(\n        \"accept\" to \" application/json\",\n        \"Authorization\" to \"Bearer ${BuildConfig.TMDB_TOKEN}\"\n\n    )\n    val seasonImdb = requests.get(\n        \"https://api.themoviedb.org/3/tv/$tmdbID/season/$season?language=en-US\",\n        headers = headers\n    ).okhttpResponse\n\n    val gson = Gson()\n    val response = seasonImdb.body.string()\n//    Log.i(\"response\", response)\n    val episodesList = gson.fromJson(response, ImdbEpisode::class.java)\n    return episodesList.episodes.size\n}\n\n//Might be used\n\n//                webView.loadUrl(\"https://vidsrc.me/embed/tv?tmdb=$id&season=$season&episode=$episode\")\n//                webView.evaluateJavascript(\"javascript:document.documentElement.outerHTML\") {\n//                    if (it.contains(\"404 Not Found\")) {\n//                        Log.i(\"Not found\", \" Yes\")\n//                        finish()\n//                    }\n//                }\n//                clickMiddle(webView, 5000)\n//                clickMiddle(webView,6000)\n//                isNextEpisode.value = false\n//                Handler(Looper.getMainLooper()).postDelayed({\n//                    webView.loadUrl(\"about:blank\")\n//                }, 10000)\n\n\n//Previous TVShow Provider\n//                        webView.loadUrl(url)\n//                        webView.evaluateJavascript(\"javascript:document.documentElement.outerHTML\"){\n//                            if(it.contains(\"404 Not Found\")){\n//                                Log.i(\"Not found\",\" Yes\" )\n//                                finish()\n//                            }\n//                        }\n//                        clickMiddle(webView,5000)\n//                        clickMiddle(webView,6000)\n//\n////                        clickMiddle(webView,1000)\n//                        clickedMiddle = true\n//                        Handler(Looper.getMainLooper()).postDelayed({\n//                            if (clickedMiddle && videoUrl.value.isNullOrBlank()) {\n//                                Toast.makeText(this@MoviePlayActivity, \"Not Released Yet\",Toast.LENGTH_SHORT).show()\n//                                finish()\n//                            }\n//                        }, 20000)\n\n//Movie Play Activity\n//    private fun sendGetRequest(url: String) : String {\n//        val client  = OkHttpClient.Builder()\n//            .connectTimeout(20, TimeUnit.SECONDS) // Set connection timeout\n//            .readTimeout(20, TimeUnit.SECONDS)    // Set read timeout\n//            .build()\n//        val request = Request.Builder().url(url).addHeader(\"ngrok-skip-browser-warning\",\"20\").build()\n//\n//        client.newCall(request).execute().use { response ->\n//            val responseBody = response.body()?.string()\n//            Log.i(\"response\", responseBody?:\"systemHang\")\n//            return responseBody?:\"\"\n//        }\n//    }\n\n\n\n\n\n\n//        GlobalScope.launch (Dispatchers.IO){\n//            val videoUrl= sendGetRequest(\"https://loon-neat-troll.ngrok-free.app/scrape?id=$id\").replace(\"\\\"\", \"\")\n//            Log.i(\"final\",videoUrl)\n//            withContext(Dispatchers.Main){\n////\n////                val mediaController = MediaController(this@MoviePlayActivity)\n////                mediaController.setAnchorView(videoView)\n////                videoView.setMediaController(mediaController)\n//\n//                // Set the video URI and start playback\n//                val videoUri = Uri.parse(videoUrl)\n//                videoView.setVideoURI(videoUri)\n//                loading.visibility = View.GONE\n//                videoView.start()\n//                ppButton.setOnClickListener{\n//                    play = if(play){\n//                        videoView.pause()\n//                        ppButton.load(R.drawable.baseline_play_arrow_24)\n//                        false\n//                    }else{\n//                        videoView.resume()\n//                        ppButton.load(R.drawable.netflix_pause_button)\n//                        true\n//                    }\n//\n//                }\n//            }\n//        }"
  },
  {
    "path": "app/src/main/java/com/demomiru/tokeiv2/utils/ViewModelsTokei.kt",
    "content": "@file:Suppress(\"UNCHECKED_CAST\")\n\npackage com.demomiru.tokeiv2.utils\n\nimport android.content.Context\nimport android.net.Uri\nimport androidx.lifecycle.LiveData\nimport androidx.lifecycle.MutableLiveData\nimport androidx.lifecycle.ViewModel\nimport androidx.lifecycle.ViewModelProvider\nimport androidx.lifecycle.lifecycleScope\nimport androidx.lifecycle.viewModelScope\nimport androidx.paging.Pager\nimport androidx.paging.PagingConfig\nimport androidx.paging.cachedIn\nimport androidx.room.util.query\nimport com.demomiru.tokeiv2.BuildConfig\nimport com.demomiru.tokeiv2.Movie\nimport com.demomiru.tokeiv2.MoviesPagingSource\nimport com.demomiru.tokeiv2.R\nimport com.demomiru.tokeiv2.TMDBService\nimport com.demomiru.tokeiv2.TVShowDetailsResponse\nimport com.demomiru.tokeiv2.TVshow\nimport com.demomiru.tokeiv2.TvShowPagingSource\nimport com.demomiru.tokeiv2.anime.AnimeInfo\nimport com.demomiru.tokeiv2.data.tmdbDataRepository\nimport com.demomiru.tokeiv2.extractors.SearchResponse\nimport com.demomiru.tokeiv2.history.QueryRepository\nimport com.demomiru.tokeiv2.history.SearchHistory\nimport com.demomiru.tokeiv2.subtitles.Sub\nimport com.demomiru.tokeiv2.watching.ContinueWatching\nimport com.demomiru.tokeiv2.watching.ContinueWatchingDao\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.launch\nimport org.checkerframework.checker.units.qual.s\n\n\nclass ContinueWatchingViewModelFactory(private val watchingDao: ContinueWatchingDao, private val id:Int) : ViewModelProvider.Factory{\n    override fun <T : ViewModel> create(modelClass: Class<T>): T {\n        if (modelClass.isAssignableFrom(ContinueWatchingViewModel::class.java)){\n            return ContinueWatchingViewModel(watchingDao,id) as T\n        }\n       throw IllegalArgumentException(\"Unknown ViewModel Class\")\n    }\n}\n\nclass ContinueWatchingViewModel(watchingDao: ContinueWatchingDao, id:Int) : ViewModel(){\n    val watchFrom : LiveData<ContinueWatching?> = watchingDao.getProgress(id)\n\n    val season = MutableLiveData(0)\n\n}\n\nclass ContinueWatchingViewModelFactory2(private val watchingDao: ContinueWatchingDao) : ViewModelProvider.Factory{\n    override fun <T : ViewModel> create(modelClass: Class<T>): T {\n        if (modelClass.isAssignableFrom(ContinueWatchingViewModel2::class.java)){\n            return ContinueWatchingViewModel2(watchingDao) as T\n        }\n        throw IllegalArgumentException(\"Unknown ViewModel Class\")\n    }\n}\n\nclass ContinueWatchingViewModel2(watchingDao: ContinueWatchingDao) : ViewModel(){\n    val allWatchHistory : LiveData<List<ContinueWatching>> = watchingDao.getContinueWatchingTest()\n\n    val currentFragment = MutableLiveData(R.id.moviesFragment)\n    val searchOpen = MutableLiveData(true)\n\n    //movies\n    val trenMovies = Pager(PagingConfig(1)){MoviesPagingSource(2)}.flow.cachedIn(viewModelScope)\n    val topMovies = Pager(PagingConfig(1)){MoviesPagingSource(3)}.flow.cachedIn(viewModelScope)\n    val popMovies = Pager(PagingConfig(1)){MoviesPagingSource(1)}.flow.cachedIn(viewModelScope)\n\n    //shows\n    val tvPopularShows = Pager(PagingConfig(1)){ TvShowPagingSource(1) }.flow.cachedIn(viewModelScope)\n    val tvTrendingShows = Pager(PagingConfig(1)){ TvShowPagingSource(2) }.flow.cachedIn(viewModelScope)\n    val tvTopShows = Pager(PagingConfig(1)){ TvShowPagingSource(3) }.flow.cachedIn(viewModelScope)\n\n    //anime\n    val winterList = MutableLiveData<List<GogoAnime.AnimeSearchResponse>>()\n    val fallList = MutableLiveData<List<GogoAnime.AnimeSearchResponse>>()\n    val springList = MutableLiveData<List<GogoAnime.AnimeSearchResponse>>()\n    val summerList = MutableLiveData<List<GogoAnime.AnimeSearchResponse>>()\n    fun getAnime(context: Context) {\n        val animeInfo = AnimeInfo(context)\n        viewModelScope.launch (Dispatchers.IO){\n            winterList.postValue(animeInfo.getSeasonalAnimeInfo(2))\n            fallList.postValue(animeInfo.getSeasonalAnimeInfo(1))\n            springList.postValue(animeInfo.getSeasonalAnimeInfo(3))\n            summerList.postValue(animeInfo.getSeasonalAnimeInfo(4))\n        }\n    }\n}\n\n//class FragmentsViewModel (private val tmdbDataRepo: tmdbDataRepository): ViewModel(){\n//    val trMovies = Pager(PagingConfig(1)){ MoviesPagingSource(3) }.flow.cachedIn(viewModelScope)\n//    val tMovies = Pager(PagingConfig(1)){MoviesPagingSource(2)}.flow.cachedIn(viewModelScope)\n//    val pMovies = Pager(PagingConfig(1)){MoviesPagingSource(1)}.flow.cachedIn(viewModelScope)\n//}\n\nclass SearchViewModel(private val queryRepository: QueryRepository): ViewModel(){\n    val queries = MutableLiveData<List<SearchHistory>>()\n    val movieList = MutableLiveData<List<Movie>>()\n    val tvList = MutableLiveData<List<TVshow>>()\n    val animeList = MutableLiveData<List<GogoAnime.AnimeSearchResponse>>()\n    val noMatches = MutableLiveData(false)\n    val choice = MutableLiveData(1)\n    val queryText = MutableLiveData(\"\")\n    val fixTitleSelection = MutableLiveData<List<SearchResponse>>()\n    init {\n        viewModelScope.launch(Dispatchers.IO) {\n            queries.postValue(queryRepository.loadData())\n        }\n    }\n\n    fun searchMovie(query: String){\n        viewModelScope.launch(Dispatchers.IO) {\n            val movies = queryRepository.movieSearch(query)\n            if (movies.isEmpty()) noMatches.postValue(true)\n            movieList.postValue(movies)\n        }\n    }\n\n    fun searchTv(query: String){\n        viewModelScope.launch(Dispatchers.IO) {\n            val shows = queryRepository.tvSearch(query)\n            if(shows.isEmpty()) noMatches.postValue(true)\n           tvList.postValue(shows)\n        }\n    }\n\n    fun searchAnime(query:String){\n        val gogoSrc = GogoAnime()\n        viewModelScope.launch(Dispatchers.IO) {\n            val anime = gogoSrc.search(query)\n            if(anime.isEmpty())noMatches.postValue(true)\n            animeList.postValue(anime)\n        }\n    }\n\n    fun addToHistory(item: SearchHistory){\n        viewModelScope.launch (Dispatchers.IO){\n            queryRepository.insert(item)\n            queries.postValue(queryRepository.loadData())\n        }\n    }\n\n    fun deleteRecord(item:SearchHistory){\n        viewModelScope.launch (Dispatchers.IO){\n            queryRepository.deleteRecord(item)\n            queries.postValue(queryRepository.loadData())\n        }\n    }\n\n    fun deleteAll(){\n        viewModelScope.launch(Dispatchers.IO) {\n            queryRepository.deleteAll()\n            queries.postValue(queryRepository.loadData())\n        }\n    }\n\n\n    val searchClicked = MutableLiveData(false)\n}\n\nclass SearchVMFactory(private val queryRepository: QueryRepository) : ViewModelProvider.Factory{\n    override fun <T : ViewModel> create(modelClass: Class<T>): T {\n        if (modelClass.isAssignableFrom(SearchViewModel::class.java)){\n            return SearchViewModel(queryRepository) as T\n        }\n        throw IllegalArgumentException(\"Unknown ViewModel Class\")\n    }\n}\n\nclass VideoViewModel(): ViewModel(){\n    val langList = MutableLiveData<List<String>>()\n    val langMap = MutableLiveData<Map<String,String>>()\n    val subs = MutableLiveData<List<SubRest>>()\n    val subUri = MutableLiveData<Uri?>()\n    fun getLang(context: Context){\n        viewModelScope.launch (Dispatchers.IO){\n            val lM = OpenSubtitle(context).getLang()\n            langMap.postValue(lM)\n            val list = lM.map {\n                it.key\n            }\n            langList.postValue(list)\n        }\n    }\n\n    fun searchSubs(context: Context, id: String, langCode: String, s :Int, e: Int, isMovie: Boolean){\n        viewModelScope.launch (Dispatchers.IO) {\n           val s =  OpenSubtitle(context).searchSubs(id, langCode, s, e, isMovie)\n            subs.postValue(s)\n        }\n    }\n\n    fun getSub(context: Context, fileLink:String,lang: String, fileName: String){\n        viewModelScope.launch (Dispatchers.IO){\n            val oS = OpenSubtitle(context)\n            oS.getSub2(fileLink,lang, fileName)\n            subUri.postValue(oS.getSRT(fileName))\n        }\n    }\n\n\n}\n\nclass TVShowViewModel() : ViewModel(){\n    private val retrofit = retrofitBuilder()\n    private val tvService = retrofit.create(TMDBService::class.java)\n    val tvShows = MutableLiveData<TVShowDetailsResponse>(null)\n    fun getTVDetails(id : String) {\n            viewModelScope.launch(Dispatchers.IO) {\n                val tvDetailsResponse = tvService.getTVShowDetails(\n                    id,\n                    BuildConfig.TMDB_API_KEY,\n                    \"en-US\"\n                )\n                if(tvDetailsResponse.isSuccessful){\n                   tvShows.postValue(tvDetailsResponse.body())\n                }\n            }\n    }\n\n    fun getSeasons(season: Int){\n        viewModelScope.launch (Dispatchers.IO){  }\n    }\n}\n\n\n"
  },
  {
    "path": "app/src/main/java/com/demomiru/tokeiv2/utils/colors.txt",
    "content": "All hex value from 100% to 0% alpha\n\n100% — FF\n99% — FC\n98% — FA\n97% — F7\n96% — F5\n95% — F2\n94% — F0\n93% — ED\n92% — EB\n91% — E8\n90% — E6\n89% — E3\n88% — E0\n87% — DE\n86% — DB\n85% — D9\n84% — D6\n83% — D4\n82% — D1\n81% — CF\n80% — CC\n79% — C9\n78% — C7\n77% — C4\n76% — C2\n75% — BF\n74% — BD\n73% — BA\n72% — B8\n71% — B5\n70% — B3\n69% — B0\n68% — AD\n67% — AB\n66% — A8\n65% — A6\n64% — A3\n63% — A1\n62% — 9E\n61% — 9C\n60% — 99\n59% — 96\n58% — 94\n57% — 91\n56% — 8F\n55% — 8C\n54% — 8A\n53% — 87\n52% — 85\n51% — 82\n50% — 80\n49% — 7D\n48% — 7A\n47% — 78\n46% — 75\n45% — 73\n44% — 70\n43% — 6E\n42% — 6B\n41% — 69\n40% — 66\n39% — 63\n38% — 61\n37% — 5E\n36% — 5C\n35% — 59\n34% — 57\n33% — 54\n32% — 52\n31% — 4F\n30% — 4D\n29% — 4A\n28% — 47\n27% — 45\n26% — 42\n25% — 40\n24% — 3D\n23% — 3B\n22% — 38\n21% — 36\n20% — 33\n19% — 30\n18% — 2E\n17% — 2B\n16% — 29\n15% — 26\n14% — 24\n13% — 21\n12% — 1F\n11% — 1C\n10% — 1A\n9% — 17\n8% — 14\n7% — 12\n6% — 0F\n5% — 0D\n4% — 0A\n3% — 08\n2% — 05\n1% — 03\n0% — 00"
  },
  {
    "path": "app/src/main/java/com/demomiru/tokeiv2/utils/retrofitBuilder.kt",
    "content": "package com.demomiru.tokeiv2.utils\n\nimport android.annotation.SuppressLint\nimport android.content.Context\nimport android.content.Intent\nimport android.os.Bundle\n\nimport android.view.animation.AnimationUtils\nimport androidx.media3.common.util.UnstableApi\nimport androidx.media3.datasource.DefaultHttpDataSource\nimport androidx.media3.datasource.HttpDataSource\nimport androidx.media3.datasource.TransferListener\n\nimport androidx.navigation.NavDirections\nimport androidx.recyclerview.widget.RecyclerView\nimport com.demomiru.tokeiv2.anime.AnimeAdapter\nimport com.demomiru.tokeiv2.Episode\nimport com.demomiru.tokeiv2.Movie\nimport com.demomiru.tokeiv2.MovieAdapter\nimport com.demomiru.tokeiv2.MovieAdapter2\nimport com.demomiru.tokeiv2.MoviePlayActivity\n\nimport com.demomiru.tokeiv2.MoviesFragmentDirections\nimport com.demomiru.tokeiv2.R\nimport com.demomiru.tokeiv2.TVShowAdapter\nimport com.demomiru.tokeiv2.TVShowAdapter2\nimport com.demomiru.tokeiv2.TVShowFragmentDirections\nimport com.demomiru.tokeiv2.TVshow\nimport com.demomiru.tokeiv2.VideoPlayActivity\nimport com.demomiru.tokeiv2.watching.ContinueWatching\nimport com.demomiru.tokeiv2.watching.ContinueWatchingAdapter\nimport com.demomiru.tokeiv2.watching.VideoData\nimport com.google.gson.Gson\nimport com.lagradost.nicehttp.addGenericDns\nimport com.lagradost.nicehttp.ignoreAllSSLErrors\nimport okhttp3.Cache\nimport okhttp3.OkHttpClient\n\nimport retrofit2.Retrofit\nimport retrofit2.converter.gson.GsonConverterFactory\nimport java.io.File\nimport java.text.SimpleDateFormat\nimport java.util.concurrent.TimeUnit\n\n\n\n\nprivate val appCache = Cache(File(\"cacheDir\", \"okhttpcache\"), 10 * 1024 * 1024)\nprivate fun OkHttpClient.Builder.addCloudFlareDns() = (\n        addGenericDns(\n            \"https://cloudflare-dns.com/dns-query\",\n            // https://www.cloudflare.com/ips/\n            listOf(\n                \"1.1.1.1\",\n                \"1.0.0.1\",\n                \"2606:4700:4700::1111\",\n                \"2606:4700:4700::1001\"\n            )\n        ))\nprivate val baseClient = OkHttpClient.Builder()\n    .followRedirects(true)\n    .followSslRedirects(true)\n    .ignoreAllSSLErrors()\n    .cache(\n        appCache\n    ).addCloudFlareDns().build()\n\nfun retrofitBuilder (): Retrofit\n{\n   return Retrofit.Builder()\n        .baseUrl(\"https://api.themoviedb.org/3/\")\n        .addConverterFactory(GsonConverterFactory.create()).client(baseClient)\n        .build()\n}\n\n//fun getHiID(id:String) : String{\n//\n//}\n\nfun dateToUnixTime(dateStr: String): Long {\n    try {\n        val sdf = SimpleDateFormat(\"yyyy-MM-dd\")\n        val date = sdf.parse(dateStr)\n        return date?.time ?: 0L\n    } catch (e: Exception) {\n        e.printStackTrace()\n    }\n    return 0L\n}\n\nfun createNumberList(n: Int): List<Int> {\n    return List(n) { it + 1 }\n}\n\nfun yearExtract(releaseDate : String) : String{\n    return releaseDate.substringBefore(\"-\")\n\n}\nfun play(movie : Movie) : NavDirections{\n    return  MoviesFragmentDirections.actionMoviesFragmentToMoviePlayActivity(movie.id, \"movie\",title = movie.title)\n\n}\nfun playShow(tvShow : TVshow, position: Int, name: String) : NavDirections{\n    return TVShowFragmentDirections.actionTVShowFragmentToTVShowDetails(tvShow.id,position,name)\n}\n\nfun dropDownMenu(seasonNumbers: Int): List<String>{\n    val resultList = mutableListOf<String>()\n    for (i in 1..seasonNumbers) {\n        resultList.add(\"Season $i\")\n    }\n    return resultList\n}\n\n@SuppressLint(\"NotifyDataSetChanged\")\nfun addRecyclerAnimation(view :RecyclerView, adapter : ContinueWatchingAdapter){\n    view.adapter = adapter\n    val context = view.context\n    val controller = AnimationUtils.loadLayoutAnimation(context, R.anim.layout_animation)\n    view.layoutAnimation = controller\n    adapter.notifyDataSetChanged()\n    view.scheduleLayoutAnimation()\n}\n\nfun addRecyclerAnimation(view :RecyclerView, adapter : AnimeAdapter){\n    view.adapter = adapter\n    val context = view.context\n    val controller = AnimationUtils.loadLayoutAnimation(context, R.anim.layout_animation)\n    view.layoutAnimation = controller\n    adapter.notifyDataSetChanged()\n    view.scheduleLayoutAnimation()\n}\n\n@SuppressLint(\"NotifyDataSetChanged\")\nfun addRecyclerAnimation(view :RecyclerView, adapter : TVShowAdapter){\n    view.adapter = adapter\n    val context = view.context\n    val controller = AnimationUtils.loadLayoutAnimation(context, R.anim.layout_animation)\n    view.layoutAnimation = controller\n    adapter.notifyDataSetChanged()\n    view.scheduleLayoutAnimation()\n}\n\nfun addRecyclerAnimation(view :RecyclerView, adapter : TVShowAdapter2){\n    view.adapter = adapter\n    val context = view.context\n    val controller = AnimationUtils.loadLayoutAnimation(context, R.anim.layout_animation)\n    view.layoutAnimation = controller\n    adapter.notifyDataSetChanged()\n    view.scheduleLayoutAnimation()\n}\n\n@SuppressLint(\"NotifyDataSetChanged\")\nfun addRecyclerAnimation(view :RecyclerView, adapter : MovieAdapter){\n    view.adapter = adapter\n    val context = view.context\n    val controller = AnimationUtils.loadLayoutAnimation(context, R.anim.layout_animation)\n    view.layoutAnimation = controller\n    adapter.notifyDataSetChanged()\n    view.scheduleLayoutAnimation()\n}\n\n@SuppressLint(\"NotifyDataSetChanged\")\nfun addRecyclerAnimation(view :RecyclerView, adapter : MovieAdapter2){\n    view.adapter = adapter\n    val context = view.context\n    val controller = AnimationUtils.loadLayoutAnimation(context, R.anim.layout_animation)\n    view.layoutAnimation = controller\n    adapter.notifyDataSetChanged()\n    view.scheduleLayoutAnimation()\n}\n\n\n fun passData(data : Movie,context : Context) : Intent{\n    val bundle = Bundle()\n    bundle.putSerializable(\"Data\", data)\n    val intent = Intent(context, MoviePlayActivity::class.java)\n    intent.putExtras(bundle)\n     intent.putExtra(\"type\",\"movie\")\n    return intent\n}\n\nfun passData(data: GogoAnime.AnimeDetails,context : Context,id: String,ep: Int,title: String): Intent{\n    val bundle = Bundle()\n    bundle.putParcelable(\"Data\", data)\n    val intent = Intent(context, MoviePlayActivity::class.java)\n    intent.putExtras(bundle)\n    intent.putExtra(\"type\",\"anime\")\n    intent.putExtra(\"id\",id)\n    intent.putExtra(\"ep\",ep)\n    return intent\n}\n\n\nfun passData(data : Episode,context : Context,title : String, imgLink : String,id : String) : Intent{\n    val bundle = Bundle()\n    bundle.putSerializable(\"Data\", data)\n    val intent = Intent(context, MoviePlayActivity::class.java)\n    intent.putExtras(bundle)\n    intent.putExtra(\"type\",\"tvshow\")\n    intent.putExtra(\"id\",id)\n    intent.putExtra(\"showTitle\",title)\n    intent.putExtra(\"poster\",imgLink)\n    return intent\n}\n\nfun passData(data : ContinueWatching,context : Context) : Intent{\n    val bundle = Bundle()\n    bundle.putParcelable(\"Data\", data)\n    val intent = Intent(context, MoviePlayActivity::class.java)\n    intent.putExtras(bundle)\n    intent.putExtra(\"type\",\"continue\")\n    return intent\n}\n\nfun encodeStringToInt(input : String) : Int{\n    return if(input == \"\") 0\n        else input.hashCode()\n\n}\n\n\nfun passVideoData(data: VideoData, context: Context) : Intent{\n    val bundle = Bundle()\n    bundle.putParcelable(\"VidData\", data)\n    val intent =  Intent(context, VideoPlayActivity::class.java)\n    intent.putExtras(bundle)\n    return intent\n}\n\nfun setSeekBarTime(rem: Long) : String{\n    return String.format(\n        \"%02d:%02d:%02d\",\n        TimeUnit.MILLISECONDS.toHours(rem),\n        TimeUnit.MILLISECONDS.toMinutes(rem) - TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(rem)),\n        TimeUnit.MILLISECONDS.toSeconds(rem) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(rem))\n    )\n}\nfun fixHtml(html : String) : String\n{\n    return html.replace(\"\\u003C\", \"<\")\n}\n\n\nfun superStreamRetrofitBuilder(): Retrofit{\n    return Retrofit.Builder()\n        .baseUrl(\"https://loon-neat-troll.ngrok-free.app/\")\n        .addConverterFactory(GsonConverterFactory.create())\n        .build()\n}\n\nfun getBaseClient(): OkHttpClient {\n    fun OkHttpClient.Builder.addCloudFlareDns() = (\n            addGenericDns(\n                \"https://cloudflare-dns.com/dns-query\",\n                // https://www.cloudflare.com/ips/\n                listOf(\n                    \"1.1.1.1\",\n                    \"1.0.0.1\",\n                    \"2606:4700:4700::1111\",\n                    \"2606:4700:4700::1001\"\n                )\n            ))\n\n\n    val appCache = Cache(File(\"cacheDir\", \"okhttpcache\"), 10 * 1024 * 1024)\n//    private val bootstrapClient = OkHttpClient.Builder().cache(appCache).build()\n//\n//    val dns = DnsOverHttps.Builder().client(bootstrapClient)\n//        .url(\"https://1.1.1.1/dns-query\".toHttpUrl())\n//        .build()\n\n    val baseClient = OkHttpClient.Builder()\n        .followRedirects(true)\n        .followSslRedirects(true)\n        .ignoreAllSSLErrors()\n        .cache(\n            appCache\n        )\n        .apply {\n           addCloudFlareDns()\n        }.build()\n    return baseClient\n}\n//fun dynamicRetrofitBuilder (id :String): Retrofit\n//{\n//    return Retrofit.Builder()\n//        .baseUrl(\"https://api.themoviedb.org/3/tv/$id\")\n//        .addConverterFactory(GsonConverterFactory.create())\n//        .build()\n//}\n"
  },
  {
    "path": "app/src/main/java/com/demomiru/tokeiv2/watching/ContinueWatching.kt",
    "content": "package com.demomiru.tokeiv2.watching\n\nimport android.net.Uri\nimport android.os.Parcel\nimport android.os.Parcelable\nimport androidx.room.Entity\nimport androidx.room.PrimaryKey\nimport androidx.room.TypeConverter\nimport com.demomiru.tokeiv2.utils.GogoAnime\nimport com.google.gson.Gson\nimport com.google.gson.reflect.TypeToken\nimport java.io.Serializable\n\n\nclass EpisodeListTypeConverter {\n\n        private val gson = Gson()\n\n        @TypeConverter\n        fun episodeListToJson(episodes: List<GogoAnime.Episode>?): String? {\n                return gson.toJson(episodes)\n        }\n\n        @TypeConverter\n        fun jsonToEpisodeList(json: String?): List<GogoAnime.Episode>? {\n                if (json == null) return null\n\n                val type = object : TypeToken<List<GogoAnime.Episode>>() {}.type\n                return gson.fromJson(json, type)\n        }\n}\n\n@Entity(tableName = \"continue_watching\")\ndata class ContinueWatching (\n        val progress : Int,\n        val imgLink : String,\n        @PrimaryKey(autoGenerate = true)\n        val tmdbID: Int? = null,\n        val title: String,\n        val episode : Int = 0,\n        val season : Int = 0,\n        val type : String,\n        val animeEp : List<GogoAnime.Episode>? = null,\n        val origin : String? = null,\n        val year : String? = null,\n        ) : Parcelable {\n        constructor(parcel: Parcel) : this(\n                parcel.readInt(),\n                parcel.readString()?:\"\",\n                parcel.readValue(Int::class.java.classLoader) as? Int,\n                parcel.readString()?:\"\",\n                parcel.readInt(),\n                parcel.readInt(),\n                parcel.readString()?:\"\",\n                parcel.createTypedArrayList(GogoAnime.Episode.CREATOR)?: listOf(),\n                parcel.readString()?:\"\",\n                parcel.readString()?:\"\"\n        ) {\n        }\n\n        override fun writeToParcel(parcel: Parcel, flags: Int) {\n                parcel.writeInt(progress)\n                parcel.writeString(imgLink)\n                parcel.writeValue(tmdbID)\n                parcel.writeString(title)\n                parcel.writeInt(episode)\n                parcel.writeInt(season)\n                parcel.writeString(type)\n                parcel.writeTypedList(animeEp)\n                parcel.writeString(origin)\n                parcel.writeString(year)\n        }\n\n        override fun describeContents(): Int {\n                return 0\n        }\n\n        companion object CREATOR : Parcelable.Creator<ContinueWatching> {\n                override fun createFromParcel(parcel: Parcel): ContinueWatching {\n                        return ContinueWatching(parcel)\n                }\n\n                override fun newArray(size: Int): Array<ContinueWatching?> {\n                        return arrayOfNulls(size)\n                }\n        }\n}\n\ndata class VideoData(\n        val progress : Int,\n        val imgLink : String,\n        @PrimaryKey\n        val tmdbID: Int,\n        val imdbId: String? = null,\n        val title: String,\n        val episode : Int = 0,\n        val season : Int = 0,\n        val type : String,\n        val videoUrl: String,\n        val superId : Int? = null,\n        val superSub : List<String>,\n        val animeEpisode : List<GogoAnime.Episode>? = null,\n        val origin: String? = null,\n        val year: String? = null\n        ) : Parcelable {\n\n        constructor(parcel: Parcel) : this(\n                parcel.readInt(),\n                parcel.readString() ?: \"\",\n                parcel.readInt(),\n                parcel.readString(),\n                parcel.readString() ?: \"\",\n                parcel.readInt(),\n                parcel.readInt(),\n                parcel.readString() ?: \"\",\n                parcel.readString() ?: \"\",\n                parcel.readInt(),\n                parcel.createStringArrayList() ?: ArrayList(),\n                parcel.createTypedArrayList(GogoAnime.Episode.CREATOR),\n                parcel.readString() ?: \"\",\n                parcel.readString() ?: \"\"\n        )\n\n        override fun writeToParcel(parcel: Parcel, flags: Int) {\n                parcel.writeInt(progress)\n                parcel.writeString(imgLink)\n                parcel.writeInt(tmdbID)\n                parcel.writeString(imdbId)\n                parcel.writeString(title)\n                parcel.writeInt(episode)\n                parcel.writeInt(season)\n                parcel.writeString(type)\n                parcel.writeString(videoUrl)\n                parcel.writeInt(superId ?: -1) // Use -1 as the default value for null\n                parcel.writeStringList(superSub)\n                parcel.writeTypedList(animeEpisode)\n                parcel.writeString(origin)\n                parcel.writeString(year)\n        }\n\n        override fun describeContents(): Int {\n                return 0\n        }\n\n        companion object CREATOR : Parcelable.Creator<VideoData> {\n                override fun createFromParcel(parcel: Parcel): VideoData {\n                        return VideoData(parcel)\n                }\n\n                override fun newArray(size: Int): Array<VideoData?> {\n                        return arrayOfNulls(size)\n                }\n        }\n}"
  },
  {
    "path": "app/src/main/java/com/demomiru/tokeiv2/watching/ContinueWatchingAdapter.kt",
    "content": "package com.demomiru.tokeiv2.watching\n\nimport android.annotation.SuppressLint\n\nimport android.os.Handler\nimport android.os.Looper\nimport android.view.LayoutInflater\n\nimport android.view.View\nimport android.view.ViewGroup\nimport android.widget.ImageView\n\nimport android.widget.TextView\n\nimport androidx.recyclerview.widget.DiffUtil\nimport androidx.recyclerview.widget.ListAdapter\nimport androidx.recyclerview.widget.RecyclerView\nimport coil.load\nimport com.demomiru.tokeiv2.R\nimport com.google.android.material.progressindicator.LinearProgressIndicator\n\n\n\nclass ContinueWatchingAdapter(private val onClick: (ContinueWatching,Boolean)->Unit): ListAdapter<ContinueWatching,ContinueWatchingAdapter.ViewHolder>(DiffCallBack){\n    class ViewHolder(view: View) : RecyclerView.ViewHolder(view){\n        val imageView: ImageView = view.findViewById(R.id.image_view)\n        val titleTextView: TextView = view.findViewById(R.id.title_text_view)\n        val progressBar : LinearProgressIndicator = view.findViewById(R.id.item_progress)\n        val tvShowDetail : TextView = view.findViewById(R.id.tv_show_detail_tv)\n        val backGround :View = view.findViewById(R.id.blur_background)\n        val delete : ImageView = view.findViewById(R.id.remove_continue)\n    }\n\n    object DiffCallBack : DiffUtil.ItemCallback<ContinueWatching>() {\n        override fun areItemsTheSame(oldItem: ContinueWatching, newItem: ContinueWatching): Boolean {\n            return oldItem === newItem\n        }\n\n        override fun areContentsTheSame(oldItem: ContinueWatching, newItem: ContinueWatching): Boolean {\n            return oldItem == newItem\n        }\n    }\n\n    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {\n        val view = LayoutInflater.from(parent.context).inflate(R.layout.item_view,parent,false)\n        return ViewHolder(view)\n    }\n\n    @SuppressLint(\"SetTextI18n\")\n    override fun onBindViewHolder(holder: ViewHolder, position: Int) {\n        val item = getItem(position)\n\n        holder.titleTextView.text = item.title\n        if (item.type != \"anime\")\n            holder.imageView.load(\"https://image.tmdb.org/t/p/w500${item.imgLink}\")\n        else\n            holder.imageView.load(item.imgLink)\n        holder.progressBar.progress = item.progress\n        holder.progressBar.visibility = View.VISIBLE\n        holder.tvShowDetail.visibility = View.GONE\n        if(item.type != \"movie\"){\n\n            holder.tvShowDetail.text = if(item.type == \"tvshow\") \"S${item.season} E${item.episode}\" else \"E${item.episode+1}\"\n            holder.tvShowDetail.visibility = View.VISIBLE\n        }\n        holder.itemView.setOnClickListener {\n            onClick(item,false)\n        }\n       holder.itemView.setOnLongClickListener {\n           // User performed a long press\n           holder.backGround.visibility = View.VISIBLE\n           holder.delete.visibility = View.VISIBLE\n           holder.itemView.setOnClickListener(null)\n           holder.delete.setOnClickListener {\n               onClick(item,true)\n           }\n\n           Handler(Looper.getMainLooper()).postDelayed({\n               holder.backGround.visibility = View.GONE\n               holder.delete.visibility = View.GONE\n               holder.itemView.setOnClickListener { onClick(item,false) }\n           }, 4000)  // Delay of 4 second\n\n           true\n       }\n    }\n}"
  },
  {
    "path": "app/src/main/java/com/demomiru/tokeiv2/watching/ContinueWatchingDao.kt",
    "content": "package com.demomiru.tokeiv2.watching\n\nimport androidx.lifecycle.LiveData\nimport androidx.room.Dao\nimport androidx.room.Delete\nimport androidx.room.Insert\nimport androidx.room.OnConflictStrategy\nimport androidx.room.Query\n\n@Dao\ninterface ContinueWatchingDao {\n\n    @Insert(onConflict = OnConflictStrategy.REPLACE)\n    suspend fun insert(continueWatching: ContinueWatching)\n\n    @Delete\n    suspend fun delete(continueWatching: ContinueWatching)\n\n    @Query(\"DELETE FROM continue_watching WHERE `tmdbID`=:id\")\n    fun deleteRecord(id:Int)\n\n    @Query(\"SELECT * FROM continue_watching\")\n    fun getContinueWatching(): List<ContinueWatching>\n    @Query(\"SELECT * FROM continue_watching\")\n    fun getContinueWatchingTest(): LiveData<List<ContinueWatching>>\n\n    @Query(\"DELETE FROM continue_watching\")\n    fun deleteAll()\n\n    @Query(\"SELECT * FROM continue_watching WHERE `tmdbID`=:id\")\n    fun getProgress(id:Int) : LiveData<ContinueWatching?>\n}"
  },
  {
    "path": "app/src/main/java/com/demomiru/tokeiv2/watching/ContinueWatchingDatabase.kt",
    "content": "package com.demomiru.tokeiv2.watching\n\nimport android.content.Context\nimport androidx.room.Database\nimport androidx.room.Room\nimport androidx.room.RoomDatabase\nimport androidx.room.TypeConverters\nimport androidx.room.migration.Migration\nimport androidx.sqlite.db.SupportSQLiteDatabase\n\n@Database(entities = [ContinueWatching::class], version = 3)\n@TypeConverters(EpisodeListTypeConverter::class)\nabstract class ContinueWatchingDatabase : RoomDatabase(){\n\n    abstract fun watchDao() : ContinueWatchingDao\n\n    companion object{\n\n        @Volatile\n        private var INSTANCE: ContinueWatchingDatabase? = null\n\n        fun getInstance(context : Context) : ContinueWatchingDatabase{\n            synchronized(this){\n                var instance = INSTANCE\n\n                if (instance == null){\n                    instance = Room.databaseBuilder(\n                        context.applicationContext,\n                       ContinueWatchingDatabase::class.java,\n                        \"continue_watching_database\"\n                    ).addMigrations(MIGRATION_1_2, MIGRATION_2_3).build()\n//                    fallbackToDestructiveMigration().build()\n\n                    INSTANCE = instance\n                }\n                return instance\n            }\n        }\n    }\n}\n\nprivate val MIGRATION_1_2 = object : Migration(1, 2) {\n    override fun migrate(database: SupportSQLiteDatabase) {\n        database.execSQL(\"ALTER TABLE continue_watching ADD COLUMN origin TEXT\")\n    }\n}\n\nprivate val MIGRATION_2_3 = object : Migration(2,3){\n    override fun migrate(database: SupportSQLiteDatabase) {\n        database.execSQL(\"ALTER TABLE continue_watching ADD COLUMN year TEXT\")\n    }\n}\n\n"
  },
  {
    "path": "app/src/main/java/com/demomiru/tokeiv2/watching/ContinueWatchingRepository.kt",
    "content": "package com.demomiru.tokeiv2.watching\n\nimport androidx.annotation.WorkerThread\nimport androidx.lifecycle.LiveData\nimport androidx.lifecycle.MutableLiveData\n\nclass ContinueWatchingRepository(private val continueWatchingDao : ContinueWatchingDao) {\n    private val _allWatchHistory = MutableLiveData<List<ContinueWatching>>()\n    val allWatchHistory : LiveData<List<ContinueWatching>> = _allWatchHistory\n\n    fun loadData(){\n        _allWatchHistory.postValue(continueWatchingDao.getContinueWatching())\n    }\n\n    @WorkerThread\n    fun deleteRecord(query: ContinueWatching){\n        continueWatchingDao.deleteRecord(query.tmdbID!!)\n    }\n\n    @WorkerThread\n    suspend fun insert(query: ContinueWatching) {\n        continueWatchingDao.insert(query)\n    }\n\n    @WorkerThread\n    suspend fun delete(query: ContinueWatching) {\n        continueWatchingDao.delete(query)\n    }\n\n    @WorkerThread\n    fun deleteAll(){\n        continueWatchingDao.deleteAll()\n    }\n\n//    fun getProgress(id:Int) : ContinueWatching?{\n//       return continueWatchingDao.getProgress(id)\n//    }\n}"
  },
  {
    "path": "app/src/main/res/anim/enter_anim.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<set xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <scale\n            android:interpolator=\"@android:anim/linear_interpolator\"\n            android:duration=\"@integer/config_navAnimTime\"\n            android:fromXScale=\"0.9\"\n            android:toXScale=\"1.0\"\n            android:fromYScale=\"0.9\"\n            android:toYScale=\"1.0\"\n            android:pivotX=\"50%\"\n            android:pivotY=\"50%\"\n    >\n    </scale>\n    <alpha\n            android:interpolator=\"@android:anim/linear_interpolator\"\n            android:duration=\"@integer/config_navAnimTime\"\n            android:fromAlpha=\"0.0\"\n            android:toAlpha=\"1.0\"/>\n</set>"
  },
  {
    "path": "app/src/main/res/anim/enter_from_bottom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<set xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <translate\n        android:fromYDelta=\"100%\"\n        android:toYDelta=\"0%\"\n        android:duration=\"700\" />\n</set>\n"
  },
  {
    "path": "app/src/main/res/anim/exit_anim.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<set xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <scale\n            android:interpolator=\"@android:anim/linear_interpolator\"\n            android:duration=\"@integer/config_navAnimTime\"\n            android:fromXScale=\"1.0\"\n            android:toXScale=\"0.9\"\n            android:fromYScale=\"1.0\"\n            android:toYScale=\"0.9\"\n            android:pivotX=\"50%\"\n            android:pivotY=\"50%\"\n    >\n    </scale>\n    <alpha\n            android:interpolator=\"@android:anim/linear_interpolator\"\n            android:duration=\"@integer/config_navAnimTime\"\n            android:fromAlpha=\"1.0\"\n            android:toAlpha=\"0.0\"/>\n</set>"
  },
  {
    "path": "app/src/main/res/anim/exit_to_top.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<set xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <translate\n        android:fromYDelta=\"0%\"\n        android:toYDelta=\"-100%\"\n        android:duration=\"700\" />\n</set>"
  },
  {
    "path": "app/src/main/res/anim/go_left.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<set xmlns:android=\"http://schemas.android.com/apk/res/android\"\n     android:interpolator=\"@android:anim/decelerate_interpolator\"\n>\n    <translate\n            android:fromXDelta=\"0%\"\n            android:toXDelta=\"-30%\"\n            android:duration=\"200\"\n    >\n    </translate>\n</set>"
  },
  {
    "path": "app/src/main/res/anim/go_right.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<set xmlns:android=\"http://schemas.android.com/apk/res/android\"\n     android:interpolator=\"@android:anim/decelerate_interpolator\"\n>\n    <translate\n            android:fromXDelta=\"0%\"\n            android:toXDelta=\"30%\"\n            android:duration=\"200\"\n    >\n    </translate>\n</set>"
  },
  {
    "path": "app/src/main/res/anim/layout_animation.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<layoutAnimation\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:animation=\"@anim/slide_in_right\"\n    android:animationOrder=\"normal\"\n    android:delay=\"20%\" />"
  },
  {
    "path": "app/src/main/res/anim/nav_enter_anim.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<set xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <alpha\n            android:interpolator=\"@android:anim/linear_interpolator\"\n            android:duration=\"@integer/config_navAnimTime\"\n            android:fromAlpha=\"0.0\"\n            android:toAlpha=\"1.0\"/>\n</set>"
  },
  {
    "path": "app/src/main/res/anim/nav_exit_anim.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<set xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <alpha\n            android:interpolator=\"@android:anim/linear_interpolator\"\n            android:duration=\"@integer/config_navAnimTime\"\n            android:fromAlpha=\"1.0\"\n            android:toAlpha=\"0.0\"/>\n</set>"
  },
  {
    "path": "app/src/main/res/anim/nav_pop_enter.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<set xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <alpha\n            android:interpolator=\"@android:anim/linear_interpolator\"\n            android:duration=\"@integer/config_navAnimTime\"\n            android:fromAlpha=\"0.0\"\n            android:toAlpha=\"1.0\"/>\n</set>"
  },
  {
    "path": "app/src/main/res/anim/nav_pop_exit.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<set xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <alpha\n            android:interpolator=\"@android:anim/linear_interpolator\"\n            android:duration=\"@integer/config_navAnimTime\"\n            android:fromAlpha=\"1.0\"\n            android:toAlpha=\"0.0\"/>\n</set>"
  },
  {
    "path": "app/src/main/res/anim/pop_enter.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<set xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <scale\n            android:interpolator=\"@android:anim/linear_interpolator\"\n            android:duration=\"@integer/config_navAnimTime\"\n            android:fromXScale=\"0.9\"\n            android:toXScale=\"1.0\"\n            android:fromYScale=\"0.9\"\n            android:toYScale=\"1.0\"\n            android:pivotX=\"50%\"\n            android:pivotY=\"50%\"\n    >\n    </scale>\n    <alpha\n            android:interpolator=\"@android:anim/linear_interpolator\"\n            android:duration=\"@integer/config_navAnimTime\"\n            android:fromAlpha=\"0.0\"\n            android:toAlpha=\"1.0\"/>\n</set>"
  },
  {
    "path": "app/src/main/res/anim/pop_exit.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<set xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <scale\n            android:interpolator=\"@android:anim/linear_interpolator\"\n            android:duration=\"@integer/config_navAnimTime\"\n            android:fromXScale=\"1.0\"\n            android:toXScale=\"0.9\"\n            android:fromYScale=\"1.0\"\n            android:toYScale=\"0.9\"\n            android:pivotX=\"50%\"\n            android:pivotY=\"50%\"\n    >\n    </scale>\n    <alpha\n            android:interpolator=\"@android:anim/linear_interpolator\"\n            android:duration=\"@integer/config_navAnimTime\"\n            android:fromAlpha=\"1.0\"\n            android:toAlpha=\"0.0\"/>\n</set>"
  },
  {
    "path": "app/src/main/res/anim/rotate_around_center_point.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<set xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:shareInterpolator=\"false\" >\n\n    <rotate\n        android:duration=\"4000\"\n        android:interpolator=\"@android:anim/linear_interpolator\"\n        android:pivotX=\"50%\"\n        android:pivotY=\"50%\"\n        android:repeatCount=\"infinite\"\n        android:repeatMode=\"restart\"\n        android:toDegrees=\"360\" />\n</set>"
  },
  {
    "path": "app/src/main/res/anim/rotate_left.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<set\n        xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:interpolator=\"@android:anim/decelerate_interpolator\"\n>\n    <rotate android:fromDegrees=\"0\"\n            android:toDegrees=\"-90\"\n            android:pivotX=\"50%\"\n            android:pivotY=\"50%\"\n            android:duration=\"50\"\n    />\n    <rotate android:fromDegrees=\"0\"\n            android:toDegrees=\"90\"\n            android:startOffset=\"50\"\n            android:pivotX=\"50%\"\n            android:pivotY=\"50%\"\n            android:duration=\"50\"\n    />\n    <scale android:fromXScale=\"1.0\" android:fromYScale=\"0.9\"\n           android:toXScale=\"1.0\" android:toYScale=\"0.9\"\n           android:pivotX=\"50%\" android:pivotY=\"50%\"\n           android:duration=\"50\"/>\n    <scale android:fromXScale=\"0.9\" android:fromYScale=\"1\"\n           android:toXScale=\"0.9\" android:toYScale=\"1\"\n           android:pivotX=\"50%\" android:pivotY=\"50%\"\n           android:duration=\"50\" android:startOffset=\"50\"/>\n</set>"
  },
  {
    "path": "app/src/main/res/anim/rotate_right.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<set\n        xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:interpolator=\"@android:anim/decelerate_interpolator\"\n>\n    <rotate android:fromDegrees=\"0\"\n            android:toDegrees=\"90\"\n            android:pivotX=\"50%\"\n            android:pivotY=\"50%\"\n            android:duration=\"50\"\n    />\n    <rotate android:fromDegrees=\"0\"\n            android:toDegrees=\"-90\"\n            android:startOffset=\"50\"\n            android:pivotX=\"50%\"\n            android:pivotY=\"50%\"\n            android:duration=\"50\"\n    />\n    <scale android:fromXScale=\"1.0\" android:fromYScale=\"0.9\"\n           android:toXScale=\"1.0\" android:toYScale=\"0.9\"\n           android:pivotX=\"50%\" android:pivotY=\"50%\"\n           android:duration=\"50\"/>\n    <scale android:fromXScale=\"0.9\" android:fromYScale=\"1\"\n           android:toXScale=\"0.9\" android:toYScale=\"1\"\n           android:pivotX=\"50%\" android:pivotY=\"50%\"\n           android:duration=\"50\" android:startOffset=\"50\"/>\n</set>"
  },
  {
    "path": "app/src/main/res/anim/slide_from_uo.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<set xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <translate\n        android:duration=\"750\"\n        android:fromYDelta=\"0\"\n        android:toYDelta=\"100%p\" />\n</set>"
  },
  {
    "path": "app/src/main/res/anim/slide_in.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<set xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <translate\n        android:duration=\"750\"\n        android:fromYDelta=\"100%p\"\n        android:toYDelta=\"0\" />\n</set>"
  },
  {
    "path": "app/src/main/res/anim/slide_in_right.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<set xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <translate\n        android:fromXDelta=\"100%p\"\n        android:toXDelta=\"0\"\n        android:duration=\"500\"/>\n</set>"
  },
  {
    "path": "app/src/main/res/anim/slide_out.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<set xmlns:android=\"http://schemas.android.com/apk/res/android\">\n\n    <translate\n        android:duration=\"750\"\n        android:fromYDelta=\"0\"\n        android:toYDelta=\"100%p\" />\n</set>"
  },
  {
    "path": "app/src/main/res/drawable/anime_bottom_nav.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\" android:height=\"24dp\" android:width=\"24dp\" android:viewportWidth=\"24\" android:viewportHeight=\"24\">\n    <path android:fillColor=\"#000000\" android:pathData=\"M11 4V6H4V8H15.36C15.13 8.87 14.63 9.77 13.88 10.69C13.35 11.35 12.71 12 12 12.67C11.29 12 10.65 11.35 10.12 10.69C9.65 10.12 9.3 9.55 9.03 9H6.85C7.21 10.05 7.82 11.03 8.56 11.95C9.13 12.66 9.79 13.34 10.5 14L5.36 18.23L6.64 19.77L12 15.34L17.36 19.77L18.64 18.23L13.5 14C14.21 13.34 14.87 12.66 15.44 11.95C16.41 10.74 17.16 9.43 17.4 8H20V6H13V4Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/background_search_history.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<shape xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:shape=\"rectangle\"\n    >\n    <corners android:radius=\"20dp\"/>\n    <solid android:color=\"#CC000000\"/>\n\n\n\n</shape>"
  },
  {
    "path": "app/src/main/res/drawable/background_text.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<shape xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:shape=\"rectangle\"\n    >\n    <solid android:color=\"#CC000000\"/>\n\n\n\n</shape>"
  },
  {
    "path": "app/src/main/res/drawable/baseline_cancel_24.xml",
    "content": "<vector android:height=\"24dp\" android:tint=\"#D51616\"\n    android:viewportHeight=\"24\" android:viewportWidth=\"24\"\n    android:width=\"24dp\" xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <path android:fillColor=\"@android:color/white\" android:pathData=\"M12,2C6.47,2 2,6.47 2,12s4.47,10 10,10 10,-4.47 10,-10S17.53,2 12,2zM17,15.59L15.59,17 12,13.41 8.41,17 7,15.59 10.59,12 7,8.41 8.41,7 12,10.59 15.59,7 17,8.41 13.41,12 17,15.59z\"/>\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/baseline_double_arrow_24.xml",
    "content": "<vector android:height=\"24dp\" android:tint=\"#FFFFFF\"\n    android:viewportHeight=\"24\" android:viewportWidth=\"24\"\n    android:width=\"24dp\" xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <path android:fillColor=\"@android:color/white\" android:pathData=\"M15.5,5l-4.5,0l5,7l-5,7l4.5,0l5,-7z\"/>\n    <path android:fillColor=\"@android:color/white\" android:pathData=\"M8.5,5l-4.5,0l5,7l-5,7l4.5,0l5,-7z\"/>\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/baseline_history_24.xml",
    "content": "<vector android:height=\"24dp\" android:tint=\"#FFFFFF\"\n    android:viewportHeight=\"24\" android:viewportWidth=\"24\"\n    android:width=\"24dp\" xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <path android:fillColor=\"@android:color/white\" android:pathData=\"M13,3c-4.97,0 -9,4.03 -9,9L1,12l3.89,3.89 0.07,0.14L9,12L6,12c0,-3.87 3.13,-7 7,-7s7,3.13 7,7 -3.13,7 -7,7c-1.93,0 -3.68,-0.79 -4.94,-2.06l-1.42,1.42C8.27,19.99 10.51,21 13,21c4.97,0 9,-4.03 9,-9s-4.03,-9 -9,-9zM12,8v5l4.28,2.54 0.72,-1.21 -3.5,-2.08L13.5,8L12,8z\"/>\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/baseline_keyboard_arrow_down_24.xml",
    "content": "<vector android:height=\"24dp\" android:tint=\"@color/white\"\n    android:viewportHeight=\"24\" android:viewportWidth=\"24\"\n    android:width=\"24dp\" xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <path android:fillColor=\"@android:color/white\" android:pathData=\"M7.41,8.59L12,13.17l4.59,-4.58L18,10l-6,6 -6,-6 1.41,-1.41z\"/>\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/baseline_keyboard_arrow_up_24.xml",
    "content": "<vector android:height=\"24dp\" android:tint=\"@color/white\"\n    android:viewportHeight=\"24\" android:viewportWidth=\"24\"\n    android:width=\"24dp\" xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <path android:fillColor=\"@android:color/white\" android:pathData=\"M7.41,15.41L12,10.83l4.59,4.58L18,14l-6,-6 -6,6z\"/>\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/baseline_lock_open_24.xml",
    "content": "<vector android:height=\"48dp\" android:tint=\"#FFFFFF\"\n    android:viewportHeight=\"24\" android:viewportWidth=\"24\"\n    android:width=\"48dp\" xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <path android:fillColor=\"@android:color/white\" android:pathData=\"M12,17c1.1,0 2,-0.9 2,-2s-0.9,-2 -2,-2 -2,0.9 -2,2 0.9,2 2,2zM18,8h-1L17,6c0,-2.76 -2.24,-5 -5,-5S7,3.24 7,6h1.9c0,-1.71 1.39,-3.1 3.1,-3.1 1.71,0 3.1,1.39 3.1,3.1v2L6,8c-1.1,0 -2,0.9 -2,2v10c0,1.1 0.9,2 2,2h12c1.1,0 2,-0.9 2,-2L20,10c0,-1.1 -0.9,-2 -2,-2zM18,20L6,20L6,10h12v10z\"/>\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/baseline_play_arrow_24.xml",
    "content": "<vector android:height=\"40dp\" android:tint=\"#FFFFFF\"\n    android:viewportHeight=\"24\" android:viewportWidth=\"24\"\n    android:width=\"40dp\" xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <path android:fillColor=\"@android:color/white\" android:pathData=\"M8,5v14l11,-7z\"/>\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/baseline_play_circle_24.xml",
    "content": "<vector android:height=\"24dp\"\n    android:viewportHeight=\"24\" android:viewportWidth=\"24\"\n    android:width=\"24dp\" xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <path android:fillColor=\"@android:color/white\" android:pathData=\"M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10s10,-4.48 10,-10S17.52,2 12,2zM9.5,16.5v-9l7,4.5L9.5,16.5z\"/>\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/baseline_search_24.xml",
    "content": "<vector android:height=\"24dp\" android:tint=\"#000000\"\n    android:viewportHeight=\"24\" android:viewportWidth=\"24\"\n    android:width=\"24dp\" xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <path android:fillColor=\"@android:color/white\" android:pathData=\"M15.5,14h-0.79l-0.28,-0.27C15.41,12.59 16,11.11 16,9.5 16,5.91 13.09,3 9.5,3S3,5.91 3,9.5 5.91,16 9.5,16c1.61,0 3.09,-0.59 4.23,-1.57l0.27,0.28v0.79l5,4.99L20.49,19l-4.99,-5zM9.5,14C7.01,14 5,11.99 5,9.5S7.01,5 9.5,5 14,7.01 14,9.5 11.99,14 9.5,14z\"/>\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/baseline_zoom_out_map_24.xml",
    "content": "<vector android:height=\"24dp\" android:tint=\"#FFFFFF\"\n    android:viewportHeight=\"24\" android:viewportWidth=\"24\"\n    android:width=\"24dp\" xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <path android:fillColor=\"@android:color/white\" android:pathData=\"M15,3l2.3,2.3l-2.89,2.87l1.42,1.42L18.7,6.7L21,9V3H15zM3,9l2.3,-2.3l2.87,2.89l1.42,-1.42L6.7,5.3L9,3H3V9zM9,21l-2.3,-2.3l2.89,-2.87l-1.42,-1.42L5.3,17.3L3,15v6H9zM21,15l-2.3,2.3l-2.87,-2.89l-1.42,1.42l2.89,2.87L15,21h6V15z\"/>\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/custom_thumb.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<layer-list xmlns:android=\"http://schemas.android.com/apk/res/android\">\n\n    <item>\n        <shape android:shape=\"oval\">\n            <solid android:color=\"@color/red\"/>\n            <size\n                android:height=\"22dp\"\n                android:width=\"22dp\"/>\n        </shape>\n    </item>\n\n</layer-list>"
  },
  {
    "path": "app/src/main/res/drawable/delete.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"24dp\"\n    android:height=\"24dp\"\n    android:viewportWidth=\"408.483\"\n    android:viewportHeight=\"408.483\">\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M87.748,388.784c0.461,11.01 9.521,19.699 20.539,19.699h191.911c11.018,0 20.078,-8.689 20.539,-19.699l13.705,-289.316H74.043L87.748,388.784zM247.655,171.329c0,-4.61 3.738,-8.349 8.35,-8.349h13.355c4.609,0 8.35,3.738 8.35,8.349v165.293c0,4.611 -3.738,8.349 -8.35,8.349h-13.355c-4.61,0 -8.35,-3.736 -8.35,-8.349V171.329zM189.216,171.329c0,-4.61 3.738,-8.349 8.349,-8.349h13.355c4.609,0 8.349,3.738 8.349,8.349v165.293c0,4.611 -3.737,8.349 -8.349,8.349h-13.355c-4.61,0 -8.349,-3.736 -8.349,-8.349V171.329L189.216,171.329zM130.775,171.329c0,-4.61 3.738,-8.349 8.349,-8.349h13.356c4.61,0 8.349,3.738 8.349,8.349v165.293c0,4.611 -3.738,8.349 -8.349,8.349h-13.356c-4.61,0 -8.349,-3.736 -8.349,-8.349V171.329z\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"M343.567,21.043h-88.535V4.305c0,-2.377 -1.927,-4.305 -4.305,-4.305h-92.971c-2.377,0 -4.304,1.928 -4.304,4.305v16.737H64.916c-7.125,0 -12.9,5.776 -12.9,12.901V74.47h304.451V33.944C356.467,26.819 350.692,21.043 343.567,21.043z\" />\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/down_arrow.xml",
    "content": "<vector android:height=\"48dp\" android:tint=\"#FFFFFF\"\n    android:viewportHeight=\"24\" android:viewportWidth=\"24\"\n    android:width=\"48dp\" xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <path android:fillColor=\"@android:color/white\" android:pathData=\"M7.41,8.59L12,13.17l4.59,-4.58L18,10l-6,6 -6,-6 1.41,-1.41z\"/>\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/edit.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"24dp\"\n    android:height=\"24dp\"\n    android:viewportWidth=\"512\"\n    android:viewportHeight=\"511\">\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"m405.332,256.484c-11.797,0 -21.332,9.559 -21.332,21.332v170.668c0,11.754 -9.559,21.332 -21.332,21.332h-298.668c-11.777,0 -21.332,-9.578 -21.332,-21.332v-298.668c0,-11.754 9.555,-21.332 21.332,-21.332h170.668c11.797,0 21.332,-9.559 21.332,-21.332 0,-11.777 -9.535,-21.336 -21.332,-21.336h-170.668c-35.285,0 -64,28.715 -64,64v298.668c0,35.285 28.715,64 64,64h298.668c35.285,0 64,-28.715 64,-64v-170.668c0,-11.797 -9.539,-21.332 -21.336,-21.332zM405.332,256.484\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"m200.02,237.051c-1.492,1.492 -2.496,3.391 -2.922,5.438l-15.082,75.438c-0.703,3.496 0.406,7.102 2.922,9.641 2.027,2.027 4.758,3.113 7.555,3.113 0.68,0 1.387,-0.063 2.09,-0.211l75.414,-15.082c2.09,-0.43 3.988,-1.43 5.461,-2.926l168.789,-168.789 -75.414,-75.41zM200.02,237.051\" />\n    <path\n        android:fillColor=\"#ffffff\"\n        android:pathData=\"m496.383,16.102c-20.797,-20.801 -54.633,-20.801 -75.414,0l-29.523,29.523 75.414,75.414 29.523,-29.527c10.07,-10.047 15.617,-23.445 15.617,-37.695s-5.547,-27.648 -15.617,-37.715zM496.383,16.102\" />\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/fill_screen.xml",
    "content": "<vector android:alpha=\"0.9\" android:height=\"40dp\" android:tint=\"#FFFFFF\"\n    android:viewportHeight=\"24\" android:viewportWidth=\"24\"\n    android:width=\"40dp\" xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <path android:fillColor=\"@android:color/white\" android:pathData=\"M6.5,7.5l2.5,0l0,-1.5l-4,0l0,4l1.5,0z\"/>\n    <path android:fillColor=\"@android:color/white\" android:pathData=\"M19,12l-1.5,0l0,2.5l-2.5,0l0,1.5l4,0z\"/>\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/fit_screen.xml",
    "content": "<vector android:alpha=\"0.9\" android:height=\"40dp\" android:tint=\"#FFFFFF\"\n    android:viewportHeight=\"24\" android:viewportWidth=\"24\"\n    android:width=\"40dp\" xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <path android:fillColor=\"@android:color/white\" android:pathData=\"M17,4h3c1.1,0 2,0.9 2,2v2h-2L20,6h-3L17,4zM4,8L4,6h3L7,4L4,4c-1.1,0 -2,0.9 -2,2v2h2zM20,16v2h-3v2h3c1.1,0 2,-0.9 2,-2v-2h-2zM7,18L4,18v-2L2,16v2c0,1.1 0.9,2 2,2h3v-2zM18,8L6,8v8h12L18,8z\"/>\n</vector>\n\n"
  },
  {
    "path": "app/src/main/res/drawable/focus.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<selector xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <item android:state_pressed=\"true\"\n        android:drawable=\"@drawable/rectangle_box\" /> <!-- pressed -->\n    <item android:state_focused=\"true\"\n        android:drawable=\"@drawable/rectangle_box\" /> <!-- focused -->\n    <item android:state_hovered=\"true\"\n        android:drawable=\"@drawable/rectangle_box\" /> <!-- hovered -->\n\n</selector>"
  },
  {
    "path": "app/src/main/res/drawable/focus_search.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<selector xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <item android:state_pressed=\"true\"\n        android:drawable=\"@color/ripple_color\" /> <!-- pressed -->\n    <item android:state_focused=\"true\"\n        android:drawable=\"@color/ripple_color\" /> <!-- focused -->\n    <item android:state_hovered=\"true\"\n        android:drawable=\"@color/ripple_color\" /> <!-- hovered -->\n</selector>"
  },
  {
    "path": "app/src/main/res/drawable/gradient_fill.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<shape xmlns:android=\"http://schemas.android.com/apk/res/android\" android:shape=\"rectangle\"\n    >\n    <gradient\n        android:type=\"linear\"\n        android:startColor=\"@color/black\"\n        android:centerColor=\"#00FFFFFF\"\n        android:endColor=\"#00FFFFFF\"\n        android:angle=\"20\"/>\n</shape>\n"
  },
  {
    "path": "app/src/main/res/drawable/gradient_fill_bottom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<shape xmlns:android=\"http://schemas.android.com/apk/res/android\" android:shape=\"rectangle\"\n    >\n    <gradient\n        android:type=\"linear\"\n        android:startColor=\"@color/black\"\n        android:centerColor=\"#00FFFFFF\"\n        android:endColor=\"#00FFFFFF\"\n        android:angle=\"90\"/>\n</shape>\n"
  },
  {
    "path": "app/src/main/res/drawable/gradient_fill_text.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<shape xmlns:android=\"http://schemas.android.com/apk/res/android\" android:shape=\"rectangle\"\n    >\n\n        <gradient\n            android:type=\"radial\"\n            android:startColor=\"#CC000000\"\n            android:centerColor=\"#B3000000\"\n            android:gradientRadius=\"28dp\"\n        />\n\n</shape>\n"
  },
  {
    "path": "app/src/main/res/drawable/ic_baseline_keyboard_backspace_24.xml",
    "content": "<vector android:height=\"24dp\" android:tint=\"#FFFFFF\"\n    android:viewportHeight=\"24\" android:viewportWidth=\"24\"\n    android:width=\"24dp\" xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <path android:fillColor=\"@android:color/white\" android:pathData=\"M21,11H6.83l3.58,-3.59L9,6l-6,6 6,6 1.41,-1.41L6.83,13H21z\"/>\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/ic_forward.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"90dp\"\n    android:height=\"90dp\"\n    android:viewportWidth=\"1024\"\n    android:viewportHeight=\"1024\">\n    <group>\n        <clip-path android:pathData=\"M0,0h1024v1024h-1024z\" />\n        <path\n            android:fillColor=\"#00FFFFFF\"\n            android:pathData=\"M0,0h1024v1024h-1024z\" />\n        <path\n            android:fillColor=\"#00FFFFFF\"\n            android:pathData=\"M747,544A199.99,199.99 45,0 1,547 744c-110.46,0 -200,-89.54 -200,-200S436.54,344 547,344\"\n            android:strokeWidth=\"20\"\n            android:strokeColor=\"#fff\" />\n        <path\n            android:fillColor=\"#fff\"\n            android:pathData=\"M525.26,294 L572,344 525.26,394 512,379.82 545.48,344 512,308.18Z\" />\n        <path\n            android:fillColor=\"#fff\"\n            android:pathData=\"M596.26,294 L643,344 596.26,394 583,379.82 616.48,344 583,308.18Z\" />\n\n    </group>\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/ic_launcher_background.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"108dp\"\n    android:height=\"108dp\"\n    android:viewportWidth=\"108\"\n    android:viewportHeight=\"108\">\n    <path\n        android:fillColor=\"#3DDC84\"\n        android:pathData=\"M0,0h108v108h-108z\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M9,0L9,108\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,0L19,108\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M29,0L29,108\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M39,0L39,108\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M49,0L49,108\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M59,0L59,108\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M69,0L69,108\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M79,0L79,108\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M89,0L89,108\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M99,0L99,108\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,9L108,9\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,19L108,19\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,29L108,29\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,39L108,39\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,49L108,49\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,59L108,59\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,69L108,69\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,79L108,79\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,89L108,89\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,99L108,99\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,29L89,29\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,39L89,39\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,49L89,49\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,59L89,59\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,69L89,69\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,79L89,79\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M29,19L29,89\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M39,19L39,89\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M49,19L49,89\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M59,19L59,89\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M69,19L69,89\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M79,19L79,89\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/ic_menu.xml",
    "content": "<vector android:height=\"24dp\" android:tint=\"#FFFFFF\"\n    android:viewportHeight=\"24\" android:viewportWidth=\"24\"\n    android:width=\"24dp\" xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <path android:fillColor=\"@android:color/white\" android:pathData=\"M3,18h18v-2L3,16v2zM3,13h18v-2L3,11v2zM3,6v2h18L21,6L3,6z\"/>\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/ic_rewind.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"90dp\"\n    android:height=\"90dp\"\n    android:viewportWidth=\"1024\"\n    android:viewportHeight=\"1024\">\n    <group>\n        <clip-path android:pathData=\"M0,0h1024v1024h-1024z\" />\n        <path\n            android:fillColor=\"#00FFFFFF\"\n            android:pathData=\"M0,0h1024v1024h-1024z\" />\n        <path\n            android:fillColor=\"#00000000\"\n            android:pathData=\"M512,337.2C622.46,337.2 712,426.74 712,537.2S622.46,737.2 512,737.2 312,647.66 312,537.2\"\n            android:strokeWidth=\"20\"\n            android:strokeColor=\"#fff\" />\n        <path\n            android:fillColor=\"#fff\"\n            android:pathData=\"M531.75,286.8 L485.01,336.8 531.75,386.8 545.01,372.61 511.53,336.8 545.01,300.98Z\" />\n        <path\n            android:fillColor=\"#fff\"\n            android:pathData=\"M483.75,286.8 L437.01,336.8 483.75,386.8 497.01,372.61 463.53,336.8 497.01,300.98Z\" />\n\n\n    </group>\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/ic_rotation.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"30dp\"\n    android:height=\"30dp\"\n    android:tint=\"#FFFFFF\"\n    android:viewportWidth=\"24\"\n    android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"@android:color/white\"\n        android:pathData=\"M16.48,2.52c3.27,1.55 5.61,4.72 5.97,8.48h1.5C23.44,4.84 18.29,0 12,0l-0.66,0.03 3.81,3.81 1.33,-1.32zM10.23,1.75c-0.59,-0.59 -1.54,-0.59 -2.12,0L1.75,8.11c-0.59,0.59 -0.59,1.54 0,2.12l12.02,12.02c0.59,0.59 1.54,0.59 2.12,0l6.36,-6.36c0.59,-0.59 0.59,-1.54 0,-2.12L10.23,1.75zM14.83,21.19L2.81,9.17l6.36,-6.36 12.02,12.02 -6.36,6.36zM7.52,21.48C4.25,19.94 1.91,16.76 1.55,13L0.05,13C0.56,19.16 5.71,24 12,24l0.66,-0.03 -3.81,-3.81 -1.33,1.32z\" />\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/icon_play.xml",
    "content": "<vector android:alpha=\"0.9\" android:height=\"40dp\" android:tint=\"#FFFFFF\"\n    android:viewportHeight=\"24\" android:viewportWidth=\"24\"\n    android:width=\"40dp\" xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <path android:fillColor=\"@android:color/white\" android:pathData=\"M8,5v14l11,-7z\"/>\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/image_view_round.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<shape xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:shape=\"rectangle\">\n    <corners android:radius=\"20dp\" /> <!-- Adjust the radius as needed -->\n    <solid android:color=\"@android:color/transparent\" />\n</shape>"
  },
  {
    "path": "app/src/main/res/drawable/more.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"24dp\"\n    android:height=\"24dp\"\n    android:tint=\"#FFFFFF\"\n    android:viewportWidth=\"24\"\n    android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"@android:color/white\"\n        android:pathData=\"M12,8c1.1,0 2,-0.9 2,-2s-0.9,-2 -2,-2 -2,0.9 -2,2 0.9,2 2,2zM12,10c-1.1,0 -2,0.9 -2,2s0.9,2 2,2 2,-0.9 2,-2 -0.9,-2 -2,-2zM12,16c-1.1,0 -2,0.9 -2,2s0.9,2 2,2 2,-0.9 2,-2 -0.9,-2 -2,-2z\" />\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/netflix_audio_subtitles.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"35dp\"\n    android:height=\"35dp\"\n    android:viewportWidth=\"512\"\n    android:viewportHeight=\"512\">\n  <path\n      android:fillColor=\"#FFF\"\n      android:pathData=\"M0,86v340h512V86H0zM70,266h252v30H70V266zM160,356H70v-30h90V356zM442,356H190v-30h252V356zM442,296h-90v-30h90V296z\"/>\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/netflix_brightness_four.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"30dp\"\n    android:height=\"30dp\"\n    android:viewportWidth=\"302.4\"\n    android:viewportHeight=\"302.4\">\n    <path\n        android:fillColor=\"#FFF\"\n        android:pathData=\"M204.8,97.6C191.2,84 172,75.2 151.2,75.2s-40,8.4 -53.6,22.4c-13.6,13.6 -22.4,32.8 -22.4,53.6s8.8,40 22.4,53.6c13.6,13.6 32.8,22.4 53.6,22.4s40,-8.4 53.6,-22.4c13.6,-13.6 22.4,-32.8 22.4,-53.6S218.8,111.2 204.8,97.6zM190.4,190.4c-10,10 -24,16 -39.2,16s-29.2,-6 -39.2,-16s-16,-24 -16,-39.2s6,-29.2 16,-39.2s24,-16 39.2,-16s29.2,6 39.2,16s16,24 16,39.2S200.4,180.4 190.4,190.4z\"/>\n    <path\n        android:fillColor=\"#FFF\"\n        android:pathData=\"M292,140.8h-30.8c-5.6,0 -10.4,4.8 -10.4,10.4c0,5.6 4.8,10.4 10.4,10.4H292c5.6,0 10.4,-4.8 10.4,-10.4C302.4,145.6 297.6,140.8 292,140.8z\"/>\n    <path\n        android:fillColor=\"#FFF\"\n        android:pathData=\"M151.2,250.8c-5.6,0 -10.4,4.8 -10.4,10.4V292c0,5.6 4.8,10.4 10.4,10.4c5.6,0 10.4,-4.8 10.4,-10.4v-30.8C161.6,255.6 156.8,250.8 151.2,250.8z\"/>\n    <path\n        android:fillColor=\"#FFF\"\n        android:pathData=\"M258,243.6l-22,-22c-3.6,-4 -10.4,-4 -14.4,0s-4,10.4 0,14.4l22,22c4,4 10.4,4 14.4,0S262,247.6 258,243.6z\"/>\n    <path\n        android:fillColor=\"#FFF\"\n        android:pathData=\"M151.2,0c-5.6,0 -10.4,4.8 -10.4,10.4v30.8c0,5.6 4.8,10.4 10.4,10.4c5.6,0 10.4,-4.8 10.4,-10.4V10.4C161.6,4.8 156.8,0 151.2,0z\"/>\n    <path\n        android:fillColor=\"#FFF\"\n        android:pathData=\"M258.4,44.4c-4,-4 -10.4,-4 -14.4,0l-22,22c-4,4 -4,10.4 0,14.4c3.6,4 10.4,4 14.4,0l22,-22C262.4,54.8 262.4,48.4 258.4,44.4z\"/>\n    <path\n        android:fillColor=\"#FFF\"\n        android:pathData=\"M80.4,221.6c-3.6,-4 -10.4,-4 -14.4,0l-22,22c-4,4 -4,10.4 0,14.4s10.4,4 14.4,0l22,-22C84.4,232 84.4,225.6 80.4,221.6z\"/>\n    </vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/netflix_brightness_one.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"30dp\"\n    android:height=\"30dp\"\n    android:viewportWidth=\"302.4\"\n    android:viewportHeight=\"302.4\">\n  <path\n      android:fillColor=\"#FFF\"\n      android:pathData=\"M204.8,97.6C191.2,84 172,75.2 151.2,75.2s-40,8.4 -53.6,22.4c-13.6,13.6 -22.4,32.8 -22.4,53.6s8.8,40 22.4,53.6c13.6,13.6 32.8,22.4 53.6,22.4s40,-8.4 53.6,-22.4c13.6,-13.6 22.4,-32.8 22.4,-53.6S218.8,111.2 204.8,97.6zM190.4,190.4c-10,10 -24,16 -39.2,16s-29.2,-6 -39.2,-16s-16,-24 -16,-39.2s6,-29.2 16,-39.2s24,-16 39.2,-16s29.2,6 39.2,16s16,24 16,39.2S200.4,180.4 190.4,190.4z\"/>\n  <path\n      android:fillColor=\"#FFF\"\n      android:pathData=\"M292,140.8h-30.8c-5.6,0 -10.4,4.8 -10.4,10.4c0,5.6 4.8,10.4 10.4,10.4H292c5.6,0 10.4,-4.8 10.4,-10.4C302.4,145.6 297.6,140.8 292,140.8z\"/>\n  <path\n      android:fillColor=\"#FFF\"\n      android:pathData=\"M151.2,250.8c-5.6,0 -10.4,4.8 -10.4,10.4V292c0,5.6 4.8,10.4 10.4,10.4c5.6,0 10.4,-4.8 10.4,-10.4v-30.8C161.6,255.6 156.8,250.8 151.2,250.8z\"/>\n  <path\n      android:fillColor=\"#FFF\"\n      android:pathData=\"M258,243.6l-22,-22c-3.6,-4 -10.4,-4 -14.4,0s-4,10.4 0,14.4l22,22c4,4 10.4,4 14.4,0S262,247.6 258,243.6z\"/>\n  <path\n      android:fillColor=\"#FFF\"\n      android:pathData=\"M151.2,0c-5.6,0 -10.4,4.8 -10.4,10.4v30.8c0,5.6 4.8,10.4 10.4,10.4c5.6,0 10.4,-4.8 10.4,-10.4V10.4C161.6,4.8 156.8,0 151.2,0z\"/>\n  <path\n      android:fillColor=\"#FFF\"\n      android:pathData=\"M258.4,44.4c-4,-4 -10.4,-4 -14.4,0l-22,22c-4,4 -4,10.4 0,14.4c3.6,4 10.4,4 14.4,0l22,-22C262.4,54.8 262.4,48.4 258.4,44.4z\"/>\n  <path\n      android:fillColor=\"#FFF\"\n      android:pathData=\"M41.2,140.8H10.4c-5.6,0 -10.4,4.8 -10.4,10.4s4.4,10.4 10.4,10.4h30.8c5.6,0 10.4,-4.8 10.4,-10.4C51.6,145.6 46.8,140.8 41.2,140.8z\"/>\n  <path\n      android:fillColor=\"#FFF\"\n      android:pathData=\"M80.4,221.6c-3.6,-4 -10.4,-4 -14.4,0l-22,22c-4,4 -4,10.4 0,14.4s10.4,4 14.4,0l22,-22C84.4,232 84.4,225.6 80.4,221.6z\"/>\n  <path\n      android:fillColor=\"#FFF\"\n      android:pathData=\"M80.4,66.4l-22,-22c-4,-4 -10.4,-4 -14.4,0s-4,10.4 0,14.4l22,22c4,4 10.4,4 14.4,0S84.4,70.4 80.4,66.4z\"/>\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/netflix_brightness_three.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"30dp\"\n    android:height=\"30dp\"\n    android:viewportWidth=\"302.4\"\n    android:viewportHeight=\"302.4\">\n    <path\n        android:fillColor=\"#FFF\"\n        android:pathData=\"M204.8,97.6C191.2,84 172,75.2 151.2,75.2s-40,8.4 -53.6,22.4c-13.6,13.6 -22.4,32.8 -22.4,53.6s8.8,40 22.4,53.6c13.6,13.6 32.8,22.4 53.6,22.4s40,-8.4 53.6,-22.4c13.6,-13.6 22.4,-32.8 22.4,-53.6S218.8,111.2 204.8,97.6zM190.4,190.4c-10,10 -24,16 -39.2,16s-29.2,-6 -39.2,-16s-16,-24 -16,-39.2s6,-29.2 16,-39.2s24,-16 39.2,-16s29.2,6 39.2,16s16,24 16,39.2S200.4,180.4 190.4,190.4z\"/>\n    <path\n        android:fillColor=\"#FFF\"\n        android:pathData=\"M292,140.8h-30.8c-5.6,0 -10.4,4.8 -10.4,10.4c0,5.6 4.8,10.4 10.4,10.4H292c5.6,0 10.4,-4.8 10.4,-10.4C302.4,145.6 297.6,140.8 292,140.8z\"/>\n   <path\n        android:fillColor=\"#FFF\"\n        android:pathData=\"M258,243.6l-22,-22c-3.6,-4 -10.4,-4 -14.4,0s-4,10.4 0,14.4l22,22c4,4 10.4,4 14.4,0S262,247.6 258,243.6z\"/>\n    <path\n        android:fillColor=\"#FFF\"\n        android:pathData=\"M151.2,0c-5.6,0 -10.4,4.8 -10.4,10.4v30.8c0,5.6 4.8,10.4 10.4,10.4c5.6,0 10.4,-4.8 10.4,-10.4V10.4C161.6,4.8 156.8,0 151.2,0z\"/>\n    <path\n        android:fillColor=\"#FFF\"\n        android:pathData=\"M258.4,44.4c-4,-4 -10.4,-4 -14.4,0l-22,22c-4,4 -4,10.4 0,14.4c3.6,4 10.4,4 14.4,0l22,-22C262.4,54.8 262.4,48.4 258.4,44.4z\"/>\n\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/netflix_brightness_two.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"30dp\"\n    android:height=\"30dp\"\n    android:viewportWidth=\"302.4\"\n    android:viewportHeight=\"302.4\">\n    <path\n        android:fillColor=\"#FFF\"\n        android:pathData=\"M204.8,97.6C191.2,84 172,75.2 151.2,75.2s-40,8.4 -53.6,22.4c-13.6,13.6 -22.4,32.8 -22.4,53.6s8.8,40 22.4,53.6c13.6,13.6 32.8,22.4 53.6,22.4s40,-8.4 53.6,-22.4c13.6,-13.6 22.4,-32.8 22.4,-53.6S218.8,111.2 204.8,97.6zM190.4,190.4c-10,10 -24,16 -39.2,16s-29.2,-6 -39.2,-16s-16,-24 -16,-39.2s6,-29.2 16,-39.2s24,-16 39.2,-16s29.2,6 39.2,16s16,24 16,39.2S200.4,180.4 190.4,190.4z\"/>\n\n\n    <path\n        android:fillColor=\"#FFF\"\n        android:pathData=\"M151.2,0c-5.6,0 -10.4,4.8 -10.4,10.4v30.8c0,5.6 4.8,10.4 10.4,10.4c5.6,0 10.4,-4.8 10.4,-10.4V10.4C161.6,4.8 156.8,0 151.2,0z\"/>\n    <path\n        android:fillColor=\"#FFF\"\n        android:pathData=\"M258.4,44.4c-4,-4 -10.4,-4 -14.4,0l-22,22c-4,4 -4,10.4 0,14.4c3.6,4 10.4,4 14.4,0l22,-22C262.4,54.8 262.4,48.4 258.4,44.4z\"/>\n\n\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/netflix_lock_black.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"20dp\"\n    android:height=\"20dp\"\n    android:viewportWidth=\"512\"\n    android:viewportHeight=\"512\">\n    <path\n        android:fillColor=\"#000\"\n        android:pathData=\"M400,188h-36.037v-82.23c0,-58.322 -48.449,-105.77 -108,-105.77c-59.551,0 -108,47.448 -108,105.77V188H112c-33.084,0 -60,26.916 -60,60v204c0,33.084 26.916,60 60,60h288c33.084,0 60,-26.916 60,-60V248C460,214.916 433.084,188 400,188zM187.963,105.77c0,-36.266 30.505,-65.77 68,-65.77s68,29.504 68,65.77V188h-136V105.77zM420,452c0,11.028 -8.972,20 -20,20H112c-11.028,0 -20,-8.972 -20,-20V248c0,-11.028 8.972,-20 20,-20h288c11.028,0 20,8.972 20,20V452z\"/>\n    <path\n        android:fillColor=\"#000\"\n        android:pathData=\"M256,286c-20.435,0 -37,16.565 -37,37c0,13.048 6.76,24.51 16.963,31.098V398c0,11.045 8.954,20 20,20c11.045,0 20,-8.955 20,-20v-43.855C286.207,347.565 293,336.08 293,323C293,302.565 276.435,286 256,286z\"/>\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/netflix_pause_button.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"40dp\"\n    android:height=\"40dp\"\n    android:viewportWidth=\"357\"\n    android:viewportHeight=\"357\">\n  <path\n      android:fillColor=\"#FFF\"\n      android:pathData=\"M25.5,357h102V0h-102V357zM229.5,0v357h102V0H229.5z\"/>\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/netflix_speed.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"30dp\"\n    android:height=\"30dp\"\n    android:viewportWidth=\"511.999\"\n    android:viewportHeight=\"511.999\">\n    <path\n        android:fillColor=\"#FFF\"\n        android:pathData=\"M357.42,209.037c-9.09,-9.093 -23.832,-9.09\n        -32.924,0l-66.389,66.387c-3.286,-0.779 -6.708,-1.203 -10.23,-1.203c-24.435,\n        0 -44.316,19.897 -44.316,44.356c0,24.459 19.88,44.357 44.316,44.357c24.459,0\n         44.357,-19.899 44.357,-44.357c0,-3.522 -0.424,-6.944 -1.203,-10.23l66.387,\n         -66.387C366.513,232.87 366.513,218.128 357.42,209.037z\" />\n    <path\n        android:fillColor=\"#FFF\"\n        android:pathData=\"M437.082,120.098c-99.832,-99.835 -262.314,\n        -99.84 -362.204,0.005c-86.213,86.257 -99.573,222.314 -31.77,323.512c7.156,\n        10.681 21.62,13.535 32.301,6.382c10.681,-7.156 13.539,-21.618 6.382,-32.301c-19.051,\n        -28.435 -30.27,-60.236 -33.926,-92.597h21.889c12.857,0 23.281,-10.424 23.281,\n        -23.281s-10.424,-23.281 -23.281,-23.281H47.791c4.219,-38.675 19.11,-76.218 44.212,\n        -107.794l15.84,15.842c4.546,4.546 10.504,6.82 16.463,6.82c5.958,0 11.917,-2.274 16.461,\n        -6.82c9.092,-9.09 9.092,-23.832 0,-32.924l-15.913,-15.91c32.054,-25.745 69.977,\n        -40.678 108.842,-44.8v21.986c0,12.857 10.424,23.281 23.281,23.281c12.857,0 23.281,\n        -10.424 23.281,-23.281V93.162c38.183,4.412 75.369,19.281 106.874,44.598l-15.901,\n        15.902c-9.09,9.092 -9.089,23.832 0.002,32.925c4.547,4.546 10.504,6.818 16.463,\n        6.818s11.918,-2.274 16.463,-6.82l15.826,-15.826c25.107,31.573 40.002,69.111 44.224,\n        107.779h-21.961c-12.857,0 -23.281,10.424 -23.281,23.281c0,12.857 10.424,23.281 23.281,\n        23.281h21.89c-3.658,32.36 -14.88,64.159 -33.937,92.594c-7.158,10.681 -4.304,25.142 6.376,\n        32.3c3.981,2.668 8.485,3.945 12.941,3.945c7.503,0 14.869,-3.621 19.36,-10.321C536.708,\n        342.412 523.337,206.352 437.082,120.098z\" />\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/netflix_unlock.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"30dp\"\n    android:height=\"30dp\"\n    android:viewportWidth=\"253.334\"\n    android:viewportHeight=\"253.334\">\n  <path\n      android:fillColor=\"#FFF\"\n      android:pathData=\"M160.44,89.902H74.524V52.345C74.524,34.51 89.034,20 106.87,20s32.346,14.51 32.346,32.345V62.57c0,5.523 4.478,10 10,10s10,-4.477 10,-10V52.345C159.215,23.482 135.733,0 106.87,0S54.524,23.482 54.524,52.345v37.557h-1.225c-15.244,0 -27.646,12.402 -27.646,27.646v106.908c0,15.923 12.954,28.878 28.878,28.878h104.678c15.924,0 28.878,-12.955 28.878,-28.878V117.548C188.087,102.304 175.684,89.902 160.44,89.902zM168.087,224.456c0,4.896 -3.982,8.878 -8.878,8.878H54.531c-4.896,0 -8.878,-3.982 -8.878,-8.878V117.548c0,-4.216 3.431,-7.646 7.646,-7.646H160.44c4.216,0 7.646,3.43 7.646,7.646V224.456z\"/>\n  <path\n      android:fillColor=\"#FFF\"\n      android:pathData=\"M106.87,134.44c-11.409,0 -20.691,9.282 -20.691,20.691c0,7.783 4.324,14.57 10.691,18.102v25.562c0,5.523 4.478,10 10,10s10,-4.477 10,-10v-25.562c6.368,-3.532 10.691,-10.319 10.691,-18.102C127.561,143.722 118.279,134.44 106.87,134.44z\"/>\n\n\n\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/next_episode.xml",
    "content": "<vector android:height=\"40dp\" android:tint=\"#FFFFFF\"\n    android:viewportHeight=\"24\" android:viewportWidth=\"24\"\n    android:width=\"40dp\" xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <path android:fillColor=\"@android:color/white\" android:pathData=\"M6,18l8.5,-6L6,6v12zM16,6v12h2V6h-2z\"/>\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/play_ripple.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<selector xmlns:android=\"http://schemas.android.com/apk/res/android\">\n\n        <item android:state_pressed=\"true\"\n            android:drawable=\"@color/ripple_color\" /> <!-- pressed -->\n        <item android:state_focused=\"true\"\n            android:drawable=\"@color/ripple_color\" /> <!-- focused -->\n        <item android:state_hovered=\"true\"\n            android:drawable=\"@color/ripple_color\" /> <!-- hovered -->\n    <item android:drawable=\"@android:color/transparent\" /> <!-- default -->\n\n</selector>"
  },
  {
    "path": "app/src/main/res/drawable/player_controller_bg.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<layer-list xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <item>\n        <shape>\n            <gradient\n                android:angle=\"90\"\n                android:centerColor=\"@android:color/transparent\"\n                android:centerY=\"0.9\"\n                android:endColor=\"@android:color/black\"\n                android:startColor=\"@android:color/transparent\" />\n        </shape>\n    </item>\n    <item>\n        <shape>\n            <gradient\n                android:angle=\"90\"\n                android:centerColor=\"@android:color/transparent\"\n                android:centerY=\"0.3\"\n                android:endColor=\"@android:color/transparent\"\n                android:startColor=\"@android:color/black\" />\n        </shape>\n    </item>\n</layer-list>\n"
  },
  {
    "path": "app/src/main/res/drawable/properties.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"24dp\"\n    android:height=\"24dp\"\n    android:tint=\"#FFFFFF\"\n    android:viewportWidth=\"24\"\n    android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"@android:color/white\"\n        android:pathData=\"M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM13,17h-2v-2h2v2zM13,13h-2L11,7h2v6z\" />\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/quality_24.xml",
    "content": "<vector android:height=\"24dp\" android:tint=\"#FFFFFF\"\n    android:viewportHeight=\"24\" android:viewportWidth=\"24\"\n    android:width=\"24dp\" xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <path android:fillColor=\"@android:color/white\" android:pathData=\"M19,4L5,4c-1.11,0 -2,0.9 -2,2v12c0,1.1 0.89,2 2,2h14c1.1,0 2,-0.9 2,-2L21,6c0,-1.1 -0.9,-2 -2,-2zM11,15L9.5,15v-2h-2v2L6,15L6,9h1.5v2.5h2L9.5,9L11,9v6zM18,14c0,0.55 -0.45,1 -1,1h-0.75v1.5h-1.5L14.75,15L14,15c-0.55,0 -1,-0.45 -1,-1v-4c0,-0.55 0.45,-1 1,-1h3c0.55,0 1,0.45 1,1v4zM14.5,13.5h2v-3h-2v3z\"/>\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/radio_group_tab_bg.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<shape xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:shape=\"rectangle\"\n    >\n\n    <solid android:color=\"#ECEDEF\" />\n    <stroke\n        android:width=\"0.5dp\"\n        android:color=\"#9AA2AF\"\n        />\n    <corners android:radius=\"30dp\"/>\n</shape>"
  },
  {
    "path": "app/src/main/res/drawable/rectangle_box.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<shape xmlns:android=\"http://schemas.android.com/apk/res/android\" android:shape=\"rectangle\">\n    <solid android:color=\"@android:color/transparent\"/>\n    <stroke android:width=\"10dp\" android:color=\"@color/colorPrimary\"/>\n    <corners android:radius=\"10dp\"/>\n</shape>"
  },
  {
    "path": "app/src/main/res/drawable/rectangle_box_slim.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<shape xmlns:android=\"http://schemas.android.com/apk/res/android\" android:shape=\"rectangle\">\n    <solid android:color=\"@android:color/transparent\"/>\n    <stroke android:width=\"5dp\" android:color=\"@color/colorPrimary\"/>\n    <corners android:radius=\"10dp\"/>\n</shape>"
  },
  {
    "path": "app/src/main/res/drawable/selected_quality.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<shape xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:shape=\"rectangle\">\n    <gradient\n        android:startColor=\"#DDDDDD\"\n        android:endColor=\"#00DDDDDD\"\n        android:type=\"linear\"\n        android:angle=\"90\" />\n</shape>\n"
  },
  {
    "path": "app/src/main/res/drawable/selected_subtitle.xml",
    "content": "<vector android:alpha=\"0.9\" android:height=\"24dp\" android:tint=\"#FFFFFF\"\n    android:viewportHeight=\"24\" android:viewportWidth=\"24\"\n    android:width=\"24dp\" xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <path android:fillColor=\"@android:color/white\" android:pathData=\"M9,16.17L4.83,12l-1.42,1.41L9,19 21,7l-1.41,-1.41z\"/>\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/share.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"24dp\"\n    android:height=\"24dp\"\n    android:tint=\"#FFFFFF\"\n    android:viewportWidth=\"24\"\n    android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"@android:color/white\"\n        android:pathData=\"M18,16.08c-0.76,0 -1.44,0.3 -1.96,0.77L8.91,12.7c0.05,-0.23 0.09,-0.46 0.09,-0.7s-0.04,-0.47 -0.09,-0.7l7.05,-4.11c0.54,0.5 1.25,0.81 2.04,0.81 1.66,0 3,-1.34 3,-3s-1.34,-3 -3,-3 -3,1.34 -3,3c0,0.24 0.04,0.47 0.09,0.7L8.04,9.81C7.5,9.31 6.79,9 6,9c-1.66,0 -3,1.34 -3,3s1.34,3 3,3c0.79,0 1.5,-0.31 2.04,-0.81l7.12,4.16c-0.05,0.21 -0.08,0.43 -0.08,0.65 0,1.61 1.31,2.92 2.92,2.92 1.61,0 2.92,-1.31 2.92,-2.92s-1.31,-2.92 -2.92,-2.92z\" />\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/share_link.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"48dp\"\n    android:height=\"48dp\"\n    android:tint=\"#FFFFFF\"\n    android:viewportWidth=\"24\"\n    android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"@android:color/white\"\n        android:pathData=\"M3.9,12c0,-1.71 1.39,-3.1 3.1,-3.1h4L11,7L7,7c-2.76,0 -5,2.24 -5,5s2.24,5 5,5h4v-1.9L7,15.1c-1.71,0 -3.1,-1.39 -3.1,-3.1zM8,13h8v-2L8,11v2zM17,7h-4v1.9h4c1.71,0 3.1,1.39 3.1,3.1s-1.39,3.1 -3.1,3.1h-4L13,17h4c2.76,0 5,-2.24 5,-5s-2.24,-5 -5,-5z\" />\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/tab_selector.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<selector xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <item android:state_checked=\"true\">\n        <shape  android:shape=\"rectangle\"\n\n            >\n            <corners android:radius=\"30dp\"/>\n            <solid android:color=\"@color/colorPrimary\"/>\n        </shape>\n        </item>\n\n    <item android:state_pressed=\"true\">\n    <shape  android:shape=\"rectangle\"\n\n        >\n        <corners android:radius=\"30dp\"/>\n        <solid android:color=\"@color/ripple_color\"/>\n    </shape>\n    </item>\n    <item android:state_focused=\"true\">\n        <shape  android:shape=\"rectangle\"\n\n            >\n            <corners android:radius=\"30dp\"/>\n            <solid android:color=\"@color/ripple_color\"/>\n        </shape>\n    </item>\n    <item android:state_hovered=\"true\">\n    <shape  android:shape=\"rectangle\"\n\n        >\n        <corners android:radius=\"30dp\"/>\n        <solid android:color=\"@color/ripple_color\"/>\n    </shape>\n        </item>\n</selector>"
  },
  {
    "path": "app/src/main/res/drawable/tab_text_color_selector.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<selector xmlns:android=\"http://schemas.android.com/apk/res/android\">\n\n    <item android:color = \"#FFFFFF\" android:state_checked=\"true\"/>\n\n    <item android:color = \"#ADB3BE\" android:state_checked=\"false\"/>\n</selector>"
  },
  {
    "path": "app/src/main/res/drawable/volume_up_24.xml",
    "content": "<vector android:alpha=\"0.9\" android:autoMirrored=\"true\"\n    android:height=\"24dp\" android:tint=\"#FFFFFF\"\n    android:viewportHeight=\"24\" android:viewportWidth=\"24\"\n    android:width=\"24dp\" xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <path android:fillColor=\"@android:color/white\" android:pathData=\"M3,9v6h4l5,5L12,4L7,9L3,9zM16.5,12c0,-1.77 -1.02,-3.29 -2.5,-4.03v8.05c1.48,-0.73 2.5,-2.25 2.5,-4.02zM14,3.23v2.06c2.89,0.86 5,3.54 5,6.71s-2.11,5.85 -5,6.71v2.06c4.01,-0.91 7,-4.49 7,-8.77s-2.99,-7.86 -7,-8.77z\"/>\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/white_round.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<shape xmlns:android=\"http://schemas.android.com/apk/res/android\">\n\n    <solid android:color=\"@color/white\"/>\n    <corners android:radius=\"50dp\"/>\n\n</shape>"
  },
  {
    "path": "app/src/main/res/drawable-v24/ic_launcher_foreground.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:aapt=\"http://schemas.android.com/aapt\"\n    android:width=\"108dp\"\n    android:height=\"108dp\"\n    android:viewportWidth=\"108\"\n    android:viewportHeight=\"108\">\n    <path android:pathData=\"M31,63.928c0,0 6.4,-11 12.1,-13.1c7.2,-2.6 26,-1.4 26,-1.4l38.1,38.1L107,108.928l-32,-1L31,63.928z\">\n        <aapt:attr name=\"android:fillColor\">\n            <gradient\n                android:endX=\"85.84757\"\n                android:endY=\"92.4963\"\n                android:startX=\"42.9492\"\n                android:startY=\"49.59793\"\n                android:type=\"linear\">\n                <item\n                    android:color=\"#44000000\"\n                    android:offset=\"0.0\" />\n                <item\n                    android:color=\"#00000000\"\n                    android:offset=\"1.0\" />\n            </gradient>\n        </aapt:attr>\n    </path>\n    <path\n        android:fillColor=\"#FFFFFF\"\n        android:fillType=\"nonZero\"\n        android:pathData=\"M65.3,45.828l3.8,-6.6c0.2,-0.4 0.1,-0.9 -0.3,-1.1c-0.4,-0.2 -0.9,-0.1 -1.1,0.3l-3.9,6.7c-6.3,-2.8 -13.4,-2.8 -19.7,0l-3.9,-6.7c-0.2,-0.4 -0.7,-0.5 -1.1,-0.3C38.8,38.328 38.7,38.828 38.9,39.228l3.8,6.6C36.2,49.428 31.7,56.028 31,63.928h46C76.3,56.028 71.8,49.428 65.3,45.828zM43.4,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2c-0.3,-0.7 -0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C45.3,56.528 44.5,57.328 43.4,57.328L43.4,57.328zM64.6,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2s-0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C66.5,56.528 65.6,57.328 64.6,57.328L64.6,57.328z\"\n        android:strokeWidth=\"1\"\n        android:strokeColor=\"#00000000\" />\n</vector>"
  },
  {
    "path": "app/src/main/res/font/exo_2.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<font-family xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n        app:fontProviderAuthority=\"com.google.android.gms.fonts\"\n        app:fontProviderPackage=\"com.google.android.gms\"\n        app:fontProviderQuery=\"Exo 2\"\n        app:fontProviderCerts=\"@array/com_google_android_gms_fonts_certs\">\n</font-family>\n"
  },
  {
    "path": "app/src/main/res/font/exo_2_thin.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<font-family xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n        app:fontProviderAuthority=\"com.google.android.gms.fonts\"\n        app:fontProviderPackage=\"com.google.android.gms\"\n        app:fontProviderQuery=\"name=Exo 2&amp;weight=100\"\n        app:fontProviderCerts=\"@array/com_google_android_gms_fonts_certs\">\n</font-family>\n"
  },
  {
    "path": "app/src/main/res/layout/activity_main.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n\n<androidx.coordinatorlayout.widget.CoordinatorLayout\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\">\n\n\n\n    <androidx.core.widget.NestedScrollView\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:id=\"@+id/nestedScrollView\"\n        app:layout_behavior=\"@string/appbar_scrolling_view_behavior\"\n        android:layout_marginBottom=\"70dp\"\n        >\n\n        <LinearLayout\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"match_parent\"\n            android:orientation=\"vertical\"\n            >\n            <TextView\n                android:layout_width=\"wrap_content\"\n                android:layout_height=\"wrap_content\"\n                android:visibility=\"gone\"\n                android:id=\"@+id/continue_watching_text\"\n                android:layout_margin=\"10dp\"\n                android:text=\"@string/continue_watching\"\n                android:fontFamily=\"@font/exo_2\"\n                android:textAppearance=\"@style/TextAppearance.AppCompat.Display1\"\n                />\n\n            <androidx.recyclerview.widget.RecyclerView\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\"\n                android:visibility=\"gone\"\n                android:layout_margin=\"10dp\"\n                android:id=\"@+id/watch_history_rc\"\n                />\n\n            <fragment\n                android:layout_width=\"match_parent\"\n                android:id=\"@+id/nav_host_fragment\"\n                android:name=\"androidx.navigation.fragment.NavHostFragment\"\n                app:navGraph = \"@navigation/nav_main\"\n                app:defaultNavHost = \"true\"\n                android:layout_height=\"match_parent\"\n                app:layout_constraintTop_toBottomOf=\"@+id/card_container\"\n                app:layout_constraintStart_toStartOf=\"parent\"\n                app:layout_constraintEnd_toEndOf=\"parent\"\n                tools:ignore=\"FragmentTagUsage\" />\n\n\n        </LinearLayout>\n\n    </androidx.core.widget.NestedScrollView>\n\n    <com.google.android.material.bottomnavigation.BottomNavigationView\n        android:id=\"@+id/bottom_nav_bar\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"60dp\"\n        android:layout_gravity=\"bottom\"\n        app:menu=\"@menu/bottom_nav\" />\n\n</androidx.coordinatorlayout.widget.CoordinatorLayout>\n\n<!--    <androidx.appcompat.widget.Toolbar-->\n<!--        android:layout_width=\"match_parent\"-->\n<!--        android:layout_height=\"?attr/actionBarSize\"-->\n<!--        app:theme=\"@style/ThemeOverlay.AppCompat.ActionBar\"-->\n<!--        android:id=\"@+id/toolbar\"-->\n<!--        app:layout_constraintTop_toTopOf=\"parent\"-->\n<!--        app:layout_constraintStart_toStartOf=\"parent\"-->\n<!--        app:layout_constraintEnd_toEndOf=\"parent\"-->\n<!--        />-->\n\n<!--    <ScrollView-->\n<!--        android:layout_width=\"match_parent\"-->\n<!--        android:layout_height=\"wrap_content\"-->\n<!--        app:layout_constraintTop_toBottomOf=\"@+id/toolbar\"-->\n<!--        app:layout_constraintStart_toStartOf=\"parent\"-->\n<!--        app:layout_constraintEnd_toEndOf=\"parent\"-->\n<!--        >-->\n\n            <!--    <TextView-->\n            <!--        android:id=\"@+id/movies_text\"-->\n            <!--        android:layout_width=\"wrap_content\"-->\n            <!--        android:layout_height=\"wrap_content\"-->\n            <!--        android:layout_margin=\"5dp\"-->\n            <!--        android:fontFamily=\"sans-serif-condensed-light\"-->\n            <!--        android:text=\"@string/movies\"-->\n            <!--        android:textAppearance=\"@style/TextAppearance.AppCompat.Display1\"-->\n            <!--        app:layout_constraintStart_toStartOf=\"parent\"-->\n            <!--        app:layout_constraintTop_toBottomOf=\"@+id/card_container\" />-->\n\n            <!--    <Button-->\n            <!--        android:id=\"@+id/check_button\"-->\n            <!--        android:layout_width=\"wrap_content\"-->\n            <!--        android:layout_height=\"wrap_content\"-->\n            <!--        android:background=\"@color/green\"-->\n            <!--        app:layout_constraintBottom_toTopOf=\"@+id/movie_recycler_view\"-->\n            <!--        app:layout_constraintEnd_toEndOf=\"parent\"-->\n            <!--        app:layout_constraintStart_toEndOf=\"@id/movies_text\" />-->\n\n            <!--    <androidx.recyclerview.widget.RecyclerView-->\n            <!--        android:id=\"@+id/movie_recycler_view\"-->\n            <!--        android:layout_width=\"0dp\"-->\n            <!--        android:layout_margin=\"10dp\"-->\n            <!--        android:layout_height=\"wrap_content\"-->\n\n            <!--        app:layout_constraintEnd_toEndOf=\"parent\"-->\n            <!--        app:layout_constraintStart_toStartOf=\"parent\"-->\n            <!--        app:layout_constraintTop_toBottomOf=\"@+id/movies_text\"-->\n            <!--/>-->\n            <!--    <TextView-->\n            <!--        android:id=\"@+id/popular_text\"-->\n            <!--        android:layout_width=\"wrap_content\"-->\n            <!--        android:layout_height=\"wrap_content\"-->\n            <!--        android:layout_margin=\"5dp\"-->\n            <!--        android:fontFamily=\"sans-serif-condensed-light\"-->\n            <!--        android:text=\"@string/popular\"-->\n            <!--        android:textAppearance=\"@style/TextAppearance.AppCompat.Display1\"-->\n            <!--        app:layout_constraintTop_toBottomOf=\"@id/movie_recycler_view\"-->\n            <!--        app:layout_constraintStart_toStartOf=\"parent\"-->\n\n            <!--        />-->\n\n            <!--    <androidx.recyclerview.widget.RecyclerView-->\n            <!--        android:id=\"@+id/tv_recycler_view\"-->\n            <!--        android:layout_width=\"0dp\"-->\n            <!--        android:layout_margin=\"10dp\"-->\n            <!--        android:layout_height=\"wrap_content\"-->\n            <!--        app:layout_constraintEnd_toEndOf=\"parent\"-->\n            <!--        app:layout_constraintStart_toStartOf=\"parent\"-->\n            <!--        app:layout_constraintTop_toBottomOf=\"@+id/popular_text\" />-->\n\n\n\n"
  },
  {
    "path": "app/src/main/res/layout/activity_movie_play.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RelativeLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:id=\"@+id/z_layout\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    tools:context=\".MoviePlayActivity\">\n\n    <WebView\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:visibility=\"gone\"\n        android:id=\"@+id/web_view\"/>\n<!--    <androidx.media3.ui.PlayerView-->\n<!--        android:layout_width=\"match_parent\"-->\n<!--        android:id=\"@+id/video_view\"-->\n<!--        android:visibility=\"gone\"-->\n<!--        android:layout_height=\"match_parent\"-->\n<!--        />-->\n\n\n    <androidx.recyclerview.widget.RecyclerView\n        android:id=\"@+id/results_rc\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:layout_marginStart=\"25dp\"\n        android:layout_marginTop=\"25dp\"\n        android:layout_marginEnd=\"25dp\"\n        android:layout_marginBottom=\"25dp\" />\n\n    <ProgressBar\n        android:id=\"@+id/loading_content\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"50dp\"\n        android:visibility=\"gone\"\n        android:layout_centerVertical=\"true\"\n        />\n\n<!--    <include layout=\"@layout/custom_video_player\"/>-->\n</RelativeLayout>"
  },
  {
    "path": "app/src/main/res/layout/activity_video_play.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    tools:context=\".VideoPlayActivity\"\n    android:orientation=\"horizontal\">\n\n    <FrameLayout\n        android:layout_width=\"match_parent\"\n        android:id=\"@+id/main_player\"\n        android:layout_height=\"match_parent\"\n        android:visibility=\"gone\"\n        tools:visibility=\"gone\"\n        >\n\n    <androidx.media3.ui.PlayerView\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:id=\"@+id/video_view\"\n        android:background=\"@color/black\"\n        app:controller_layout_id=\"@layout/custom_video_player2\"/>\n\n    <LinearLayout\n        android:id=\"@+id/videoView_two_layout\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"180dp\"\n        android:layout_marginStart=\"30dp\"\n        android:layout_marginLeft=\"30dp\"\n        android:orientation=\"vertical\"\n        android:visibility=\"gone\"\n        android:layout_gravity=\"center_vertical\"\n        tools:visibility=\"visible\"\n        >\n\n\n        <ImageView\n            android:id=\"@+id/videoView_brightness_image\"\n            android:layout_width=\"24dp\"\n            android:layout_height=\"24dp\"\n            android:layout_marginStart=\"2dp\"\n            android:layout_marginLeft=\"2dp\"\n            android:layout_marginBottom=\"7dp\"\n            android:layout_weight=\"0\"\n            android:src=\"@drawable/netflix_brightness_four\" />\n\n        <SeekBar\n            android:id=\"@+id/videoView_brightness\"\n            android:layout_width=\"130dp\"\n            android:layout_height=\"wrap_content\"\n            android:layout_marginStart=\"-50dp\"\n            android:layout_marginEnd=\"-50dp\"\n            android:layout_weight=\"1\"\n            android:max=\"255\"\n            android:progress=\"150\"\n            android:progressBackgroundTint=\"@color/white\"\n            android:progressTint=\"@color/red\"\n            android:rotation=\"270\"\n            android:scaleY=\"3\"\n            android:thumb=\"@null\"\n             />\n\n        </LinearLayout>\n\n        <LinearLayout\n            android:id=\"@+id/volume_ll\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"180dp\"\n            android:layout_marginStart=\"30dp\"\n            android:layout_marginLeft=\"30dp\"\n            android:orientation=\"vertical\"\n            android:visibility=\"gone\"\n            android:layout_gravity=\"center_vertical|end\"\n            tools:visibility=\"visible\"\n            >\n\n\n            <ImageView\n                android:id=\"@+id/volume_image\"\n                android:layout_width=\"24dp\"\n                android:layout_height=\"24dp\"\n                android:layout_marginStart=\"2dp\"\n                android:layout_marginLeft=\"2dp\"\n                android:layout_marginBottom=\"7dp\"\n                android:layout_weight=\"0\"\n                android:src=\"@drawable/volume_up_24\" />\n\n            <SeekBar\n                android:id=\"@+id/volume_seek\"\n                android:layout_width=\"130dp\"\n                android:layout_height=\"wrap_content\"\n                android:layout_marginStart=\"-50dp\"\n                android:layout_marginEnd=\"-30dp\"\n                android:layout_weight=\"1\"\n                android:max=\"255\"\n                android:progress=\"150\"\n                android:progressBackgroundTint=\"@color/white\"\n                android:progressTint=\"@color/red\"\n                android:rotation=\"270\"\n                android:scaleY=\"3\"\n                android:thumb=\"@null\"\n                />\n\n        </LinearLayout>\n\n        <ImageView\n            android:layout_width=\"40dp\"\n            android:layout_height=\"40dp\"\n            android:id=\"@+id/unlock_controls\"\n            android:visibility=\"gone\"\n            android:layout_gravity=\"bottom\"\n            android:layout_margin=\"25dp\"\n            android:src=\"@drawable/baseline_lock_open_24\"\n            />\n\n        <androidx.media3.ui.SubtitleView\n            android:id=\"@+id/custom_subtitles\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"match_parent\"\n            android:layout_marginBottom=\"20dp\"\n            />\n\n\n    </FrameLayout>\n    <FrameLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:visibility=\"visible\"\n        tools:visibility=\"gone\"\n        android:id=\"@+id/video_loading_fl\"\n        >\n        <WebView\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"match_parent\"\n            android:visibility=\"invisible\"\n            android:id=\"@+id/web_view2\"/>\n    <ProgressBar\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:layout_gravity=\"center\"\n        android:visibility=\"visible\"\n        android:id=\"@+id/video_loading\"\n        />\n    </FrameLayout>\n\n    <androidx.constraintlayout.widget.ConstraintLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:background=\"@color/black\"\n        android:id=\"@+id/subtitle_select\"\n        android:visibility=\"gone\"\n        tools:visibility=\"visible\"\n        >\n\n        <androidx.recyclerview.widget.RecyclerView\n            android:id=\"@+id/sub_tracks_rc\"\n            android:layout_width=\"0dp\"\n            app:layout_constraintWidth_percent=\"0.5\"\n            app:layout_constraintHeight_percent=\"0.5\"\n            android:layout_height=\"0dp\"\n            android:layout_gravity=\"center\"\n            android:layout_margin=\"10dp\"\n            app:layout_constraintBottom_toTopOf=\"@id/add_open_sub\"\n\n            app:layout_constraintStart_toStartOf=\"parent\"\n            app:layout_constraintTop_toTopOf=\"parent\" />\n\n        <TextView\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:text=\"Sources\"\n            android:textSize=\"20sp\"\n            android:layout_margin=\"10dp\"\n            app:layout_constraintBottom_toTopOf=\"@+id/source_change_rc\"\n            app:layout_constraintStart_toEndOf=\"@+id/sub_tracks_rc\" />\n\n        <ProgressBar\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:id=\"@+id/source_loading\"\n            app:layout_constraintBottom_toTopOf=\"@+id/apply_sub\"\n            app:layout_constraintEnd_toEndOf=\"@+id/source_change_rc\"\n            app:layout_constraintStart_toStartOf=\"@+id/source_change_rc\"\n            app:layout_constraintTop_toTopOf=\"parent\" />\n\n        <androidx.recyclerview.widget.RecyclerView\n            android:id=\"@+id/source_change_rc\"\n            android:layout_width=\"0dp\"\n            android:layout_height=\"wrap_content\"\n            android:layout_gravity=\"center\"\n            android:layout_margin=\"20dp\"\n            app:layout_constraintBottom_toTopOf=\"@id/apply_sub\"\n            app:layout_constraintEnd_toEndOf=\"parent\"\n            app:layout_constraintStart_toEndOf=\"@+id/sub_tracks_rc\"\n            app:layout_constraintTop_toTopOf=\"parent\"\n            app:layout_constraintWidth_percent=\"0.45\" />\n\n        <Button\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:layout_margin=\"25dp\"\n            android:id=\"@+id/add_open_sub\"\n            android:text=\"Add From Open Sub\"\n            app:layout_constraintBottom_toTopOf=\"@+id/switchcompat\"\n            app:layout_constraintStart_toStartOf=\"parent\" />\n\n        <com.google.android.material.switchmaterial.SwitchMaterial\n            android:id=\"@+id/switchcompat\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:textAppearance=\"@style/TextAppearance.AppCompat.Medium\"\n            android:checked=\"true\"\n            android:text=\"Subtitles\"\n            app:layout_constraintStart_toStartOf=\"parent\"\n            app:layout_constraintBottom_toBottomOf=\"parent\"\n            android:layout_margin=\"25dp\"\n            />\n\n        <Button\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:id=\"@+id/apply_sub\"\n            android:layout_margin=\"25dp\"\n            android:text=\"Apply\"\n            app:layout_constraintBottom_toBottomOf=\"parent\"\n            app:layout_constraintEnd_toEndOf=\"parent\" />\n\n    </androidx.constraintlayout.widget.ConstraintLayout>\n\n    <androidx.constraintlayout.widget.ConstraintLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:background=\"@color/black\"\n        android:id=\"@+id/quality_select\"\n        android:orientation=\"vertical\"\n        android:visibility=\"gone\"\n        tools:visibility=\"gone\"\n        >\n\n        <androidx.recyclerview.widget.RecyclerView\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:layout_gravity=\"center\"\n            android:id=\"@+id/tracks_rc\"\n            app:layout_constraintBottom_toBottomOf=\"parent\"\n            app:layout_constraintEnd_toEndOf=\"parent\"\n            app:layout_constraintStart_toStartOf=\"parent\"\n            app:layout_constraintTop_toTopOf=\"parent\" />\n\n\n        <Button\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:id=\"@+id/apply_quality\"\n            android:layout_margin=\"25dp\"\n            android:text=\"Apply\"\n            app:layout_constraintBottom_toBottomOf=\"parent\"\n            app:layout_constraintEnd_toEndOf=\"parent\" />\n\n    </androidx.constraintlayout.widget.ConstraintLayout>\n\n    <LinearLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:id=\"@+id/open_sub_ll\"\n        android:visibility=\"gone\"\n        tools:visibility=\"visible\"\n        android:orientation=\"vertical\"\n        tools:context=\".scrapers.OpenSubtitle\">\n\n\n        <LinearLayout\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:orientation=\"horizontal\">\n        <Spinner\n            android:layout_width=\"0dp\"\n            android:layout_weight=\"1\"\n            android:id=\"@+id/spinner\"\n            android:padding=\"10dp\"\n            android:layout_margin=\"10dp\"\n            android:layout_height=\"wrap_content\"\n            android:layout_gravity=\"center\"\n            />\n\n        <Button\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:layout_margin = \"20dp\"\n            android:id=\"@+id/search\"\n            android:text=\"Search\"\n            android:layout_gravity=\"center\"\n            />\n\n        <Button\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:id=\"@+id/apply\"\n            android:text=\"Apply\"\n            android:layout_marginEnd=\"10dp\"\n            android:layout_gravity=\"center\"\n            />\n        </LinearLayout>\n\n        <androidx.recyclerview.widget.RecyclerView\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:layout_margin=\"20dp\"\n            android:id=\"@+id/sub_rc\"\n            />\n\n    </LinearLayout>\n\n    <include layout=\"@layout/custom_video_player2\"\n        android:visibility=\"gone\"\n        />\n\n<!--    <Button-->\n<!--        android:id=\"@+id/button\"-->\n<!--        android:layout_width=\"wrap_content\"-->\n<!--        android:layout_height=\"wrap_content\"/>-->\n\n</LinearLayout>"
  },
  {
    "path": "app/src/main/res/layout/card_view.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<androidx.cardview.widget.CardView xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"wrap_content\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\">\n    <androidx.constraintlayout.widget.ConstraintLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"240dp\">\n\n        <com.google.android.material.imageview.ShapeableImageView\n            android:id=\"@+id/vertical_container\"\n            android:layout_width=\"0dp\"\n            android:layout_height=\"230dp\"\n            android:layout_margin=\"5dp\"\n            app:layout_constraintBottom_toBottomOf=\"parent\"\n            app:layout_constraintStart_toStartOf=\"parent\"\n            app:layout_constraintTop_toTopOf=\"parent\"\n            app:shapeAppearance=\"@style/roundedImageView\"\n            android:scaleType=\"centerCrop\"\n            app:layout_constraintWidth_percent=\"0.45\" />\n\n        <com.google.android.material.imageview.ShapeableImageView\n            android:id=\"@+id/horizontal_container1\"\n            android:layout_width=\"0dp\"\n            android:layout_height=\"112dp\"\n            android:scaleType=\"fitCenter\"\n            android:layout_margin=\"5dp\"\n            app:shapeAppearance=\"@style/roundedImageView\"\n            app:layout_constraintEnd_toEndOf=\"parent\"\n            app:layout_constraintStart_toEndOf=\"@+id/vertical_container\"\n            app:layout_constraintTop_toTopOf=\"parent\"\n            app:layout_constraintWidth_percent=\"0.5\" />\n\n        <com.google.android.material.imageview.ShapeableImageView\n            android:id=\"@+id/horizontal_container2\"\n            android:layout_width=\"0dp\"\n            android:layout_height=\"112dp\"\n            android:scaleType=\"fitCenter\"\n            app:shapeAppearance=\"@style/roundedImageView\"\n            android:layout_margin=\"5dp\"\n            app:layout_constraintEnd_toEndOf=\"parent\"\n            app:layout_constraintStart_toEndOf=\"@+id/vertical_container\"\n            app:layout_constraintTop_toBottomOf=\"@+id/horizontal_container1\"\n            app:layout_constraintWidth_percent=\"0.5\" />\n    </androidx.constraintlayout.widget.ConstraintLayout>\n    </androidx.cardview.widget.CardView>"
  },
  {
    "path": "app/src/main/res/layout/custom_video_player2.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<androidx.constraintlayout.widget.ConstraintLayout\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    android:layout_width=\"match_parent\"\n    android:background=\"@drawable/player_controller_bg\"\n    android:layout_height=\"match_parent\">\n\n    <LinearLayout\n        android:id=\"@+id/videoView_one_layout\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:gravity=\"center\"\n        android:orientation=\"horizontal\"\n        android:visibility=\"visible\"\n        app:layout_constraintTop_toTopOf=\"parent\">\n\n        <ImageButton\n            android:id=\"@+id/videoView_go_back\"\n            android:layout_width=\"48dp\"\n            android:layout_height=\"48dp\"\n            android:layout_weight=\"0\"\n            android:background=\"@drawable/play_ripple\"\n            android:focusable=\"true\"\n            android:src=\"@drawable/ic_baseline_keyboard_backspace_24\" />\n\n        <TextView\n            android:id=\"@+id/videoView_title\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:layout_weight=\"1\"\n            android:gravity=\"center\"\n            android:maxLines=\"2\"\n            android:text=\"Movie Name\"\n            android:textColor=\"@color/white\" />\n\n        <TextView\n            android:id=\"@+id/videoView_quality\"\n            android:layout_width=\"48dp\"\n            android:layout_height=\"48dp\"\n            android:layout_weight=\"0\"\n            android:text=\"1080p\"\n            android:gravity=\"center\"\n            android:textColor=\"@color/white\"\n\n             />\n\n    </LinearLayout>\n\n<!--    <LinearLayout-->\n<!--        android:id=\"@+id/videoView_two_layout\"-->\n<!--        android:layout_width=\"wrap_content\"-->\n<!--        android:layout_height=\"180dp\"-->\n<!--        android:layout_marginStart=\"30dp\"-->\n<!--        android:layout_marginLeft=\"30dp\"-->\n<!--        android:orientation=\"vertical\"-->\n<!--        android:visibility=\"gone\"-->\n<!--        tools:visibility=\"visible\"-->\n<!--        app:layout_constraintBottom_toTopOf=\"@id/videoView_four_layout\"-->\n<!--        app:layout_constraintLeft_toLeftOf=\"parent\"-->\n<!--        app:layout_constraintTop_toBottomOf=\"@id/videoView_one_layout\">-->\n\n\n<!--        <ImageView-->\n<!--            android:id=\"@+id/videoView_brightness_image\"-->\n<!--            android:layout_width=\"24dp\"-->\n<!--            android:layout_height=\"24dp\"-->\n<!--            android:layout_marginStart=\"2dp\"-->\n<!--            android:layout_marginLeft=\"2dp\"-->\n<!--            android:layout_marginBottom=\"7dp\"-->\n<!--            android:layout_weight=\"0\"-->\n<!--            android:src=\"@drawable/netflix_brightness_four\" />-->\n\n<!--        <SeekBar-->\n<!--            android:id=\"@+id/videoView_brightness\"-->\n<!--            android:layout_width=\"130dp\"-->\n<!--            android:layout_height=\"wrap_content\"-->\n<!--            android:layout_marginStart=\"-50dp\"-->\n<!--            android:layout_marginLeft=\"-50dp\"-->\n<!--            android:layout_weight=\"1\"-->\n<!--            android:max=\"255\"-->\n<!--            android:progress=\"150\"-->\n<!--            android:progressBackgroundTint=\"@color/white\"-->\n<!--            android:progressTint=\"@color/red\"-->\n<!--            android:rotation=\"270\"-->\n<!--            android:scaleY=\"3\"-->\n<!--            android:thumb=\"@null\"-->\n<!--            tools:targetApi=\"lollipop\" />-->\n\n<!--    </LinearLayout>-->\n\n    <LinearLayout\n        android:id=\"@+id/videoView_three_layout\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:gravity=\"center\"\n        android:orientation=\"horizontal\"\n        android:visibility=\"visible\"\n        app:layout_constraintBottom_toBottomOf=\"parent\"\n        app:layout_constraintTop_toTopOf=\"parent\">\n\n\n        <Space\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:layout_weight=\"1.3\" />\n\n        <ImageButton\n            android:id=\"@+id/videoView_rewind\"\n            android:layout_width=\"60dp\"\n            android:layout_height=\"60dp\"\n            android:background=\"@drawable/play_ripple\"\n            android:focusable=\"true\"\n            android:src=\"@drawable/ic_rewind\" />\n\n        <Space\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:layout_weight=\"1\" />\n\n\n        <FrameLayout\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\">\n            <ImageButton\n            android:id=\"@+id/videoView_play_pause_btn\"\n            android:layout_width=\"80dp\"\n            android:layout_height=\"80dp\"\n                android:visibility=\"gone\"\n            android:background=\"@drawable/play_ripple\"\n              android:focusable=\"true\"\n            android:src=\"@drawable/netflix_pause_button\" />\n\n            <ProgressBar\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"match_parent\"\n                android:layout_gravity=\"center\"\n                android:id=\"@+id/buffering\"\n                />\n        </FrameLayout>\n\n        <Space\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:layout_weight=\"1\" />\n\n\n        <ImageButton\n            android:id=\"@+id/videoView_forward\"\n            android:layout_width=\"60dp\"\n            android:background=\"@drawable/play_ripple\"\n            android:focusable=\"true\"\n            android:layout_height=\"60dp\"\n            android:src=\"@drawable/ic_forward\" />\n\n        <Space\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:layout_weight=\"1.3\" />\n\n\n    </LinearLayout>\n\n    <LinearLayout\n        android:id=\"@+id/videoView_four_layout\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:orientation=\"vertical\"\n        android:visibility=\"visible\"\n        app:layout_constraintBottom_toBottomOf=\"parent\">\n\n\n        <LinearLayout\n            android:id=\"@+id/videoView_four_one_child_layout\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:layout_gravity=\"center\"\n            android:gravity=\"center\"\n            android:orientation=\"horizontal\"\n            android:padding=\"8dp\">\n\n            <SeekBar\n                android:id=\"@+id/videoView_seekbar\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\"\n                android:layout_weight=\"1\"\n                android:progress=\"50\"\n                android:progressBackgroundTint=\"@color/white\"\n                android:progressTint=\"@color/red\"\n                android:thumb=\"@drawable/custom_thumb\"\n                tools:targetApi=\"lollipop\" />\n\n            <TextView\n                android:id=\"@+id/videoView_endtime\"\n                android:layout_width=\"wrap_content\"\n                android:layout_height=\"wrap_content\"\n                android:layout_weight=\"0\"\n                android:text=\"00:00:00\"\n                android:textColor=\"@color/white\"\n                android:textSize=\"17sp\" />\n\n        </LinearLayout>\n\n\n        <LinearLayout\n            android:id=\"@+id/videoView_four_two_child_layout\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:orientation=\"horizontal\"\n            android:padding=\"8dp\">\n\n            <LinearLayout\n                android:id=\"@+id/videoView_lock_screen\"\n                android:layout_width=\"wrap_content\"\n                android:layout_height=\"wrap_content\"\n                android:layout_gravity=\"center\"\n                android:layout_weight=\"1\"\n                android:focusable=\"true\"\n                android:background=\"@drawable/focus_search\"\n                android:gravity=\"center\"\n                android:orientation=\"horizontal\"\n                android:padding=\"10dp\"\n                >\n\n\n                <ImageView\n                    android:layout_width=\"20dp\"\n                    android:layout_height=\"20dp\"\n                    android:layout_marginEnd=\"8dp\"\n                    android:layout_marginRight=\"5dp\"\n                    android:background=\"@android:color/transparent\"\n                    android:src=\"@drawable/netflix_unlock\" />\n\n                <TextView\n                    android:layout_width=\"wrap_content\"\n                    android:layout_height=\"wrap_content\"\n                    android:layout_gravity=\"center\"\n                    android:background=\"@android:color/transparent\"\n                    android:text=\"Lock\"\n                    android:textColor=\"@color/white\"\n                    android:textSize=\"12sp\" />\n\n            </LinearLayout>\n\n\n            <LinearLayout\n                android:focusable=\"true\"\n                android:background=\"@drawable/focus_search\"\n                android:id=\"@+id/videoView_track\"\n                android:layout_width=\"wrap_content\"\n                android:layout_height=\"wrap_content\"\n                android:layout_gravity=\"center\"\n                android:layout_weight=\"1\"\n                android:gravity=\"center\"\n                android:orientation=\"horizontal\"\n                android:padding=\"10dp\"\n                >\n\n\n                <ImageView\n                    android:layout_width=\"20dp\"\n                    android:layout_height=\"20dp\"\n                    android:layout_marginEnd=\"8dp\"\n                    android:layout_marginRight=\"5dp\"\n                    android:background=\"@android:color/transparent\"\n                    android:src=\"@drawable/netflix_audio_subtitles\" />\n\n                <TextView\n                    android:layout_width=\"wrap_content\"\n                    android:layout_height=\"wrap_content\"\n                    android:layout_gravity=\"center\"\n                    android:background=\"@android:color/transparent\"\n                    android:text=\"Subtitle/Source\"\n                    android:textColor=\"@color/white\"\n                    android:textSize=\"12sp\" />\n\n            </LinearLayout>\n\n            <LinearLayout\n                android:focusable=\"true\"\n                android:background=\"@drawable/focus_search\"\n                android:id=\"@+id/videoView_screen_size\"\n                android:layout_width=\"wrap_content\"\n                android:layout_height=\"wrap_content\"\n                android:layout_gravity=\"center\"\n                android:layout_weight=\"1\"\n                android:gravity=\"center\"\n                android:orientation=\"horizontal\"\n                android:padding=\"10dp\"\n                >\n\n\n                <ImageView\n                    android:layout_width=\"20dp\"\n                    android:layout_height=\"20dp\"\n                    android:layout_marginEnd=\"8dp\"\n                    android:layout_marginRight=\"5dp\"\n                    android:id=\"@+id/screen_resize_img\"\n                    android:background=\"@android:color/transparent\"\n                    android:src=\"@drawable/baseline_zoom_out_map_24\" />\n\n                <TextView\n                    android:layout_width=\"wrap_content\"\n                    android:layout_height=\"wrap_content\"\n                    android:layout_gravity=\"center\"\n                    android:background=\"@android:color/transparent\"\n                    android:id=\"@+id/screen_resize_text\"\n                    android:text=\"Zoom\"\n                    android:textColor=\"@color/white\"\n                    android:textSize=\"12sp\" />\n\n            </LinearLayout>\n            <LinearLayout\n                android:focusable=\"true\"\n                android:background=\"@drawable/focus_search\"\n                android:id=\"@+id/videoView_resolution\"\n                android:layout_width=\"wrap_content\"\n                android:layout_height=\"wrap_content\"\n                android:layout_gravity=\"center\"\n                android:layout_weight=\"1\"\n                android:gravity=\"center\"\n                android:orientation=\"horizontal\"\n                android:padding=\"10dp\"\n                >\n\n\n                <ImageView\n                    android:layout_width=\"20dp\"\n                    android:layout_height=\"20dp\"\n                    android:layout_marginEnd=\"8dp\"\n                    android:layout_marginRight=\"5dp\"\n                    android:id=\"@+id/screen_quality_img\"\n                    android:background=\"@android:color/transparent\"\n                    android:src=\"@drawable/quality_24\" />\n\n                <TextView\n                    android:layout_width=\"wrap_content\"\n                    android:layout_height=\"wrap_content\"\n                    android:layout_gravity=\"center\"\n                    android:background=\"@android:color/transparent\"\n                    android:id=\"@+id/screen_quality_text\"\n                    android:text=\"Quality\"\n                    android:textColor=\"@color/white\"\n                    android:textSize=\"12sp\" />\n\n            </LinearLayout>\n\n            <LinearLayout\n                android:focusable=\"true\"\n                android:background=\"@drawable/focus_search\"\n                android:id=\"@+id/videoView_next_ep\"\n                android:layout_width=\"wrap_content\"\n                android:layout_height=\"wrap_content\"\n                android:visibility=\"gone\"\n                tools:visibility=\"visible\"\n                android:layout_gravity=\"center\"\n                android:layout_weight=\"1\"\n                android:gravity=\"center\"\n                android:orientation=\"horizontal\"\n                android:padding=\"10dp\"\n                >\n\n                <ImageView\n                    android:layout_width=\"20dp\"\n                    android:layout_height=\"20dp\"\n                    android:layout_marginEnd=\"8dp\"\n                    android:layout_marginRight=\"5dp\"\n                    android:id=\"@+id/next_ep_img\"\n                    android:background=\"@android:color/transparent\"\n                    android:src=\"@drawable/next_episode\" />\n\n                <TextView\n                    android:layout_width=\"wrap_content\"\n                    android:layout_height=\"wrap_content\"\n                    android:layout_gravity=\"center\"\n                    android:background=\"@android:color/transparent\"\n                    android:id=\"@+id/next_ep_text\"\n                    android:text=\"Next\"\n                    android:textColor=\"@color/white\"\n                    android:textSize=\"12sp\" />\n\n            </LinearLayout>\n\n            <LinearLayout\n                android:focusable=\"true\"\n                android:background=\"@drawable/focus_search\"\n                android:id=\"@+id/videoView_skip_op\"\n                android:layout_width=\"wrap_content\"\n                android:layout_height=\"wrap_content\"\n                android:visibility=\"gone\"\n                tools:visibility=\"visible\"\n                android:layout_gravity=\"center\"\n                android:layout_weight=\"1\"\n                android:gravity=\"center\"\n                android:orientation=\"horizontal\"\n                android:padding=\"10dp\"\n                >\n\n                <ImageView\n                    android:layout_width=\"20dp\"\n                    android:layout_height=\"20dp\"\n                    android:layout_marginEnd=\"8dp\"\n                    android:layout_marginRight=\"5dp\"\n                    android:id=\"@+id/skip_op_img\"\n                    android:background=\"@android:color/transparent\"\n                    android:src=\"@drawable/baseline_double_arrow_24\" />\n\n                <TextView\n                    android:layout_width=\"wrap_content\"\n                    android:layout_height=\"wrap_content\"\n                    android:layout_gravity=\"center\"\n                    android:background=\"@android:color/transparent\"\n                    android:id=\"@+id/skip_op_text\"\n                    android:text=\"Skip OP\"\n                    android:textColor=\"@color/white\"\n                    android:textSize=\"12sp\" />\n\n            </LinearLayout>\n\n\n        </LinearLayout>\n\n    </LinearLayout>\n\n    <LinearLayout\n        android:id=\"@+id/video_five_layout\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:gravity=\"center|bottom\"\n        android:orientation=\"vertical\"\n        android:padding=\"8dp\"\n        android:visibility=\"gone\"\n        app:layout_constraintBottom_toBottomOf=\"parent\">\n\n        <LinearLayout\n            android:id=\"@+id/video_five_child_layout\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:background=\"@drawable/white_round\"\n            android:gravity=\"center\"\n            android:orientation=\"horizontal\"\n            android:padding=\"14dp\">\n\n            <ImageView\n                android:layout_width=\"wrap_content\"\n                android:layout_height=\"wrap_content\"\n                android:layout_marginEnd=\"5dp\"\n                android:layout_marginRight=\"5dp\"\n                android:src=\"@drawable/netflix_lock_black\" />\n\n            <TextView\n                android:layout_width=\"wrap_content\"\n                android:layout_height=\"wrap_content\"\n\n                android:textColor=\"@color/black\"\n                android:textStyle=\"bold\" />\n\n\n        </LinearLayout>\n\n        <TextView\n            android:id=\"@+id/videoView_lock_text\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:layout_marginVertical=\"5dp\"\n\n            android:textColor=\"@color/white\"\n            android:textSize=\"13sp\"\n            android:textStyle=\"bold\" />\n\n        <TextView\n            android:id=\"@+id/videoView_lock_text_two\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n\n            android:textSize=\"10sp\" />\n\n    </LinearLayout>\n\n</androidx.constraintlayout.widget.ConstraintLayout>\n"
  },
  {
    "path": "app/src/main/res/layout/dropdown_menu.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:layout_width=\"wrap_content\"\n    android:layout_height=\"wrap_content\"\n    android:orientation=\"horizontal\"\n    >\n\n    <TextView\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:text=\"@string/season\"\n        android:fontFamily=\"@font/exo_2\"\n        android:textSize=\"20sp\"\n        android:layout_margin=\"10dp\"\n        />\n    <TextView\n        android:id=\"@+id/season_number\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:textSize=\"20sp\"\n        android:fontFamily=\"@font/exo_2\"\n        android:text=\"\"\n        />\n\n</LinearLayout>"
  },
  {
    "path": "app/src/main/res/layout/episode_expanded_view.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<FrameLayout\n    android:layout_height=\"wrap_content\"\n    android:layout_width=\"match_parent\"\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    >\n\n\n<androidx.cardview.widget.CardView\n    android:foreground=\"@drawable/gradient_fill\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"wrap_content\"\n    app:cardElevation=\"10dp\"\n    app:cardCornerRadius=\"15dp\"\n    android:layout_margin=\"10dp\"\n    >\n\n        <LinearLayout\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:id=\"@+id/episode_card_ll\"\n            android:orientation=\"vertical\">\n            <FrameLayout\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\"\n                android:id=\"@+id/expanded_episode_fl\"\n                >\n\n                <ImageView\n                    android:layout_width=\"match_parent\"\n                    android:layout_height=\"175dp\"\n                    android:id=\"@+id/episode_img\"\n                    android:scaleType=\"centerCrop\"\n                    android:importantForAccessibility=\"no\" />\n                <ImageView\n                    android:id=\"@+id/play_button_2\"\n                    android:layout_width=\"50dp\"\n                    android:layout_gravity=\"center\"\n                    android:layout_height=\"50dp\"\n                    android:layout_marginTop=\"6dp\"\n                    android:importantForAccessibility=\"no\"\n                    android:src=\"@drawable/baseline_play_circle_24\"\n                    />\n\n                <TextView\n                    android:layout_width=\"wrap_content\"\n                    android:id=\"@+id/episode_number\"\n                    android:layout_height=\"wrap_content\"\n                    tools:text=\"1\"\n                    android:fontFamily=\"@font/exo_2\"\n                    android:background=\"@drawable/gradient_fill_text\"\n                    android:layout_marginStart=\"10dp\"\n                    android:textStyle=\"bold\"\n                    android:textAppearance=\"@style/TextAppearance.AppCompat.Display1\"\n                    android:layout_gravity=\"bottom\"\n                    />\n\n\n            </FrameLayout>\n            <TextView\n                android:id=\"@+id/episode_no_text\"\n                android:layout_width=\"match_parent\"\n                android:fontFamily=\"@font/exo_2\"\n                android:layout_height=\"wrap_content\"\n                android:textStyle=\"bold\"\n                android:layout_marginStart=\"10dp\"\n                android:layout_gravity=\"top\"\n                tools:text=\"@string/episodes\"\n                android:textSize=\"20sp\"/>\n\n            <androidx.constraintlayout.widget.ConstraintLayout\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\"\n                >\n            <at.blogc.android.views.ExpandableTextView\n                android:id=\"@+id/episode_overview_text\"\n                android:layout_width=\"0dp\"\n                app:layout_constraintStart_toStartOf=\"parent\"\n                android:fontFamily=\"@font/exo_2\"\n                android:layout_height=\"wrap_content\"\n                app:layout_constraintEnd_toStartOf=\"@+id/expand_text\"\n                android:layout_margin=\"10dp\"\n                android:layout_gravity=\"bottom\"\n                app:layout_constraintTop_toTopOf=\"parent\"\n                app:layout_constraintBottom_toBottomOf=\"parent\"\n                android:maxLines=\"2\"\n                android:ellipsize=\"end\"\n                app:animation_duration=\"750\"/>\n            <ImageView\n                android:layout_width=\"24dp\"\n                android:layout_height=\"24dp\"\n                app:layout_constraintTop_toTopOf=\"parent\"\n                app:layout_constraintBottom_toBottomOf=\"parent\"\n                android:importantForAccessibility=\"no\"\n                android:id=\"@+id/expand_text\"\n                app:layout_constraintEnd_toEndOf=\"parent\"\n                android:src=\"@drawable/baseline_keyboard_arrow_down_24\"\n                />\n            </androidx.constraintlayout.widget.ConstraintLayout>\n\n        </LinearLayout>\n\n\n\n</androidx.cardview.widget.CardView>\n\n\n\n\n</FrameLayout>"
  },
  {
    "path": "app/src/main/res/layout/episode_item_viem.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"wrap_content\"\n\n    android:orientation=\"horizontal\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\">\n\n    <ImageView\n        android:id=\"@+id/play_button\"\n        android:layout_width=\"50dp\"\n        android:layout_height=\"50dp\"\n        android:layout_gravity=\"center_vertical\"\n        android:src=\"@drawable/baseline_play_circle_24\"\n        app:layout_constraintBottom_toBottomOf=\"@id/episode_no_text\"\n        app:layout_constraintStart_toStartOf=\"parent\"\n        app:layout_constraintTop_toTopOf=\"@id/episode_no_text\" />\n\n    <TextView\n        android:id=\"@+id/episode_no_text\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_margin=\"5dp\"\n        android:fontFamily=\"@font/exo_2\"\n        android:padding=\"10dp\"\n        android:textAppearance=\"@style/TextAppearance.AppCompat.Display1\"\n        app:layout_constraintBottom_toBottomOf=\"parent\"\n        app:layout_constraintStart_toEndOf=\"@id/play_button\"\n        app:layout_constraintTop_toTopOf=\"parent\"\n        tools:text=\"Episode 1\" />\n\n\n</LinearLayout>"
  },
  {
    "path": "app/src/main/res/layout/fragment_anime.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<androidx.constraintlayout.widget.ConstraintLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    tools:context=\".anime.AnimeFragment\">\n\n    <TextView\n        android:id=\"@+id/winter_text\"\n        android:layout_width=\"wrap_content\"\n        android:visibility=\"invisible\"\n        android:layout_height=\"wrap_content\"\n        android:layout_margin=\"5dp\"\n        android:fontFamily=\"@font/exo_2\"\n        android:text=\"Winter\"\n        android:textAppearance=\"@style/TextAppearance.AppCompat.Display1\"\n        app:layout_constraintTop_toTopOf=\"parent\"\n        app:layout_constraintStart_toStartOf=\"parent\"\n\n        />\n\n    <androidx.recyclerview.widget.RecyclerView\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:layout_margin=\"5dp\"\n        android:id=\"@+id/winter_anime_rc\"\n        app:layout_constraintTop_toBottomOf=\"@+id/winter_text\"\n        app:layout_constraintStart_toStartOf=\"parent\"\n        app:layout_constraintEnd_toEndOf=\"parent\"\n\n        />\n\n    <TextView\n        android:id=\"@+id/fall_text\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_margin=\"5dp\"\n        android:visibility=\"invisible\"\n        android:fontFamily=\"@font/exo_2\"\n        android:text=\"Fall\"\n        android:textAppearance=\"@style/TextAppearance.AppCompat.Display1\"\n        app:layout_constraintTop_toBottomOf=\"@id/winter_anime_rc\"\n        app:layout_constraintStart_toStartOf=\"parent\"\n\n        />\n\n    <androidx.recyclerview.widget.RecyclerView\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:layout_margin=\"10dp\"\n        android:id=\"@+id/fall_anime_rc\"\n        app:layout_constraintTop_toBottomOf=\"@+id/fall_text\"\n        app:layout_constraintStart_toStartOf=\"parent\"\n        app:layout_constraintEnd_toEndOf=\"parent\"\n\n        />\n\n    <TextView\n        android:id=\"@+id/spring_text\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_margin=\"5dp\"\n        android:fontFamily=\"@font/exo_2\"\n        android:text=\"Spring\"\n        android:visibility=\"invisible\"\n        android:textAppearance=\"@style/TextAppearance.AppCompat.Display1\"\n        app:layout_constraintTop_toBottomOf=\"@+id/fall_anime_rc\"\n        app:layout_constraintStart_toStartOf=\"parent\"\n\n        />\n\n    <androidx.recyclerview.widget.RecyclerView\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:layout_margin=\"5dp\"\n        android:id=\"@+id/spring_anime_rc\"\n        app:layout_constraintTop_toBottomOf=\"@id/spring_text\"\n        app:layout_constraintStart_toStartOf=\"parent\"\n        app:layout_constraintEnd_toEndOf=\"parent\"\n\n        />\n\n    <TextView\n        android:id=\"@+id/summer_text\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_margin=\"5dp\"\n        android:fontFamily=\"@font/exo_2\"\n        android:text=\"Summer\"\n        android:visibility=\"invisible\"\n        android:textAppearance=\"@style/TextAppearance.AppCompat.Display1\"\n        app:layout_constraintTop_toBottomOf=\"@+id/spring_anime_rc\"\n        app:layout_constraintStart_toStartOf=\"parent\"\n\n        />\n\n    <androidx.recyclerview.widget.RecyclerView\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:layout_margin=\"5dp\"\n        android:id=\"@+id/summer_anime_rc\"\n        app:layout_constraintTop_toBottomOf=\"@id/summer_text\"\n        app:layout_constraintStart_toStartOf=\"parent\"\n        app:layout_constraintEnd_toEndOf=\"parent\"\n\n        />\n    <ProgressBar\n        android:layout_width=\"0dp\"\n        android:layout_height=\"wrap_content\"\n        app:layout_constraintTop_toTopOf=\"parent\"\n        app:layout_constraintBottom_toBottomOf=\"parent\"\n        app:layout_constraintStart_toStartOf=\"parent\"\n        app:layout_constraintEnd_toEndOf=\"parent\"\n        android:id=\"@+id/loading_anime\"\n        />\n\n\n\n</androidx.constraintlayout.widget.ConstraintLayout>"
  },
  {
    "path": "app/src/main/res/layout/fragment_anime_details.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<androidx.constraintlayout.widget.ConstraintLayout\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    android:transitionName=\"@string/expandtvshow\"\n    android:id=\"@+id/expand_tvshow_view\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"wrap_content\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    tools:context=\".TVShowDetails\">\n    <LinearLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:id=\"@+id/progress_layout\"\n        app:layout_constraintTop_toTopOf=\"parent\"\n        app:layout_constraintBottom_toBottomOf=\"parent\"\n        >\n        <ProgressBar\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"match_parent\"\n            android:layout_gravity=\"center\"\n            android:id=\"@+id/progress_circular\"\n            />\n\n    </LinearLayout>\n\n\n    <FrameLayout\n        android:layout_width=\"match_parent\"\n        android:id=\"@+id/show_images\"\n        android:layout_height=\"wrap_content\"\n        app:layout_constraintTop_toTopOf=\"parent\"\n        app:layout_constraintEnd_toEndOf=\"parent\"\n        app:layout_constraintStart_toStartOf=\"parent\"\n\n        >\n        <com.google.android.material.imageview.ShapeableImageView\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"360dp\"\n            android:id=\"@+id/show_backdrop\"\n            app:shapeAppearance=\"@style/roundedImageView\"\n            android:foreground=\"@drawable/gradient_fill_bottom\"\n            android:scaleType=\"centerCrop\"\n            />\n        <androidx.cardview.widget.CardView\n\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            app:cardElevation=\"10dp\"\n            app:cardCornerRadius=\"15dp\"\n            android:layout_margin=\"10dp\"\n            android:layout_gravity=\"bottom\"\n            >\n\n        </androidx.cardview.widget.CardView>\n        <com.google.android.material.imageview.ShapeableImageView\n            android:layout_width=\"170dp\"\n            android:importantForAccessibility=\"no\"\n            android:id=\"@+id/show_poster\"\n            android:visibility=\"gone\"\n            android:layout_height=\"250dp\"\n            android:layout_marginStart=\"10dp\"\n            android:outlineAmbientShadowColor=\"@color/black\"\n            android:layout_marginBottom=\"20dp\"\n            app:shapeAppearance=\"@style/roundedImageView\"\n            android:layout_gravity=\"bottom\"\n            android:scaleType=\"center\"\n            tools:src=\"@drawable/icon_tvshow\"\n            />\n\n    </FrameLayout>\n\n    <TextView\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:id=\"@+id/title_show\"\n        android:fontFamily=\"@font/exo_2\"\n        android:textAppearance=\"@style/TextAppearance.AppCompat.Display1\"\n        app:layout_constraintTop_toBottomOf=\"@+id/show_images\"\n        app:layout_constraintStart_toStartOf=\"parent\"\n        app:layout_constraintEnd_toEndOf=\"parent\"\n        android:layout_margin=\"10dp\"/>\n\n    <androidx.constraintlayout.widget.ConstraintLayout\n        android:layout_width=\"match_parent\"\n        android:id=\"@+id/overview\"\n        app:layout_constraintTop_toBottomOf=\"@id/title_show\"\n        app:layout_constraintStart_toStartOf=\"parent\"\n        app:layout_constraintEnd_toEndOf=\"parent\"\n        android:layout_margin=\"25dp\"\n        android:layout_height=\"wrap_content\"\n        >\n        <at.blogc.android.views.ExpandableTextView\n            android:id=\"@+id/overview_text\"\n            android:layout_width=\"0dp\"\n            app:layout_constraintStart_toStartOf=\"parent\"\n            android:fontFamily=\"@font/exo_2\"\n            android:layout_height=\"wrap_content\"\n            app:layout_constraintEnd_toStartOf=\"@+id/expand_text\"\n            android:layout_margin=\"10dp\"\n            android:layout_gravity=\"bottom\"\n            app:layout_constraintTop_toTopOf=\"parent\"\n            app:layout_constraintBottom_toBottomOf=\"parent\"\n            android:maxLines=\"5\"\n            android:ellipsize=\"end\"\n            app:animation_duration=\"750\"/>\n        <ImageView\n            android:layout_width=\"24dp\"\n            android:layout_height=\"24dp\"\n            app:layout_constraintTop_toTopOf=\"parent\"\n            app:layout_constraintBottom_toBottomOf=\"parent\"\n            android:importantForAccessibility=\"no\"\n            android:id=\"@+id/expand_text\"\n            app:layout_constraintEnd_toEndOf=\"parent\"\n            android:src=\"@drawable/baseline_keyboard_arrow_down_24\"\n            />\n    </androidx.constraintlayout.widget.ConstraintLayout>\n\n    <Button\n        android:layout_width=\"match_parent\"\n        android:layout_marginTop=\"10dp\"\n        android:layout_height=\"wrap_content\"\n        app:layout_constraintTop_toBottomOf=\"@id/overview\"\n        app:layout_constraintStart_toStartOf=\"parent\"\n        app:layout_constraintEnd_toEndOf=\"parent\"\n        android:layout_marginStart=\"10dp\"\n        android:layout_marginEnd=\"10dp\"\n        android:id=\"@+id/continue_button\"\n        android:visibility=\"gone\"\n        tools:visibility=\"visible\"\n        android:text=\"Continue Watching\"\n        />\n\n    <LinearLayout\n        android:layout_width=\"match_parent\"\n        android:id=\"@+id/prequel_sequel_ll\"\n        app:layout_constraintTop_toBottomOf=\"@id/continue_button\"\n        app:layout_constraintStart_toStartOf=\"parent\"\n        android:orientation=\"horizontal\"\n        app:layout_constraintEnd_toEndOf=\"parent\"\n        android:layout_height=\"wrap_content\">\n\n        <Button\n            android:layout_width=\"0dp\"\n            android:id=\"@+id/prequel_btn\"\n            android:layout_margin=\"10dp\"\n            android:layout_height=\"wrap_content\"\n            android:text=\"Prequel\"\n            android:visibility=\"gone\"\n            android:layout_weight=\"1\"\n            />\n\n        <Button\n            android:layout_width=\"0dp\"\n            android:layout_margin=\"10dp\"\n            android:visibility=\"gone\"\n            android:text=\"Sequel\"\n            android:id=\"@+id/sequel_btn\"\n            android:layout_height=\"wrap_content\"\n            android:layout_weight=\"1\"\n            />\n\n    </LinearLayout>\n\n    <TextView\n        android:id=\"@+id/episodes_text\"\n        android:layout_marginTop=\"10dp\"\n        android:visibility=\"invisible\"\n        tools:visibility=\"visible\"\n        android:layout_width=\"match_parent\"\n        android:fontFamily=\"@font/exo_2\"\n        android:layout_marginStart=\"25dp\"\n        android:layout_marginBottom=\"10dp\"\n        android:layout_height=\"wrap_content\"\n        android:textSize=\"20sp\"\n        app:layout_constraintEnd_toEndOf=\"parent\"\n        app:layout_constraintStart_toStartOf=\"parent\"\n        app:layout_constraintTop_toBottomOf=\"@id/prequel_sequel_ll\"\n        android:text=\"@string/episodes\" />\n\n    <androidx.recyclerview.widget.RecyclerView\n        android:layout_marginTop=\"25dp\"\n        android:layout_width=\"match_parent\"\n        android:layout_marginStart=\"10dp\"\n        android:layout_marginEnd=\"10dp\"\n        android:layout_height=\"wrap_content\"\n        app:layout_constraintTop_toBottomOf=\"@id/episodes_text\"\n        app:layout_constraintStart_toStartOf=\"parent\"\n        app:layout_constraintEnd_toEndOf=\"parent\"\n        android:id=\"@+id/episode_display_rc\"\n        />\n\n\n\n</androidx.constraintlayout.widget.ConstraintLayout>"
  },
  {
    "path": "app/src/main/res/layout/fragment_correct_title_selection.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<FrameLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    tools:context=\".extractors.CorrectTitleSelection\">\n\n\n\n</FrameLayout>"
  },
  {
    "path": "app/src/main/res/layout/fragment_movies.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<androidx.constraintlayout.widget.ConstraintLayout\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    tools:context=\".MoviesFragment\"\n    >\n\n\n\n    <TextView\n        android:id=\"@+id/trending_text\"\n        android:layout_width=\"wrap_content\"\n        android:visibility=\"invisible\"\n        android:fontFamily=\"@font/exo_2\"\n        android:layout_height=\"wrap_content\"\n        android:layout_margin=\"5dp\"\n        android:text=\"@string/trending\"\n        android:textAppearance=\"@style/TextAppearance.AppCompat.Display1\"\n        app:layout_constraintTop_toTopOf=\"parent\"\n        app:layout_constraintStart_toStartOf=\"parent\"\n\n        />\n\n    <androidx.recyclerview.widget.RecyclerView\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:layout_margin=\"5dp\"\n        android:id=\"@+id/trending_movie_rc\"\n        app:layout_constraintTop_toBottomOf=\"@+id/trending_text\"\n        app:layout_constraintStart_toStartOf=\"parent\"\n        app:layout_constraintEnd_toEndOf=\"parent\"\n\n        />\n\n\n\n    <TextView\n        android:id=\"@+id/movies_text\"\n        android:layout_width=\"wrap_content\"\n        android:visibility=\"invisible\"\n        android:layout_height=\"wrap_content\"\n        android:text=\"@string/popular\"\n        android:layout_margin=\"5dp\"\n        android:fontFamily=\"@font/exo_2\"\n        app:layout_constraintTop_toBottomOf=\"@+id/trending_movie_rc\"\n        app:layout_constraintStart_toStartOf=\"parent\"\n        android:textAppearance=\"@style/TextAppearance.AppCompat.Display1\" />\n\n        <androidx.recyclerview.widget.RecyclerView\n            android:id=\"@+id/movie_recycler_view\"\n            android:layout_width=\"0dp\"\n            android:layout_margin=\"10dp\"\n            android:layout_height=\"wrap_content\"\n\n            app:layout_constraintEnd_toEndOf=\"parent\"\n            app:layout_constraintStart_toStartOf=\"parent\"\n            app:layout_constraintTop_toBottomOf=\"@+id/movies_text\"\n        />\n\n\n\n\n    <TextView\n        android:id=\"@+id/topmovies_text\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:text=\"@string/top_rated\"\n        android:visibility=\"invisible\"\n        android:layout_margin=\"5dp\"\n        android:fontFamily=\"@font/exo_2\"\n        app:layout_constraintTop_toBottomOf=\"@+id/movie_recycler_view\"\n        app:layout_constraintStart_toStartOf=\"parent\"\n        android:textAppearance=\"@style/TextAppearance.AppCompat.Display1\" />\n\n    <androidx.recyclerview.widget.RecyclerView\n        android:id=\"@+id/topRatedMovie_recycler_view\"\n        android:layout_width=\"0dp\"\n        android:layout_margin=\"10dp\"\n        android:layout_height=\"wrap_content\"\n\n        app:layout_constraintEnd_toEndOf=\"parent\"\n        app:layout_constraintStart_toStartOf=\"parent\"\n        app:layout_constraintTop_toBottomOf=\"@+id/topmovies_text\"\n        />\n\n    <ProgressBar\n        android:layout_width=\"0dp\"\n        android:layout_height=\"wrap_content\"\n        app:layout_constraintTop_toTopOf=\"parent\"\n        app:layout_constraintBottom_toBottomOf=\"parent\"\n        app:layout_constraintStart_toStartOf=\"parent\"\n        app:layout_constraintEnd_toEndOf=\"parent\"\n        android:id=\"@+id/loading_movies\"\n        />\n\n\n</androidx.constraintlayout.widget.ConstraintLayout>\n\n"
  },
  {
    "path": "app/src/main/res/layout/fragment_search.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    tools:context=\".SearchFragment\"\n    android:orientation=\"vertical\"\n    >\n\n    <RadioGroup\n        android:id=\"@+id/choice\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:layout_margin=\"10dp\"\n        android:background=\"@drawable/radio_group_tab_bg\"\n        android:orientation=\"horizontal\"\n        >\n\n        <RadioButton\n            android:id=\"@+id/movies_search\"\n            android:layout_width=\"0dp\"\n            android:layout_height=\"35dp\"\n            android:layout_weight=\"0.5\"\n            android:background=\"@drawable/tab_selector\"\n            android:button=\"@null\"\n            android:checked=\"true\"\n            android:fontFamily=\"@font/exo_2\"\n            android:text=\"@string/movies\"\n            android:gravity=\"center\"\n            android:textColor=\"@drawable/tab_text_color_selector\"\n            android:textSize=\"16sp\"\n            android:textStyle=\"bold\"\n            />\n\n        <RadioButton\n            android:id=\"@+id/tvShows_search\"\n            android:layout_width=\"0dp\"\n            android:layout_height=\"35dp\"\n            android:layout_weight=\"0.5\"\n            android:background=\"@drawable/tab_selector\"\n            android:button=\"@null\"\n            android:checked=\"false\"\n            android:fontFamily=\"@font/exo_2\"\n            android:text=\"@string/tv_show\"\n            android:gravity=\"center\"\n            android:textColor=\"@drawable/tab_text_color_selector\"\n            android:textSize=\"16sp\"\n            android:textStyle=\"bold\"\n            />\n\n        <RadioButton\n            android:id=\"@+id/anime_search\"\n            android:layout_width=\"0dp\"\n            android:layout_height=\"35dp\"\n            android:layout_weight=\"0.5\"\n            android:background=\"@drawable/tab_selector\"\n            android:button=\"@null\"\n            android:checked=\"false\"\n            android:fontFamily=\"@font/exo_2\"\n            android:text=\"@string/anime\"\n            android:gravity=\"center\"\n            android:textColor=\"@drawable/tab_text_color_selector\"\n            android:textSize=\"16sp\"\n            android:textStyle=\"bold\"\n            />\n\n    </RadioGroup>\n\n    <SearchView\n        android:layout_width=\"match_parent\"\n        android:focusable=\"true\"\n        android:focusableInTouchMode=\"true\"\n        android:id=\"@+id/searchView\"\n        android:padding=\"10dp\"\n        android:layout_height=\"50dp\"\n        android:layout_marginTop=\"10dp\"\n        android:layout_marginStart=\"10dp\"\n        android:iconifiedByDefault=\"false\"\n        android:layout_marginEnd=\"10dp\"\n        android:background=\"@drawable/rectangle_box_slim\"\n        />\n    <com.google.android.material.textfield.TextInputLayout\n        android:layout_width=\"match_parent\"\n        android:paddingTop=\"10dp\"\n        android:paddingStart=\"10dp\"\n        android:paddingEnd=\"10dp\"\n        android:visibility=\"gone\"\n        android:id=\"@+id/search_til\"\n        android:layout_height=\"wrap_content\">\n\n        <androidx.appcompat.widget.AppCompatEditText\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:id=\"@+id/search_et\"\n            android:fontFamily=\"@font/exo_2\"\n            android:imeOptions=\"actionSearch\"\n            android:inputType=\"text\"\n            android:hint=\"@string/search\"\n            />\n\n    </com.google.android.material.textfield.TextInputLayout>\n    <FrameLayout\n        android:layout_width=\"match_parent\"\n\n        android:layout_height=\"match_parent\">\n\n\n        <androidx.recyclerview.widget.RecyclerView\n            android:id=\"@+id/search_results_rc\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:layout_margin=\"10dp\"\n            />\n        <LinearLayout\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"match_parent\"\n            android:background=\"@color/black\"\n            android:id=\"@+id/search_history_ll\"\n            android:orientation=\"vertical\"\n            >\n\n            <androidx.recyclerview.widget.RecyclerView\n                android:layout_width=\"match_parent\"\n                android:visibility=\"gone\"\n                tools:visibility=\"visible\"\n                android:id=\"@+id/search_history_rc\"\n                android:layout_weight=\"1\"\n                android:layout_height=\"wrap_content\"\n                android:paddingBottom= \"30dp\"\n                android:paddingStart=\"10dp\"\n                android:paddingEnd=\"10dp\"\n                android:paddingTop=\"10dp\"\n                android:background=\"@drawable/background_search_history\"\n                android:layout_marginStart=\"10dp\"\n                android:layout_marginEnd=\"10dp\"\n\n                />\n            <TextView\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"40dp\"\n                android:id=\"@+id/delete_all_button\"\n                android:fontFamily=\"@font/exo_2\"\n                android:text=\"@string/clear_all\"\n                android:layout_marginStart=\"15dp\"\n                android:layout_marginEnd=\"15dp\"\n                android:background=\"@drawable/background_search_history\"\n                android:textColor=\"@color/white\"\n                android:layout_marginBottom=\"8dp\"\n                android:gravity=\"center\"\n                android:textSize=\"18sp\"\n                android:layout_gravity=\"bottom\"\n                />\n        </LinearLayout>\n\n\n    </FrameLayout>\n\n    <ProgressBar\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:visibility=\"gone\"\n        android:id=\"@+id/search_loading\"\n\n        />\n\n\n</LinearLayout>"
  },
  {
    "path": "app/src/main/res/layout/fragment_tv_show.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<androidx.constraintlayout.widget.ConstraintLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    tools:context=\".TVShowFragment\">\n\n    <!-- TODO: Update blank fragment layout -->\n    <TextView\n        android:id=\"@+id/popular_text\"\n        android:layout_width=\"wrap_content\"\n        android:visibility=\"invisible\"\n        android:layout_height=\"wrap_content\"\n        android:layout_margin=\"5dp\"\n        android:fontFamily=\"@font/exo_2\"\n        android:text=\"@string/popular\"\n        android:textAppearance=\"@style/TextAppearance.AppCompat.Display1\"\n        app:layout_constraintTop_toTopOf=\"parent\"\n        app:layout_constraintStart_toStartOf=\"parent\"\n\n        />\n\n    <androidx.recyclerview.widget.RecyclerView\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:layout_margin=\"5dp\"\n        android:id=\"@+id/popular_tvshow_rc\"\n        app:layout_constraintTop_toBottomOf=\"@+id/popular_text\"\n        app:layout_constraintStart_toStartOf=\"parent\"\n        app:layout_constraintEnd_toEndOf=\"parent\"\n\n        />\n\n    <TextView\n        android:id=\"@+id/trending_text\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_margin=\"5dp\"\n        android:visibility=\"invisible\"\n        android:fontFamily=\"@font/exo_2\"\n        android:text=\"@string/trending\"\n        android:textAppearance=\"@style/TextAppearance.AppCompat.Display1\"\n        app:layout_constraintTop_toBottomOf=\"@id/popular_tvshow_rc\"\n        app:layout_constraintStart_toStartOf=\"parent\"\n\n        />\n\n    <androidx.recyclerview.widget.RecyclerView\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:layout_margin=\"10dp\"\n        android:id=\"@+id/trending_tvshow_rc\"\n        app:layout_constraintTop_toBottomOf=\"@+id/trending_text\"\n        app:layout_constraintStart_toStartOf=\"parent\"\n        app:layout_constraintEnd_toEndOf=\"parent\"\n\n        />\n\n    <TextView\n        android:id=\"@+id/topShows_text\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_margin=\"5dp\"\n        android:fontFamily=\"@font/exo_2\"\n        android:text=\"@string/top_rated\"\n        android:visibility=\"invisible\"\n        android:textAppearance=\"@style/TextAppearance.AppCompat.Display1\"\n        app:layout_constraintTop_toBottomOf=\"@+id/trending_tvshow_rc\"\n        app:layout_constraintStart_toStartOf=\"parent\"\n\n        />\n\n    <androidx.recyclerview.widget.RecyclerView\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:layout_margin=\"5dp\"\n        android:id=\"@+id/toprated_tvshow_rc\"\n        app:layout_constraintTop_toBottomOf=\"@id/topShows_text\"\n        app:layout_constraintStart_toStartOf=\"parent\"\n        app:layout_constraintEnd_toEndOf=\"parent\"\n\n        />\n    <ProgressBar\n        android:layout_width=\"0dp\"\n        android:layout_height=\"wrap_content\"\n        app:layout_constraintTop_toTopOf=\"parent\"\n        app:layout_constraintBottom_toBottomOf=\"parent\"\n        app:layout_constraintStart_toStartOf=\"parent\"\n        app:layout_constraintEnd_toEndOf=\"parent\"\n        android:id=\"@+id/loading_tvshow\"\n        />\n\n\n\n</androidx.constraintlayout.widget.ConstraintLayout>"
  },
  {
    "path": "app/src/main/res/layout/fragment_tv_show_details.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<androidx.constraintlayout.widget.ConstraintLayout\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    android:transitionName=\"@string/expandtvshow\"\n    android:id=\"@+id/expand_tvshow_view\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"wrap_content\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    tools:context=\".TVShowDetails\">\n    <LinearLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:id=\"@+id/progress_layout\"\n        app:layout_constraintTop_toTopOf=\"parent\"\n        app:layout_constraintBottom_toBottomOf=\"parent\"\n        >\n        <ProgressBar\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"match_parent\"\n            android:layout_gravity=\"center\"\n            android:id=\"@+id/progress_circular\"\n            />\n\n    </LinearLayout>\n\n\n    <FrameLayout\n        android:layout_width=\"match_parent\"\n        android:id=\"@+id/show_images\"\n        android:layout_height=\"wrap_content\"\n        app:layout_constraintTop_toTopOf=\"parent\"\n        app:layout_constraintEnd_toEndOf=\"parent\"\n        app:layout_constraintStart_toStartOf=\"parent\"\n\n    >\n    <com.google.android.material.imageview.ShapeableImageView\n     android:layout_width=\"match_parent\"\n     android:layout_height=\"360dp\"\n     android:id=\"@+id/show_backdrop\"\n        app:shapeAppearance=\"@style/roundedImageView\"\n        android:foreground=\"@drawable/gradient_fill_bottom\"\n     android:scaleType=\"centerCrop\"\n        />\n        <androidx.cardview.widget.CardView\n\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            app:cardElevation=\"10dp\"\n            app:cardCornerRadius=\"15dp\"\n            android:layout_margin=\"10dp\"\n            android:layout_gravity=\"bottom\"\n            >\n\n        </androidx.cardview.widget.CardView>\n        <com.google.android.material.imageview.ShapeableImageView\n            android:layout_width=\"170dp\"\n            android:importantForAccessibility=\"no\"\n            android:id=\"@+id/show_poster\"\n            android:visibility=\"gone\"\n            android:layout_height=\"250dp\"\n            android:layout_marginStart=\"10dp\"\n            android:outlineAmbientShadowColor=\"@color/black\"\n            android:layout_marginBottom=\"20dp\"\n            app:shapeAppearance=\"@style/roundedImageView\"\n            android:layout_gravity=\"bottom\"\n            android:scaleType=\"center\"\n            tools:src=\"@drawable/icon_tvshow\"\n            />\n\n    </FrameLayout>\n\n    <TextView\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:id=\"@+id/title_show\"\n        android:fontFamily=\"@font/exo_2\"\n        android:textAppearance=\"@style/TextAppearance.AppCompat.Display1\"\n        app:layout_constraintTop_toBottomOf=\"@+id/show_images\"\n        app:layout_constraintStart_toStartOf=\"parent\"\n        app:layout_constraintEnd_toEndOf=\"parent\"\n        android:layout_margin=\"10dp\"/>\n\n    <TextView\n        android:id=\"@+id/overview\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:layout_margin=\"25dp\"\n        android:fontFamily=\"@font/exo_2\"\n        android:textAppearance=\"@style/TextAppearance.AppCompat.Medium\"\n        app:layout_constraintEnd_toEndOf=\"parent\"\n        app:layout_constraintStart_toStartOf=\"parent\"\n        app:layout_constraintTop_toBottomOf=\"@id/title_show\"\n        tools:text=\"System Hang\" />\n\n    <Button\n        android:layout_width=\"match_parent\"\n        android:layout_marginTop=\"10dp\"\n        android:layout_height=\"wrap_content\"\n        app:layout_constraintTop_toBottomOf=\"@id/overview\"\n        app:layout_constraintStart_toStartOf=\"parent\"\n        app:layout_constraintEnd_toEndOf=\"parent\"\n        android:id=\"@+id/continue_button\"\n        android:visibility=\"gone\"\n        tools:visibility=\"visible\"\n        android:text=\"Continue Watching\"\n        />\n\n<!--    <com.google.android.material.textfield.TextInputLayout-->\n<!--        android:id=\"@+id/dropdown_menu\"-->\n<!--        style=\"@style/Widget.MaterialComponents.TextInputLayout.FilledBox.ExposedDropdownMenu\"-->\n<!--        android:layout_width=\"180dp\"-->\n<!--        android:layout_margin=\"5dp\"-->\n<!--        app:layout_constraintTop_toBottomOf=\"@+id/overview\"-->\n<!--        android:layout_height=\"wrap_content\"-->\n<!--        android:hint=\"@string/season\"-->\n<!--        app:layout_constraintStart_toStartOf=\"parent\"-->\n\n<!--        >-->\n\n<!--        <AutoCompleteTextView-->\n<!--            android:id=\"@+id/autoCompleteTextView\"-->\n<!--            android:layout_width=\"match_parent\"-->\n<!--            android:layout_height=\"wrap_content\"-->\n<!--            android:layout_margin=\"20dp\"-->\n<!--            android:inputType=\"none\"-->\n<!--            tools:ignore=\"LabelFor\" />-->\n\n<!--    </com.google.android.material.textfield.TextInputLayout>-->\n    <Spinner\n        android:layout_width=\"wrap_content\"\n        android:id=\"@+id/dropdown_spinner\"\n        android:layout_height=\"wrap_content\"\n        app:layout_constraintTop_toBottomOf=\"@id/continue_button\"\n        app:layout_constraintStart_toStartOf=\"parent\"\n        android:layout_marginStart=\"25dp\"\n        android:layout_marginTop=\"10dp\"\n        />\n\n    <TextView\n        android:id=\"@+id/episodes_text\"\n        android:layout_marginTop=\"10dp\"\n        android:visibility=\"invisible\"\n        tools:visibility=\"visible\"\n        android:layout_width=\"match_parent\"\n        android:fontFamily=\"@font/exo_2\"\n        android:layout_marginStart=\"25dp\"\n        android:layout_marginBottom=\"10dp\"\n        android:layout_height=\"wrap_content\"\n        android:textSize=\"20sp\"\n        app:layout_constraintEnd_toEndOf=\"parent\"\n        app:layout_constraintStart_toStartOf=\"parent\"\n        app:layout_constraintTop_toBottomOf=\"@id/dropdown_spinner\"\n        android:text=\"@string/episodes\" />\n\n    <androidx.recyclerview.widget.RecyclerView\n        android:layout_marginTop=\"25dp\"\n        android:layout_width=\"match_parent\"\n        android:layout_marginStart=\"10dp\"\n        android:layout_marginEnd=\"10dp\"\n        android:layout_height=\"wrap_content\"\n        app:layout_constraintTop_toBottomOf=\"@id/episodes_text\"\n        app:layout_constraintStart_toStartOf=\"parent\"\n        app:layout_constraintEnd_toEndOf=\"parent\"\n        android:id=\"@+id/episode_display_rc\"\n        />\n\n\n\n</androidx.constraintlayout.widget.ConstraintLayout>"
  },
  {
    "path": "app/src/main/res/layout/item_view.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<FrameLayout\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    android:layout_width=\"160dp\"\n    android:background=\"@drawable/focus\"\n    android:layout_height=\"wrap_content\">\n<LinearLayout\n    android:layout_width=\"160dp\"\n    android:id=\"@+id/item_view_parent\"\n    android:layout_height=\"wrap_content\"\n    android:orientation=\"vertical\"\n    android:padding=\"5dp\"\n    >\n\n    <com.google.android.material.imageview.ShapeableImageView\n        android:id=\"@+id/image_view\"\n        android:layout_width=\"150dp\"\n        android:layout_height=\"225dp\"\n        android:scaleType=\"centerCrop\"\n        app:layout_constraintEnd_toEndOf=\"parent\"\n        app:layout_constraintStart_toStartOf=\"parent\"\n        app:layout_constraintTop_toTopOf=\"parent\"\n        app:shapeAppearance=\"@style/roundedImageView\"\n        />\n\n    <com.google.android.material.progressindicator.LinearProgressIndicator\n        android:id=\"@+id/item_progress\"\n        android:outlineSpotShadowColor=\"@color/black\"\n        android:layout_width=\"match_parent\"\n        app:trackCornerRadius=\"16dp\"\n        android:background=\"@drawable/gradient_fill_text\"\n        android:visibility=\"gone\"\n        tools:visibility=\"visible\"\n        android:layout_height=\"wrap_content\"/>\n\n    <TextView\n        app:flow_wrapMode=\"aligned\"\n        android:id=\"@+id/title_text_view\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:textSize=\"16sp\"\n        android:textStyle=\"bold\"\n        android:fontFamily=\"@font/exo_2\"\n        app:layout_constraintBottom_toBottomOf=\"parent\"\n        app:layout_constraintEnd_toEndOf=\"@+id/image_view\"\n        app:layout_constraintStart_toStartOf=\"@+id/image_view\"\n        app:layout_constraintTop_toBottomOf=\"@+id/image_view\" />\n\n\n\n</LinearLayout>\n    <TextView\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:id=\"@+id/tv_show_detail_tv\"\n        android:visibility=\"gone\"\n        tools:visibility=\"visible\"\n        android:fontFamily=\"@font/exo_2\"\n        android:text=\"Dub\"\n        android:textColor=\"@color/white\"\n        android:layout_gravity=\"end\"\n        android:layout_margin=\"5dp\"\n        android:background=\"@drawable/background_text\"\n        />\n    <View\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"230dp\"\n        android:id=\"@+id/blur_background\"\n        android:visibility=\"gone\"\n        android:background=\"@drawable/background_text\"\n        />\n    <ImageView\n        android:layout_width=\"50dp\"\n        android:layout_height=\"40dp\"\n        tools:visibility=\"visible\"\n        android:id=\"@+id/remove_continue\"\n        android:visibility=\"gone\"\n        android:layout_marginBottom=\"15dp\"\n        android:layout_gravity=\"center\"\n        android:src=\"@drawable/baseline_cancel_24\"\n        android:importantForAccessibility=\"no\" />\n</FrameLayout>"
  },
  {
    "path": "app/src/main/res/layout/search_item.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"wrap_content\"\n    android:orientation=\"horizontal\"\n    android:backgroundTint=\"@drawable/focus_search\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\">\n\n    <ImageView\n        android:id=\"@+id/history_icon\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_marginTop=\"6dp\"\n        android:src=\"@drawable/baseline_history_24\"\n        app:layout_constraintBottom_toBottomOf=\"@id/search_text\"\n        app:layout_constraintStart_toStartOf=\"parent\"\n        app:layout_constraintTop_toTopOf=\"@id/search_text\"\n        android:importantForAccessibility=\"no\" />\n\n    <TextView\n        android:id=\"@+id/search_text\"\n        android:layout_width=\"0dp\"\n        android:layout_height=\"wrap_content\"\n        android:layout_weight=\"1\"\n        android:layout_margin=\"5dp\"\n        android:textSize=\"20sp\"\n        android:fontFamily=\"@font/exo_2\"\n        app:layout_constraintBottom_toBottomOf=\"parent\"\n        app:layout_constraintStart_toEndOf=\"@id/history_icon\"\n        app:layout_constraintTop_toTopOf=\"parent\"\n        tools:text=\"Search Text\" />\n\n    <ImageView\n        android:layout_width=\"wrap_content\"\n        android:id=\"@+id/delete_record\"\n        android:layout_height=\"wrap_content\"\n        android:importantForAccessibility=\"no\"\n        android:src=\"@drawable/baseline_cancel_24\"\n        android:layout_margin=\"5dp\"\n        />\n</LinearLayout>"
  },
  {
    "path": "app/src/main/res/layout/sub_view.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:layout_width=\"match_parent\"\n    android:clickable=\"true\"\n    android:focusable=\"true\"\n    android:background=\"@drawable/focus_search\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    tools:background=\"@color/black\"\n    android:layout_height=\"wrap_content\">\n\n    <CheckedTextView\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:textColor=\"@color/white\"\n        android:id=\"@+id/sub_text_view\"\n        android:textAppearance=\"@style/TextAppearance.AppCompat.Medium\"\n        android:checkMark=\"?android:attr/listChoiceIndicatorSingle\"\n        android:padding=\"5dp\"\n        android:text=\"Subtitle 1\"\n        />\n\n\n</LinearLayout>"
  },
  {
    "path": "app/src/main/res/layout/test.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<androidx.constraintlayout.widget.ConstraintLayout\n    android:layout_height=\"wrap_content\"\n    android:layout_width=\"360dp\"\n    android:layout_gravity=\"center_horizontal\"\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    >\n\n\n    <androidx.cardview.widget.CardView\n        android:layout_width=\"0dp\"\n        android:focusable=\"true\"\n        android:foreground=\"@drawable/focus\"\n        android:layout_height=\"wrap_content\"\n        android:layout_marginTop=\"10dp\"\n        android:layout_marginEnd=\"5dp\"\n        app:cardCornerRadius=\"15dp\"\n        android:id=\"@+id/episode_card\"\n        app:cardElevation=\"10dp\"\n        app:layout_constraintEnd_toEndOf=\"parent\"\n        app:layout_constraintStart_toEndOf=\"@+id/episode_number\"\n        app:layout_constraintTop_toTopOf=\"parent\">\n\n        <LinearLayout\n            android:id=\"@+id/episode_card_ll\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:orientation=\"vertical\">\n\n            <FrameLayout\n                android:id=\"@+id/expanded_episode_fl\"\n                android:clickable=\"true\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\">\n\n                <ImageView\n                    android:id=\"@+id/episode_img\"\n                    android:layout_width=\"match_parent\"\n                    android:layout_height=\"175dp\"\n                    android:importantForAccessibility=\"no\"\n                    android:scaleType=\"centerCrop\" />\n\n                <ImageView\n                    android:id=\"@+id/play_button_2\"\n                    android:layout_width=\"50dp\"\n                    android:layout_height=\"50dp\"\n                    android:layout_gravity=\"center\"\n                    android:layout_marginTop=\"6dp\"\n                    android:importantForAccessibility=\"no\"\n                    android:background=\"@drawable/gradient_fill_text\"\n                    android:src=\"@drawable/baseline_play_circle_24\" />\n\n\n            </FrameLayout>\n\n            <TextView\n                android:id=\"@+id/episode_no_text\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\"\n                android:layout_gravity=\"top\"\n                android:layout_marginStart=\"10dp\"\n                android:fontFamily=\"@font/exo_2\"\n                android:textSize=\"20sp\"\n                android:textStyle=\"bold\"\n                tools:text=\"@string/episodes\" />\n\n            <androidx.constraintlayout.widget.ConstraintLayout\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\">\n\n                <at.blogc.android.views.ExpandableTextView\n                    android:id=\"@+id/episode_overview_text\"\n                    android:layout_width=\"0dp\"\n                    android:layout_height=\"wrap_content\"\n                    android:layout_gravity=\"bottom\"\n                    android:layout_margin=\"10dp\"\n                    android:ellipsize=\"end\"\n                    android:fontFamily=\"@font/exo_2\"\n                    android:maxLines=\"2\"\n                    app:animation_duration=\"750\"\n                    app:layout_constraintBottom_toBottomOf=\"parent\"\n                    app:layout_constraintEnd_toStartOf=\"@+id/expand_text\"\n                    app:layout_constraintStart_toStartOf=\"parent\"\n                    app:layout_constraintTop_toTopOf=\"parent\" />\n\n                <ImageView\n                    android:id=\"@+id/expand_text\"\n                    android:layout_width=\"24dp\"\n                    android:layout_height=\"24dp\"\n                    android:importantForAccessibility=\"no\"\n                    android:src=\"@drawable/baseline_keyboard_arrow_down_24\"\n                    app:layout_constraintBottom_toBottomOf=\"parent\"\n                    app:layout_constraintEnd_toEndOf=\"parent\"\n                    app:layout_constraintTop_toTopOf=\"parent\" />\n            </androidx.constraintlayout.widget.ConstraintLayout>\n\n        </LinearLayout>\n\n\n    </androidx.cardview.widget.CardView>\n\n    <TextView\n        android:id=\"@+id/episode_number\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_gravity=\"center_vertical\"\n        android:layout_marginVertical=\"0dp\"\n        android:fontFamily=\"@font/exo_2\"\n        android:textAppearance=\"@style/TextAppearance.AppCompat.Display3\"\n        android:textColor=\"@color/white\"\n        android:textStyle=\"bold\"\n        app:layout_constraintBottom_toBottomOf=\"parent\"\n        app:layout_constraintStart_toStartOf=\"parent\"\n        app:layout_constraintTop_toTopOf=\"parent\"\n        app:layout_constraintVertical_bias=\"0.64\"\n        tools:text=\"1\" />\n\n</androidx.constraintlayout.widget.ConstraintLayout>"
  },
  {
    "path": "app/src/main/res/layout/track_item.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:orientation=\"vertical\"\n    android:layout_width=\"match_parent\"\n    android:focusable=\"true\"\n    android:background=\"@drawable/focus_search\"\n    android:layout_height=\"wrap_content\">\n\n    <CheckedTextView\n        android:layout_width=\"match_parent\"\n        android:id=\"@+id/track_quality\"\n        android:checkMark=\"?android:attr/listChoiceIndicatorSingle\"\n        android:layout_height=\"wrap_content\"\n        android:text=\"360p\"\n        android:padding=\"5dp\"\n        android:fontFamily=\"@font/exo_2\"\n        android:textSize=\"20sp\"\n        android:textStyle=\"bold\"\n        />\n\n</LinearLayout>"
  },
  {
    "path": "app/src/main/res/menu/bottom_nav.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<menu xmlns:android=\"http://schemas.android.com/apk/res/android\">\n\n\n    <item android:id=\"@+id/moviesFragment\"\n            android:title=\"\"\n        android:icon=\"@drawable/icon_movie\"\n        />\n\n    <item android:id=\"@+id/searchFragment\"\n        android:title=\"\"\n        android:icon=\"@drawable/baseline_search_24\"\n        />\n\n    <item android:id=\"@+id/animeFragment\"\n        android:title=\"\"\n        android:icon=\"@drawable/anime_bottom_nav\"\n        />\n\n    <item android:id=\"@+id/TVShowFragment\"\n        android:title=\"\"\n        android:icon=\"@drawable/icon_tvshow\"\n        />\n\n</menu>"
  },
  {
    "path": "app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<adaptive-icon xmlns:android=\"http://schemas.android.com/apk/res/android\">\n  <background android:drawable=\"@mipmap/ic_launcher_background\"/>\n  <foreground android:drawable=\"@mipmap/ic_launcher_foreground\"/>\n  <monochrome android:drawable=\"@mipmap/ic_launcher_monochrome\"/>\n</adaptive-icon>"
  },
  {
    "path": "app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<adaptive-icon xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <background android:drawable=\"@drawable/ic_launcher_background\" />\n    <foreground android:drawable=\"@drawable/ic_launcher_foreground\" />\n    <monochrome android:drawable=\"@drawable/ic_launcher_foreground\" />\n</adaptive-icon>"
  },
  {
    "path": "app/src/main/res/navigation/nav_main.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<navigation xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    android:id=\"@+id/nav_main\"\n    app:startDestination=\"@id/moviesFragment\">\n\n    <fragment\n        android:id=\"@+id/moviesFragment\"\n        android:name=\"com.demomiru.tokeiv2.MoviesFragment\"\n        android:label=\"@string/movies\"\n        tools:layout=\"@layout/fragment_movies\" >\n        <action\n            android:id=\"@+id/action_moviesFragment_to_TVShowFragment\"\n            app:destination=\"@id/TVShowFragment\"\n            app:enterAnim=\"@anim/slide_in\"\n            app:exitAnim=\"@android:anim/fade_out\"\n            app:popEnterAnim=\"@android:anim/fade_in\"\n            app:popExitAnim=\"@anim/slide_out\" />\n        <action\n            android:id=\"@+id/action_moviesFragment_to_moviePlayActivity\"\n            app:destination=\"@id/moviePlayActivity\" />\n        <action\n            android:id=\"@+id/action_moviesFragment_to_searchFragment\"\n            app:destination=\"@id/searchFragment\" />\n    </fragment>\n    <fragment\n        android:id=\"@+id/TVShowFragment\"\n        android:name=\"com.demomiru.tokeiv2.TVShowFragment\"\n        android:label=\"@string/tv_show\"\n        tools:layout=\"@layout/fragment_tv_show\" >\n        <action\n            android:id=\"@+id/action_TVShowFragment_to_moviesFragment\"\n            app:destination=\"@id/moviesFragment\" />\n        <action\n            android:id=\"@+id/action_TVShowFragment_to_TVShowDetails\"\n            app:destination=\"@id/TVShowDetails\"\n            app:enterAnim=\"@anim/enter_from_bottom\"\n            app:exitAnim=\"@anim/exit_to_top\"\n            app:popEnterAnim=\"@anim/go_left\"\n            app:popExitAnim=\"@anim/go_right\" />\n        <action\n            android:id=\"@+id/action_TVShowFragment_to_searchFragment\"\n            app:destination=\"@id/searchFragment\" />\n\n    </fragment>\n    <activity\n        android:id=\"@+id/moviePlayActivity\"\n        android:name=\"com.demomiru.tokeiv2.MoviePlayActivity\"\n        android:label=\"activity_movie_play\"\n        tools:layout=\"@layout/activity_movie_play\" >\n        <argument\n            android:name=\"tmdbID\"\n            app:argType=\"string\" />\n        <argument\n            android:name=\"type\"\n            app:argType=\"string\" />\n        <argument\n            android:name=\"episodeN\"\n            app:argType=\"integer\"\n            android:defaultValue=\"0\" />\n        <argument\n            android:name=\"seasonN\"\n            app:argType=\"string\"\n            android:defaultValue=\"1\" />\n        <argument\n            android:name=\"title\"\n            app:argType=\"string\"\n            android:defaultValue='\"\"' />\n    </activity>\n    <fragment\n        android:id=\"@+id/TVShowDetails\"\n        android:name=\"com.demomiru.tokeiv2.TVShowDetails\"\n        android:label=\"fragment_t_v_show_details\"\n        tools:layout=\"@layout/fragment_tv_show_details\" >\n        <argument android:name=\"tmdbID\"\n            app:argType=\"string\"\n            />\n        <action\n            android:id=\"@+id/action_TVShowDetails_to_moviePlayActivity\"\n            app:destination=\"@id/moviePlayActivity\" />\n        <argument\n            android:name=\"position\"\n            app:argType=\"integer\"\n            android:defaultValue=\"0\" />\n        <argument\n            android:name=\"title\"\n            app:argType=\"string\"\n            android:defaultValue='\"\"' />\n        <argument\n            android:name=\"animeUrl\"\n            app:argType=\"string\"\n            android:defaultValue='\"\"' />\n    </fragment>\n    <fragment\n        android:id=\"@+id/searchFragment\"\n        android:name=\"com.demomiru.tokeiv2.SearchFragment\"\n        android:label=\"fragment_search\"\n        tools:layout=\"@layout/fragment_search\" >\n        <action\n            android:id=\"@+id/action_searchFragment_to_moviePlayActivity\"\n            app:destination=\"@id/moviePlayActivity\"\n            app:enterAnim=\"@anim/nav_enter_anim\"\n            app:exitAnim=\"@anim/nav_exit_anim\"\n            app:popEnterAnim=\"@anim/nav_pop_enter\"\n            app:popExitAnim=\"@anim/nav_pop_exit\" />\n        <action\n            android:id=\"@+id/action_searchFragment_to_TVShowDetails\"\n            app:destination=\"@id/TVShowDetails\"\n            app:enterAnim=\"@anim/nav_enter_anim\"\n            app:exitAnim=\"@anim/nav_exit_anim\"\n            app:popEnterAnim=\"@anim/nav_pop_enter\"\n            app:popExitAnim=\"@anim/nav_pop_exit\" />\n        <action\n            android:id=\"@+id/action_searchFragment_to_animeDetailsFragment\"\n            app:destination=\"@id/animeDetailsFragment\" />\n    </fragment>\n    <fragment\n        android:id=\"@+id/animeFragment\"\n        android:name=\"com.demomiru.tokeiv2.anime.AnimeFragment\"\n        android:label=\"fragment_anime\"\n        tools:layout=\"@layout/fragment_anime\" >\n        <action\n            android:id=\"@+id/action_animeFragment_to_TVShowDetails\"\n            app:destination=\"@id/TVShowDetails\" />\n        <action\n            android:id=\"@+id/action_animeFragment_to_animeDetailsFragment\"\n            app:destination=\"@id/animeDetailsFragment\" />\n    </fragment>\n    <fragment\n        android:id=\"@+id/animeDetailsFragment\"\n        android:name=\"com.demomiru.tokeiv2.anime.AnimeDetailsFragment\"\n        android:label=\"AnimeDetailsFragment\" >\n        <argument\n            android:name=\"title\"\n            app:argType=\"string\" />\n        <argument\n            android:name=\"url\"\n            app:argType=\"string\" />\n        <action\n            android:id=\"@+id/action_animeDetailsFragment_self\"\n            app:destination=\"@id/animeDetailsFragment\" />\n    </fragment>\n</navigation>"
  },
  {
    "path": "app/src/main/res/transition/container_transform.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<transitionSet xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:duration=\"375\"\n    android:interpolator=\"@android:interpolator/fast_out_slow_in\"\n    android:transitionOrdering=\"together\">\n    <changeClipBounds/>\n    <changeTransform/>\n    <changeBounds/>\n</transitionSet>\n"
  },
  {
    "path": "app/src/main/res/values/colors.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <color name=\"black\">#FF000000</color>\n    <color name=\"white\">#FFFFFFFF</color>\n    <color name=\"green\">#36F465</color>\n    <color name= \"colorPrimary\">#996750A4</color>\n    <color name=\"navBar\">#2A2831</color>\n    <color name=\"red\">#AF2117</color>\n</resources>"
  },
  {
    "path": "app/src/main/res/values/font_certs.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <array name=\"com_google_android_gms_fonts_certs\">\n        <item>@array/com_google_android_gms_fonts_certs_dev</item>\n        <item>@array/com_google_android_gms_fonts_certs_prod</item>\n    </array>\n    <string-array name=\"com_google_android_gms_fonts_certs_dev\">\n        <item>\n            MIIEqDCCA5CgAwIBAgIJANWFuGx90071MA0GCSqGSIb3DQEBBAUAMIGUMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEQMA4GA1UEChMHQW5kcm9pZDEQMA4GA1UECxMHQW5kcm9pZDEQMA4GA1UEAxMHQW5kcm9pZDEiMCAGCSqGSIb3DQEJARYTYW5kcm9pZEBhbmRyb2lkLmNvbTAeFw0wODA0MTUyMzM2NTZaFw0zNTA5MDEyMzM2NTZaMIGUMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEQMA4GA1UEChMHQW5kcm9pZDEQMA4GA1UECxMHQW5kcm9pZDEQMA4GA1UEAxMHQW5kcm9pZDEiMCAGCSqGSIb3DQEJARYTYW5kcm9pZEBhbmRyb2lkLmNvbTCCASAwDQYJKoZIhvcNAQEBBQADggENADCCAQgCggEBANbOLggKv+IxTdGNs8/TGFy0PTP6DHThvbbR24kT9ixcOd9W+EaBPWW+wPPKQmsHxajtWjmQwWfna8mZuSeJS48LIgAZlKkpFeVyxW0qMBujb8X8ETrWy550NaFtI6t9+u7hZeTfHwqNvacKhp1RbE6dBRGWynwMVX8XW8N1+UjFaq6GCJukT4qmpN2afb8sCjUigq0GuMwYXrFVee74bQgLHWGJwPmvmLHC69EH6kWr22ijx4OKXlSIx2xT1AsSHee70w5iDBiK4aph27yH3TxkXy9V89TDdexAcKk/cVHYNnDBapcavl7y0RiQ4biu8ymM8Ga/nmzhRKya6G0cGw8CAQOjgfwwgfkwHQYDVR0OBBYEFI0cxb6VTEM8YYY6FbBMvAPyT+CyMIHJBgNVHSMEgcEwgb6AFI0cxb6VTEM8YYY6FbBMvAPyT+CyoYGapIGXMIGUMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEQMA4GA1UEChMHQW5kcm9pZDEQMA4GA1UECxMHQW5kcm9pZDEQMA4GA1UEAxMHQW5kcm9pZDEiMCAGCSqGSIb3DQEJARYTYW5kcm9pZEBhbmRyb2lkLmNvbYIJANWFuGx90071MAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEEBQADggEBABnTDPEF+3iSP0wNfdIjIz1AlnrPzgAIHVvXxunW7SBrDhEglQZBbKJEk5kT0mtKoOD1JMrSu1xuTKEBahWRbqHsXclaXjoBADb0kkjVEJu/Lh5hgYZnOjvlba8Ld7HCKePCVePoTJBdI4fvugnL8TsgK05aIskyY0hKI9L8KfqfGTl1lzOv2KoWD0KWwtAWPoGChZxmQ+nBli+gwYMzM1vAkP+aayLe0a1EQimlOalO762r0GXO0ks+UeXde2Z4e+8S/pf7pITEI/tP+MxJTALw9QUWEv9lKTk+jkbqxbsh8nfBUapfKqYn0eidpwq2AzVp3juYl7//fKnaPhJD9gs=\n        </item>\n    </string-array>\n    <string-array name=\"com_google_android_gms_fonts_certs_prod\">\n        <item>\n            MIIEQzCCAyugAwIBAgIJAMLgh0ZkSjCNMA0GCSqGSIb3DQEBBAUAMHQxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1Nb3VudGFpbiBWaWV3MRQwEgYDVQQKEwtHb29nbGUgSW5jLjEQMA4GA1UECxMHQW5kcm9pZDEQMA4GA1UEAxMHQW5kcm9pZDAeFw0wODA4MjEyMzEzMzRaFw0zNjAxMDcyMzEzMzRaMHQxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1Nb3VudGFpbiBWaWV3MRQwEgYDVQQKEwtHb29nbGUgSW5jLjEQMA4GA1UECxMHQW5kcm9pZDEQMA4GA1UEAxMHQW5kcm9pZDCCASAwDQYJKoZIhvcNAQEBBQADggENADCCAQgCggEBAKtWLgDYO6IIrgqWbxJOKdoR8qtW0I9Y4sypEwPpt1TTcvZApxsdyxMJZ2JORland2qSGT2y5b+3JKkedxiLDmpHpDsz2WCbdxgxRczfey5YZnTJ4VZbH0xqWVW/8lGmPav5xVwnIiJS6HXk+BVKZF+JcWjAsb/GEuq/eFdpuzSqeYTcfi6idkyugwfYwXFU1+5fZKUaRKYCwkkFQVfcAs1fXA5V+++FGfvjJ/CxURaSxaBvGdGDhfXE28LWuT9ozCl5xw4Yq5OGazvV24mZVSoOO0yZ31j7kYvtwYK6NeADwbSxDdJEqO4k//0zOHKrUiGYXtqw/A0LFFtqoZKFjnkCAQOjgdkwgdYwHQYDVR0OBBYEFMd9jMIhF1Ylmn/Tgt9r45jk14alMIGmBgNVHSMEgZ4wgZuAFMd9jMIhF1Ylmn/Tgt9r45jk14aloXikdjB0MQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEUMBIGA1UEChMLR29vZ2xlIEluYy4xEDAOBgNVBAsTB0FuZHJvaWQxEDAOBgNVBAMTB0FuZHJvaWSCCQDC4IdGZEowjTAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBAUAA4IBAQBt0lLO74UwLDYKqs6Tm8/yzKkEu116FmH4rkaymUIE0P9KaMftGlMexFlaYjzmB2OxZyl6euNXEsQH8gjwyxCUKRJNexBiGcCEyj6z+a1fuHHvkiaai+KL8W1EyNmgjmyy8AW7P+LLlkR+ho5zEHatRbM/YAnqGcFh5iZBqpknHf1SKMXFh4dd239FJ1jWYfbMDMy3NS5CTMQ2XFI1MvcyUTdZPErjQfTbQe3aDQsQcafEQPD+nqActifKZ0Np0IS9L9kR/wbNvyz6ENwPiTrjV2KRkEjH78ZMcUQXg0L3BYHJ3lc69Vs5Ddf9uUGGMYldX3WfMBEmh/9iFBDAaTCK\n        </item>\n    </string-array>\n</resources>\n"
  },
  {
    "path": "app/src/main/res/values/preloaded_fonts.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <array name=\"preloaded_fonts\" translatable=\"false\">\n        <item>@font/exo_2</item>\n        <item>@font/exo_2_thin</item>\n    </array>\n</resources>\n"
  },
  {
    "path": "app/src/main/res/values/strings.xml",
    "content": "<resources>\n    <string name=\"app_name\">Tokei</string>\n    <string name=\"movies\">Movies</string>\n    <string name=\"trending\">Trending</string>\n    <string name=\"popular\">Popular</string>\n    <string name=\"tv_show\">TV Shows</string>\n    <!-- TODO: Remove or change this placeholder text -->\n    <string name=\"hello_blank_fragment\">Hello blank fragment</string>\n    <string name=\"episodes\"><u>Episodes</u></string>\n    <string name=\"search\">Search</string>\n    <string name=\"top_rated\">Top Rated</string>\n    <string name=\"default_season\">Season 1</string>\n    <string name=\"season\">Season</string>\n    <string name=\"expandtvshow\">expandTvShow</string>\n    <string name=\"continue_watching\">Continue Watching</string>\n    <string name=\"season_episode\">S1E1</string>\n    <string name=\"clear_all\">Clear All</string>\n    <string name=\"anime\">Anime</string>\n</resources>"
  },
  {
    "path": "app/src/main/res/values/themes.xml",
    "content": "<resources xmlns:tools=\"http://schemas.android.com/tools\">\n    <!-- Base application theme. -->\n    <style name=\"Base.Theme.TokeiV2\" parent=\"Theme.Material3.DayNight.NoActionBar\">\n        <!-- Customize your light theme here. -->\n        <!-- <item name=\"colorPrimary\">@color/my_light_primary</item> -->\n\n    </style>\n    <style name=\"AppTheme\" parent=\"Theme.Material3.Dark.NoActionBar\">\n        <item name=\"android:navigationBarColor\">@color/navBar</item>\n    </style>\n\n    <style name=\"Theme.TokeiV2\" parent=\"Base.Theme.TokeiV2\" />\n\n    <style name=\"roundedImageView\">\n        <item name=\"cornerFamily\">rounded</item>\n        <item name=\"cornerSize\">16dp</item>\n    </style>\n\n    <style name=\"MyRipple\">\n        <item name=\"colorControlHighlight\">@color/ripple_color</item>\n        <item name=\"android:background\">?attr/selectableItemBackground</item>\n    </style>\n\n    <color name=\"ripple_color\">#9C9595</color>\n</resources>"
  },
  {
    "path": "app/src/main/res/values-night/themes.xml",
    "content": "<resources xmlns:tools=\"http://schemas.android.com/tools\">\n    <!-- Base application theme. -->\n    <style name=\"Base.Theme.TokeiV2\" parent=\"Theme.Material3.DayNight.NoActionBar\">\n        <!-- Customize your dark theme here. -->\n        <!-- <item name=\"colorPrimary\">@color/my_dark_primary</item> -->\n    </style>\n</resources>"
  },
  {
    "path": "app/src/main/res/xml/backup_rules.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n   Sample backup rules file; uncomment and customize as necessary.\n   See https://developer.android.com/guide/topics/data/autobackup\n   for details.\n   Note: This file is ignored for devices older that API 31\n   See https://developer.android.com/about/versions/12/backup-restore\n-->\n<full-backup-content>\n    <!--\n   <include domain=\"sharedpref\" path=\".\"/>\n   <exclude domain=\"sharedpref\" path=\"device.xml\"/>\n-->\n</full-backup-content>"
  },
  {
    "path": "app/src/main/res/xml/data_extraction_rules.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n   Sample data extraction rules file; uncomment and customize as necessary.\n   See https://developer.android.com/about/versions/12/backup-restore#xml-changes\n   for details.\n-->\n<data-extraction-rules>\n    <cloud-backup>\n        <!-- TODO: Use <include> and <exclude> to control what is backed up.\n        <include .../>\n        <exclude .../>\n        -->\n    </cloud-backup>\n    <!--\n    <device-transfer>\n        <include .../>\n        <exclude .../>\n    </device-transfer>\n    -->\n</data-extraction-rules>"
  },
  {
    "path": "app/src/test/java/com/demomiru/tokeiv2/ExampleUnitTest.kt",
    "content": "package com.demomiru.tokeiv2\n\nimport org.junit.Test\n\nimport org.junit.Assert.*\n\n/**\n * Example local unit test, which will execute on the development machine (host).\n *\n * See [testing documentation](http://d.android.com/tools/testing).\n */\nclass ExampleUnitTest {\n    @Test\n    fun addition_isCorrect() {\n        assertEquals(4, 2 + 2)\n    }\n}"
  },
  {
    "path": "build.gradle",
    "content": "// Top-level build file where you can add configuration options common to all sub-projects/modules.\n\n\nbuildscript {\n    repositories {\n        google()\n    }\n    dependencies {\n        classpath(\"androidx.navigation:navigation-safe-args-gradle-plugin:2.7.1\")\n    }\n}\n\n\nplugins {\n    id 'com.android.application' version '8.0.2' apply false\n    id 'com.android.library' version '8.0.2' apply false\n    id 'org.jetbrains.kotlin.android' version '1.8.20' apply false\n    id(\"com.google.devtools.ksp\") version \"1.9.0-1.0.11\" apply false\n}"
  },
  {
    "path": "gradle/wrapper/gradle-wrapper.properties",
    "content": "#Sat Aug 26 21:19:31 IST 2023\ndistributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-8.0-bin.zip\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\n"
  },
  {
    "path": "gradle.properties",
    "content": "# Project-wide Gradle settings.\n# IDE (e.g. Android Studio) users:\n# Gradle settings configured through the IDE *will override*\n# any settings specified in this file.\n# For more details on how to configure your build environment visit\n# http://www.gradle.org/docs/current/userguide/build_environment.html\n# Specifies the JVM arguments used for the daemon process.\n# The setting is particularly useful for tweaking memory settings.\norg.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8\n# When configured, Gradle will run in incubating parallel mode.\n# This option should only be used with decoupled projects. More details, visit\n# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects\n# org.gradle.parallel=true\n# AndroidX package structure to make it clearer which packages are bundled with the\n# Android operating system, and which are packaged with your app's APK\n# https://developer.android.com/topic/libraries/support-library/androidx-rn\nandroid.useAndroidX=true\n# Kotlin code style for this project: \"official\" or \"obsolete\":\nkotlin.code.style=official\n# Enables namespacing of each library's R class so that its R class includes only the\n# resources declared in the library itself and none from the library's dependencies,\n# thereby reducing the size of the R class for that library\nandroid.nonTransitiveRClass=true"
  },
  {
    "path": "gradlew",
    "content": "#!/usr/bin/env sh\n\n#\n# Copyright 2015 the original author or authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n##############################################################################\n##\n##  Gradle start up script for UN*X\n##\n##############################################################################\n\n# Attempt to set APP_HOME\n# Resolve links: $0 may be a link\nPRG=\"$0\"\n# Need this for relative symlinks.\nwhile [ -h \"$PRG\" ] ; do\n    ls=`ls -ld \"$PRG\"`\n    link=`expr \"$ls\" : '.*-> \\(.*\\)$'`\n    if expr \"$link\" : '/.*' > /dev/null; then\n        PRG=\"$link\"\n    else\n        PRG=`dirname \"$PRG\"`\"/$link\"\n    fi\ndone\nSAVED=\"`pwd`\"\ncd \"`dirname \\\"$PRG\\\"`/\" >/dev/null\nAPP_HOME=\"`pwd -P`\"\ncd \"$SAVED\" >/dev/null\n\nAPP_NAME=\"Gradle\"\nAPP_BASE_NAME=`basename \"$0\"`\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS='\"-Xmx64m\" \"-Xms64m\"'\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=\"maximum\"\n\nwarn () {\n    echo \"$*\"\n}\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n}\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"`uname`\" in\n  CYGWIN* )\n    cygwin=true\n    ;;\n  Darwin* )\n    darwin=true\n    ;;\n  MINGW* )\n    msys=true\n    ;;\n  NONSTOP* )\n    nonstop=true\n    ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=\"$JAVA_HOME/jre/sh/java\"\n    else\n        JAVACMD=\"$JAVA_HOME/bin/java\"\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=\"java\"\n    which java >/dev/null 2>&1 || die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\nfi\n\n# Increase the maximum file descriptors if we can.\nif [ \"$cygwin\" = \"false\" -a \"$darwin\" = \"false\" -a \"$nonstop\" = \"false\" ] ; then\n    MAX_FD_LIMIT=`ulimit -H -n`\n    if [ $? -eq 0 ] ; then\n        if [ \"$MAX_FD\" = \"maximum\" -o \"$MAX_FD\" = \"max\" ] ; then\n            MAX_FD=\"$MAX_FD_LIMIT\"\n        fi\n        ulimit -n $MAX_FD\n        if [ $? -ne 0 ] ; then\n            warn \"Could not set maximum file descriptor limit: $MAX_FD\"\n        fi\n    else\n        warn \"Could not query maximum file descriptor limit: $MAX_FD_LIMIT\"\n    fi\nfi\n\n# For Darwin, add options to specify how the application appears in the dock\nif $darwin; then\n    GRADLE_OPTS=\"$GRADLE_OPTS \\\"-Xdock:name=$APP_NAME\\\" \\\"-Xdock:icon=$APP_HOME/media/gradle.icns\\\"\"\nfi\n\n# For Cygwin or MSYS, switch paths to Windows format before running java\nif [ \"$cygwin\" = \"true\" -o \"$msys\" = \"true\" ] ; then\n    APP_HOME=`cygpath --path --mixed \"$APP_HOME\"`\n    CLASSPATH=`cygpath --path --mixed \"$CLASSPATH\"`\n\n    JAVACMD=`cygpath --unix \"$JAVACMD\"`\n\n    # We build the pattern for arguments to be converted via cygpath\n    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`\n    SEP=\"\"\n    for dir in $ROOTDIRSRAW ; do\n        ROOTDIRS=\"$ROOTDIRS$SEP$dir\"\n        SEP=\"|\"\n    done\n    OURCYGPATTERN=\"(^($ROOTDIRS))\"\n    # Add a user-defined pattern to the cygpath arguments\n    if [ \"$GRADLE_CYGPATTERN\" != \"\" ] ; then\n        OURCYGPATTERN=\"$OURCYGPATTERN|($GRADLE_CYGPATTERN)\"\n    fi\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    i=0\n    for arg in \"$@\" ; do\n        CHECK=`echo \"$arg\"|egrep -c \"$OURCYGPATTERN\" -`\n        CHECK2=`echo \"$arg\"|egrep -c \"^-\"`                                 ### Determine if an option\n\n        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition\n            eval `echo args$i`=`cygpath --path --ignore --mixed \"$arg\"`\n        else\n            eval `echo args$i`=\"\\\"$arg\\\"\"\n        fi\n        i=`expr $i + 1`\n    done\n    case $i in\n        0) set -- ;;\n        1) set -- \"$args0\" ;;\n        2) set -- \"$args0\" \"$args1\" ;;\n        3) set -- \"$args0\" \"$args1\" \"$args2\" ;;\n        4) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" ;;\n        5) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" ;;\n        6) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" ;;\n        7) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" ;;\n        8) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" \"$args7\" ;;\n        9) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" \"$args7\" \"$args8\" ;;\n    esac\nfi\n\n# Escape application args\nsave () {\n    for i do printf %s\\\\n \"$i\" | sed \"s/'/'\\\\\\\\''/g;1s/^/'/;\\$s/\\$/' \\\\\\\\/\" ; done\n    echo \" \"\n}\nAPP_ARGS=`save \"$@\"`\n\n# Collect all arguments for the java command, following the shell quoting and substitution rules\neval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS \"\\\"-Dorg.gradle.appname=$APP_BASE_NAME\\\"\" -classpath \"\\\"$CLASSPATH\\\"\" org.gradle.wrapper.GradleWrapperMain \"$APP_ARGS\"\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "gradlew.bat",
    "content": "@rem\n@rem Copyright 2015 the original author or authors.\n@rem\n@rem Licensed under the Apache License, Version 2.0 (the \"License\");\n@rem you may not use this file except in compliance with the License.\n@rem You may obtain a copy of the License at\n@rem\n@rem      https://www.apache.org/licenses/LICENSE-2.0\n@rem\n@rem Unless required by applicable law or agreed to in writing, software\n@rem distributed under the License is distributed on an \"AS IS\" BASIS,\n@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n@rem See the License for the specific language governing permissions and\n@rem limitations under the License.\n@rem\n\n@if \"%DEBUG%\" == \"\" @echo off\n@rem ##########################################################################\n@rem\n@rem  Gradle startup script for Windows\n@rem\n@rem ##########################################################################\n\n@rem Set local scope for the variables with windows NT shell\nif \"%OS%\"==\"Windows_NT\" setlocal\n\nset DIRNAME=%~dp0\nif \"%DIRNAME%\" == \"\" set DIRNAME=.\nset APP_BASE_NAME=%~n0\nset APP_HOME=%DIRNAME%\n\n@rem Resolve any \".\" and \"..\" in APP_HOME to make it shorter.\nfor %%i in (\"%APP_HOME%\") do set APP_HOME=%%~fi\n\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nset DEFAULT_JVM_OPTS=\"-Xmx64m\" \"-Xms64m\"\n\n@rem Find java.exe\nif defined JAVA_HOME goto findJavaFromJavaHome\n\nset JAVA_EXE=java.exe\n%JAVA_EXE% -version >NUL 2>&1\nif \"%ERRORLEVEL%\" == \"0\" goto execute\n\necho.\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:findJavaFromJavaHome\nset JAVA_HOME=%JAVA_HOME:\"=%\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\n\nif exist \"%JAVA_EXE%\" goto execute\n\necho.\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:execute\n@rem Setup the command line\n\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\n\n\n@rem Execute Gradle\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %*\n\n:end\n@rem End local scope for the variables with windows NT shell\nif \"%ERRORLEVEL%\"==\"0\" goto mainEnd\n\n:fail\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\nrem the _cmd.exe /c_ return code!\nif  not \"\" == \"%GRADLE_EXIT_CONSOLE%\" exit 1\nexit /b 1\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "settings.gradle",
    "content": "pluginManagement {\n    repositories {\n        google()\n        mavenCentral()\n        gradlePluginPortal()\n    }\n}\ndependencyResolutionManagement {\n    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)\n    repositories {\n        google()\n        mavenCentral()\n        maven{\n            url 'https://jitpack.io'\n        }\n    }\n}\nrootProject.name = \"TokeiV2\"\ninclude ':app'\n"
  }
]